linux-0.11 study note

本文详细解析了Linux内核中fork系统的实现过程,包括PE设置、保护模式启动、初始化段寄存器、IDT/GDT配置、x87协处理器检查,以及分页设置后的main函数调用路径。同时解释了fork返回值的不同原因,以及父子进程在执行路径上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.

在boot/setup.s文件189~191设置PE并开始进入保护模式,然后开始执行head.s

里面的指令,即startup_32标示符处的代码,初始化各个段寄存器,并设置IDT、GDT
检查有没有x87(协处理器),然后无条件跳转到137行after_page_tables标示符处,
在这里压入3个参数值,及调用init/main函数后返回地址,和main函数的地址也压入栈,
这样在设置分页(setup_paging)结束后执行ret指令时会将main地址弹出堆栈,并去
执行main函数里面的代码了。


2.


3.

大家都知道,对于父进程 fork 返回子进程号,对于子进程 fork 返回 0 ,这也是执行路径如此的原因所在。但是, fork 的返回不同值的原因又是什么,这就得看 fork 的实现了。

fork 先是调用 find_empty_process 为子进程找到一个空闲的任务号,然后调用 copy_process 复制进程, fork 返回 copy_process 的返回值 last_pid ,也就是子进程号。

从上面的实现看来, fork 的返回值不会是 0 , last_pid 从 1 开始,父进程执行 if 外面的部分,上面的逻辑正是父进程的执行逻辑。

对于子进程,先看子进程的初始状态, copy_process 中创造了子进程的上下文执行环境,这个上下文环境正是父进程 fork 系统调用时的环境,其中, p->tss.eip 正是被赋值为 fork 之后下一条指令地址,这就是子进程和父进程都返回到 fork 下一条指令处的原因。同时,需要注意的是, p->tss.eax 被赋了值 0 ,当调度到子进程开始执行时,首先加载其上下文环境, eip 被加载为 fork 之后下一条指令, eax 就被加载为 0 ,所以,对于子进程来说,和父进程唯一的区别就是返回值( eax )为 0 ,子进程执行 if 里面的部分。之所以造成这样一个函数的不同代码段被两个进程执行,是和 linux0.11 的内核创建进程实现相关的


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值