ARM Linux系统中的用户栈与内核栈

本文介绍了Linux系统中用户栈和内核栈的区别及工作原理。用户栈位于用户进程空间顶部,用于存储函数参数、返回地址和局部变量,其大小可动态扩展。内核栈位于内核空间,主要用于异常、中断和系统调用处理,其大小通常小于用户栈。内核栈设计巧妙,便于快速获取进程信息。
摘要由CSDN通过智能技术生成

在Linux系统上,一个进程有两种不同的栈,一种是用户栈,另一种是内核栈。

用户栈

用户栈就是应用程序直接使用的栈。如下图所示,它位于应用程序的用户进程空间的最顶端。

当用户程序逐级调用函数时,用户栈从高地址向低地址方向扩展,每次增加一个栈帧,一个栈帧中存放的是函数的参数、返回地址和局部变量等,所以栈帧的长度是不定的。

用户栈的栈底靠近进程空间的上边缘,但一般不会刚好对齐到边缘,出于安全考虑,会在栈底与进程上边缘之间插入一段随机大小的隔离区。这样,程序在每次运行时,栈的位置都不同,这样黑客就不大容易利用基于栈的安全漏洞来实施攻击。

用户栈的伸缩对于应用程序来说是透明的,应用程序不需要自己去管理栈,这是操作系统提供的功能。应用程序在刚刚启动的时候(由fork()系统调用复制出新的进程),新的进程其实并不占有任何栈的空间。当应用程序中调用了函数需要压栈时,会触发一个page fault,内核在处理这个异常里会发现进程需要新的栈空间,于是建立新的VMA并映射内存给用户栈。

内核栈

内核栈对于应用程序是不可见的,因为它位于内核空间中。在应用程序执行过程中,如果发生异常、中断或系统调用的话,应用程序会被暂停,系统进入内核态,转去执行异常响应等代码,这个时候所使用的栈就是内核栈。

与用户栈相比,内核栈的尺寸要小得多。在32位Linux系统上,用户栈最多可以扩展到64M,但内核栈最多也只有8K字节,而且有时为了提高内存利用率还常常把内核栈配置成4K。其实即使是只有4K,在绝大多数情况下也仍然是够用的,因为这里只是给内核代码使用的,栈不会很大。

每个进程在内核空间中都拥有一个对应的内核栈,而且这个栈是在进程fork的时候就预留出来的。以下是创建内核栈的代码(Kernel 2.6.35 版本):

[c]

static struct task_struct *dup_task_struct(struct task_struct *orig)
{
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值