内核的启动代码流程
内核启动代码位于 init/main.c中的start_kernel函数。start_kernel函数初始化内核的多个模块。
这里还创建了0号、1号、2号进程。0号进程是第一个进程,唯一一个没有通过 fork 或者 kernel_thread 产生的进程,是进程列表的第一个。1号进程是第一个用户进程,也是所有用户态进程的祖先。
进程之间需要隔离资源,因此系统有了权限分层的机制。
当一个用户态的程序运行到一半,要访问一个核心资源,例如访问网卡发一个网络包,就需要暂停当前的运行,调用系统调用,接下来就轮到内核中的代码运行了。
首先,内核将从系统调用传过来的包,在网卡上排队,轮到的时候就发送。发送完了,系统调用就结束了,返回用户态,让暂停运行的程序接着运行。
系统调用资源需要保存,调用之后再恢复。
创建1号进程的时候,需要访问1号进程的程序,这个程序是保存在ramdisk系统中的, ramdisk系统是一个内存文件系统, 因为我们访问设备的时候需要驱动,不同的设备驱动又不一样,不可能在内核里面内置所有的驱动,因此我们默认加载了ramdisk文件系统, 1号进程的文件 init就放在ramdisk中,从而可以快速的读取执行并运行init。1号进程是所有用户态进程的祖先。
同理,2号进程 kthreadd,是所有内核态进程的祖先。
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。