Linux0.11之加载二进制文件
因为先接触的是嵌入式OS,所以在阅读linux0.11源码的时候,总是会带些嵌入式OS惯性思维在思考,关于linux0.11中用户入口是我从头到尾看的过程中一直思考和寻求的问题,我很想知道对于一个用户的例程或者行为,内核的处理流程。
先说下嵌入式OS,看嵌入式OS的时候我会在内核代码中看到一个用户API接口文件夹,里面封装了所有系统函数,供给用户调用,这样的一个接口形式非常清晰。嵌入式OS会提供main接口给用户插入自己的代码,比如创建进程,创建进程时指定入口函数就可以,这样创建进程后系统就会调度到该进程,就会从用户写的函数入口开始执行。很显然,用户例程和内核时编译在一起的。
Linux平台下通常说的用户API接口库是GLIBC,但是它不同内核一起编译,用户例程也一样。Linux平台下通常时这样的,用户用GLIBC提供的API接口编写了用户例程,编译好之后成为可执行文件,然后通过shell加载并运行。
从上面看来,shell加载运行可执行文件就是内核处理用户例程或者操作的关键所在了。
先贴上一个图来看一下内核对于shell的响应流程。这个时《linux0.11内核完全注释》中的一个截图。
这个图对应的代码这儿就不贴了。/bin/sh是一个可执行的linux外壳程序,内核加载并运行sh的过程如上所示,先fork一个进程,然后调用execve系统调用加载sh可知性文件,这个加载的过程参见do_execve函数执行,简单的说就是把刚刚fork的一个进程的上下文配置成sh的上下文,加载之后sh就开始执行了,sh进程可以说时用户与内核之间的桥梁,用户通过sh命令使得内核执行用户的例程。比如用户编写了一个hello.c,编译成可知性hello,sh中./hello命令则可以让内核执行hello了。这里我得强调下sh在这个过程中做的事情,sh会先fork一个进程,然后调用execve系统调用加载hello,这个过程跟sh被内核加载时一样的。Sh和hello都是可执行文件,内核加载一个sh,sh用来加载用户的可执行文件。
到了这里也就知道了,linux0.11中用户入口并不是main,而是 mian运行起的sh。用户例程也不和内核一起编译,内核通过加载用户可执行文件运行用户例程,所以,linux平台离不开文件系统。