文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Linux中进程内核栈是什么

2023-06-12 20:42

关注

这篇文章主要介绍了Linux中进程内核栈是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

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

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

比如,有一个简单的字符驱动实现了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是记录部分进程信息的结构体,其中包括了进程上下文信息:

struct thread_info {

    unsigned long        flags;        

    int            preempt_count;    

    mm_segment_t        addr_limit;    

    struct task_struct    *task;        

    struct exec_domain    *exec_domain;    

    __u32            cpu;        

    __u32            cpu_domain;    

    struct cpu_context_save    cpu_context;    

    __u32            syscall;    

    __u8            used_cp[16];    

    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;    

#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

在(内核)驱动编程时需要注意的问题:

由于栈空间的限制,在编写的驱动(特别是被系统调用使用的底层函数)中要注意避免对栈空间消耗较大的代码,比如递归算法、局部自动变量定义的大小等等

感谢你能够认真阅读完这篇文章,希望小编分享的“Linux中进程内核栈是什么”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯