• linux内核获取当前进程路径分析


    一个简单的问题,·linux下获取当前进程。我们都知道在内核中获取当前进程可以利用current宏

    #define get_current()    (current_thread_info()->task)
    #define current        get_current()

    通过get_current发现其是利用当前线程获取的当前进程线程结构thread_info结构中有指向其所属的进程指针task

    static inline struct thread_info *current_thread_info(void)
    {
        struct thread_info *ti;
        __asm__(
            "move.l %%sp, %0 
    	"
            "and.l  %1, %0"
            : "=&d"(ti)
            : "di" (~(THREAD_SIZE-1))
            );
        return ti;
    }

    代码比较简单,获取sp寄存器的值,然后和~(THREAD_SIZE-1)相与就得到指向thread_info的指针。原理为何呢?我们都知道每个进程有用一个内核栈,当进程通过某种方式比如系统调用进入内核,需要把栈空间切换到内核栈。默认情况下,内核栈的大小是2个页面,也就是8KB。在栈的顶部保存着thread_info结构,基于栈是从高地址往低地址生长的,所以thread_info就是位于8KB地址区间的起始位置。例如内核栈空间为0xc9563000~0xc9565000(仅仅做示例,不代表任何实际意义),那么架构图如下所示:

     如图所示,内核栈中,ESP指向任何时候必定位于0xc9563000~0xc9565000之间,所以此时我们可以看做是内核栈是8KB对齐的,既然如此回想下虚拟页面中如何获取虚拟页框基地址呢?正是把内部偏移位全都置0,然后和地址想与。so~这里也是如此,THREAD_SIZE-1就是栈内偏移位,取反就把除了偏移部分,其余部分全都置1,想与后无论如何结果始终指向内核栈区间的起始位置,图中为例就是0xc9563000.that's all,thank you!!

    感谢主!

    参考:

    Linux内核3.10.1源码

  • 相关阅读:
    高德地图API之公交路线
    高德地图API之骑行路线
    高德地图API之货车路线
    高德地图API之步行路线
    高德地图API之驾车路线
    高德地图API常用控件的添加与删除(鹰眼、工具条、比例尺)
    高德地图API,地图类型切换(卫星地图)
    高德地图API之缩放比例尺控件+3D转换
    Laravel 虚拟开发环境 Homestead 密码
    优化mysql
  • 原文地址:https://www.cnblogs.com/ck1020/p/6884572.html
Copyright © 2020-2023  润新知