请选择 进入手机版 | 继续访问电脑版

[LINUX] 进程 的内核栈是什么?浅谈Linux的进程 内核栈

[复制链接]
查看125 | 回复9 | 2021-9-5 02:48:18 | 显示全部楼层 |阅读模式

在重游《LDD3》的时间 ,又发现了一个当年被我忽略的一句话:

“内核具有非常小的栈,它大概 只和一个4096字节大小的页那样小”

针对这句话,我简单地学习了一下进程 的“内核栈”

什么是进程 的“内核栈”?

在每一个进程 的生命周期中,必然会通过到体系 调用陷入内核。在实行 体系 调用陷入内核之后,这些内核代码所使用 的栈并不是原先用户空间中的栈,而是一个内核空间的栈,这个称作进程 的“内核栈”。

比如,有一个简单的字符驱动实现了open方法。在这个驱动挂载后,应用程序对谁人 驱动所对应的装备 节点实行 open操作,这个应用程序的open实在 就通过glib库调用了Linux的open体系 调用,实行 体系 调用陷入内核后,处理器转换为了特权模式(详细 的转换机制因构架而异,对于ARM来说平常 模式和用户模式的的栈针(SP)是不同的寄存器),此时使用 的栈指针就是内核栈指针,他指向内核为每个进程 分配的内核栈空间。

内核栈的作用

我个人的明白 是:在陷入内核后,体系 调用中也是存在函数调用和主动 变量,这些都必要 栈支持。用户空间的栈显然不安全,必要 内核栈的支持。此外,内核栈同时用于保存一些体系 调用前的应用层信息(如用户空间栈指针、体系 调用参数)。

内核栈与进程 布局 体的关联

每个进程 在创建的时间 都会得到一个内核栈空间,内核栈和进程 的对应关系是通过2个布局 体中的指针成员来完成的:

(1)struct task_struct

    在学习Linux进程 管理肯定要学的布局 体,在内核中代表了一个进程 ,此中 记录的进程 的全部 状态信息,定义在Sched.h (include\linux)。

    此中 有一个成员:void *stack;就是指向下面的内核栈布局 体的“栈底”。

    在体系 运行的时间 ,宏current获得的就是当进步 程的struct task_struct布局 体。

(2)内核栈布局 体union thread_union

union thread_union {

    struct thread_info thread_info;

    unsigned long stack[THREAD_SIZE/sizeof(long)];

};

 此中 struct thread_info是记录部分进程 信息的布局 体,此中 包括了进程 上下文信息:

/*

 * low level task data that entry.S needs immediate access to.

 * __switch_to() assumes cpu_context follows immediately after cpu_domain.

 */

struct thread_info {

    unsigned long        flags;        /* low level flags */

    int            preempt_count;    /* 0 => preemptable, <0 => bug */

    mm_segment_t        addr_limit;    /* address limit */

    struct task_struct    *task;        /* main task structure */

    struct exec_domain    *exec_domain;    /* execution domain */

    __u32            cpu;        /* cpu */

    __u32            cpu_domain;    /* cpu domain */

    struct cpu_context_save    cpu_context;    /* cpu context */

    __u32            syscall;    /* syscall number */

    __u8            used_cp[16];    /* thread used copro */

    unsigned long        tp_value;

    struct crunch_state    crunchstate;

    union fp_state        fpstate __attribute__((aligned(8)));

    union vfp_state        vfpstate;

#ifdef CONFIG_ARM_THUMBEE

    unsigned long        thumbee_state;    /* ThumbEE Handler Base register */

#endif

    struct restart_block    restart_block;

};

关键是此中 的task成员,指向的是所创建的进程 的struct task_struct布局 体

而此中 的stack成员就是内核栈。从这里可以看出内核栈空间和 thread_info是共用一块空间的。假如 内核栈溢出, thread_info就会被摧毁,体系 崩溃了~~~

内核栈---struct thread_info----struct task_struct三者的关系入下图:

进程

的内核栈是什么?浅谈Linux的进程

内核栈

内核栈的产生

在进程 被创建的时间 ,fork族的体系 调用中会分别为内核栈和struct task_struct分配空间,调用过程是:

fork族的体系 调用--->do_fork--->copy_process--->dup_task_struct

在dup_task_struct函数中:

static struct task_struct *dup_task_struct(struct task_struct *orig)

{

    struct task_struct *tsk;

    struct thread_info *ti;

    unsigned long *stackend;

    int err;

    prepare_to_copy(orig);

    tsk = alloc_task_struct();

    if (!tsk)

        return NULL;

    ti = alloc_thread_info(tsk);

    if (!ti) {

        free_task_struct(tsk);

        return NULL;

    }

     err = arch_dup_task_struct(tsk, orig);

    if (err)

        goto out;

    tsk->stack = ti;

    err = prop_local_init_single(&tsk->dirties);

    if (err)

        goto out;

    setup_thread_stack(tsk, orig);

......

此中 alloc_task_struct使用 内核的slab分配器去为所要创建的进程 分配struct task_struct的空间

而alloc_thread_info使用 内核的伙伴体系 去为所要创建的进程 分配内核栈(union thread_union )空间

留意 :

后面的tsk->stack = ti;语句,这就是关联了struct task_struct和内核栈

而在setup_thread_stack(tsk, orig);中,关联了内核栈和struct task_struct:

static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)

{

    *task_thread_info(p) = *task_thread_info(org);

    task_thread_info(p)->task = p;

}

内核栈的大小

由于是每一个进程 都分配一个内核栈空间,以是 不大概 分配很大。这个大小是构架相干 的,一样平常 以页为单位。实在 也就是上面我们看到的THREAD_SIZE,这个值一样平常 为4K或者8K。对于ARM构架,这个定义在Thread_info.h (arch\arm\include\asm),

#define THREAD_SIZE_ORDER    1

#define THREAD_SIZE     8192

#define THREAD_START_SP     (THREAD_SIZE - 8)

以是 ARM的内核栈是8KB

在(内核)驱动编程时必要 留意 的标题 :

由于栈空间的限定 ,在编写的驱动(特殊 是被体系 调用使用 的底层函数)中要留意 避免对栈空间斲丧 较大的代码,比如递归算法、局部主动 变量定义的大小等等


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

avatar 珍爱1103 | 2021-9-5 23:06:06 | 显示全部楼层
admin楼主很有艺术范!
回复

使用道具 举报

avatar 小仙女要起飞 | 2021-9-12 11:04:45 | 显示全部楼层
楼上的说的很好!
回复

使用道具 举报

avatar 朱婆婆老 | 2021-10-6 13:13:53 | 显示全部楼层
刚看见一个妹子,很漂亮!
回复

使用道具 举报

avatar 天之涯神之兵米 | 2021-10-6 17:54:42 | 显示全部楼层
无图无真相!
回复

使用道具 举报

avatar 无热天龙中 | 2021-10-15 19:52:11 | 显示全部楼层
admin楼主病的不轻啊!
回复

使用道具 举报

不错的帖子,值得收藏!
回复

使用道具 举报

什么狗屁帖子啊,admin楼主的语文是苍老师教的吗?
回复

使用道具 举报

avatar 王丽梅 | 9 小时前 | 显示全部楼层
每次看到admin楼主的帖子都有惊吓!
回复

使用道具 举报

avatar 寒郁轩良 | 9 小时前 | 显示全部楼层
投admin楼主一票,不用谢哦!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则