注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

FY

Johnson 's Blog

 
 
 

日志

 
 

[原创]内核中进程0里不能使用堆栈的原因  

2015-06-04 20:14:48|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
也即 : 关于pause和fork的内嵌问题
首先,我们要明确的是,不是任务0从main开始执行就不能使用栈,它可以使用栈,比如它按函数方式调用了
trap_init等,这些都会"污染"栈,但是这些栈都在函数返回时被自动清理了.
我们说的任务0不能使用栈,是指在执行fork之前,要保证栈中没有多余的内容.
而由于普通C的调用函数都会用到栈,所以fork才使用汇编的方式被调用 .
但根本原因是:

任务0和任务1都使用同一个栈,此时我们已经不用管它是属于内核还是用户。

总之任务0使用一个栈区,而任务1(一开始也"被迫"使用这个栈区)。

 

在任务0在用户栈调用 fork时,如果以普通函数调用的方式,那么此时用户栈中肯定会被以下内容"污染"

------------------------------------------

Fork后原下一条指令的地址

------------------------------------------

任务0的栈顶ebp                              ?----- 新的esp

------------------------------------------

 

然后中断到系统调用 fork中去。

forkà copy_process 

将把旧任务(即任务0)的所有寄存器内容(包括栈相关的SS:ESP)都复制给任务1

而虽然现在没有真正在主内存中给任务1分配物理内存空间,但这会在将来能过Copy-on-write的方式来复制到主内存,创建任务1的栈

接着fork调用完了后,返回。但是由于fork本身也是一个系统调用 ,只要是系统调用返回时都会进行schedule检查。

所以内核并不能保证fork返回后,任务0和任务1哪个先执行。

如果任务1先执行,并且它进行了栈操作。则产生page fault,进行copy-on-write,然后任务1的真正的用户栈被建立 ,但是建立是以先复制任务0的栈为前提的

而此时任务0的栈中有上面提到的"污染"内容在里面。

如果任务0先执行,那么在fork返回后,虽然任务0将它的栈"清空",但是紧接着任务0会执行pause调用 ,如果还是以函数的方式,则在任务0调用pause返回前,如果不巧,进行了schedule到任务1,任务1又使用了栈的话,又会造成上面的情况。


  评论这张
 
阅读(47)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018