昨天花了一天的时间在看Linux0.11的内核,当看到main.c中的int()函数的时候被一个系统调用难倒了(其实笔者的c,汇编等基础并不是很厉害。但是处于某些原因,就入了这个内核的坑,被浇冷水是经常的事情)。于是各种资料各种搜索,但是大家给出的资料都是千篇一律,不是一开始就介绍什么是系统调用,就是没有切实的去一句一句的剖析系统调用的原理,反正就是巴拉巴拉说的基本都是一样,看下来还是什么都不懂…… ps:可能是笔者真的太渣,没办法理解。
于是我便自己看是研究了,首先是从init哪那里开始,针对fork()这个系统调用开始了深入的研究(其实也不是很深入了,哈哈哈)。跟踪它实现的过程,我想现在或者以后也会有人遇到跟我类似的问题,再加上想更加巩固一下掌握的知识,就着手写了这篇博了,那么开始正题吧!
首先要说的是,我们现在针对的是Linux0.11版本内核中的fork()系统调用来对系统调用做分析。
当调用fork()函数时,在main.c中的init()函数中就出现了fork()的调用:
// 下面fork()用于创建一个子进程(子任务)。对于被创建的子进程,fork()将返回0 值,
// 对于原(父进程)将返回子进程的进程号。所以180-184 句是子进程执行的内容。该子进程
// 关闭了句柄0(stdin),以只读方式打开/etc/rc 文件,并执行/bin/sh 程序,所带参数和
// 环境变量分别由argv_rc 和envp_rc 数组给出。参见后面的描述。
if (!(pid = fork ()))
{
close (0);
if (open ("/etc/rc", O_RDONLY, 0))
_exit (1); // 如果打开文件失败,则退出(/lib/_exit.c,10)。
execve ("/bin/sh", argv_rc, envp_rc); // 装入/bin/sh 程序并执行。
_exit (2); // 若execve()执行失败则退出(出错码2,“文件或目录不存在”)。
}
大家应该都知道这个函数,确切的说应该是系统调用是用来创建一个新进程的。但是大家会发现内核里面根本找不到这个函数的具体原型,那它到底是怎么实现的呢?我们可以用编辑器查看的定义,我用的是source Insight 3 ,发现