作者:30erli
原创作品转载请注明出处 + 《Linux内核分析》MOOC课程
linux启动过程
1.实验截图
1开始内核初始化
2内核初始化完毕,执行init
2.内核启动过程
- 机器加电,处理器完成自检和初始化,设置各寄存器的初值,而后开始执行指令。因为32位Intel处理器在加电,reset或init后,控制寄存器CR0初值为0x60000010H,由此对应处理器是在实模式下,分页机制没有启动(PE=0,PG=0),因此,处理器所使用的地址和操作数的长度为16位;代码段寄存器CS的初值为0xF000H,指令寄存器EIP的初值为 0xFFF0H(这两个值也是由Intel处理器的体系结构定的,所以下面说的0xFFFF0H的道理也就在这里了。)
- 处理器执行的第一条指令的地址是CS×16+IP,即0XFFFF0H,而该地址离实模式下处理器的最大地址0xfffffH仅有16字节,是驻留在ROM中的BIOS的入口地址,处理器从此处开始执行指令,因此最先获得机器控制权的是BIOS。
- BIOS完成对整个机器系统的检测,并将有关系统配置的基本信息(比如...)记录在内存的BIOS的数据区中(BIOS数据区在什么地方?),然后,从引导盘上将一个引导扇区,读入到内存的0x7c00H处,其实被复制到物理内存的内容就是BOOTLOADER,具体到你的电脑那就是lilo或者grub了,然后转到0x7c00处,将对机器的控制权交给引导程序(为什么被读到内存的0x7c00h处这个地址呢?这个地方是个约定)
- 引导程序bootloader开始负责操作系统的初始化,以grub为例来说,grub读取内存中的grub配置信息(menu.lst或grub.lst)现在系统大多使用grub2来引导,读取的文件也变成了/boot/grub/grub.cof文件,然后依照此配置信息来启动不同的操作系统。(引导程序BootLoader开始负责操作系统初始化,然后起动操作系统。启动操作系统时一般会指定kernel、initrd和root所在的分区和目录,比如root (hd0,0),kernel (hd0,0)/bzImage root=/dev/ram init=/bin/ash,initrd (hd0,0)/myinitrd4M.img)(一般分两阶段启动,先是利用initrd的内存文件系统,然后切换到硬盘文件系统继续启动。initrd文件的功能主要有两个:1、提供开机必需的但kernel文件(即vmlinuz)没有提供的驱动模块(modules) 2、负责加载硬盘上的根文件系统并执行其中的/sbin/init程序进而将开机过程持续下去)
- 加载内核,根据grub设定的内核映像所在的路径,系统读取内存映像,并进行解压缩操作,此时屏幕上一般输出"Uncompressing Linux"的提示。当解压缩内核完成后,屏幕输出"Ok,booting the kernel"系统将解压后的内核放在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成linux内核的初始化。
- 内核进行初始化,内核的初始化过程结束后,就会把控制权交给/init程序,从此进入用户空间;因为内核先是将 initramfs 文件挂在为根文件系统,所以刚开始运行的/init程序其实是 initramfs 文件中的,所以该文件需要的重要的初始化脚本、内核模块、配置文件等,都位于 initramfs 文件中,这也是为什么很多时候我们修改了某些配置文件后,需要先更新 initramfs 文件再重启操作系统才会生效;
initramfs 文件中的/init程序负责挂载硬盘上的文件系统,然后再把根文件系统切换到硬盘上的根分区,再运行/sbin/init程序,这时所有程序、配置文件、脚本都是使用的硬盘上的了,当然,网络文件系统也是同理。可以看出 init 程序的运行也是一个分阶段的过程;/sbin/init程序负责系统的初始化、各种服务的运行、用户的登陆等等; - /sbin/init,该文件会读取/etc/inittab文件,并依据此文件进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级。
- 在设定了运行等级以后,Linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序,这个脚本做的工作非常多,包括设定PATH,设定网络配置(/etc/sysconfig/network)启动swap分区,设定/proc等。
- 依据/etc/modules.conf文件或者/etc/modules.d目录下的文件夹来装载内核模块。
- 执行不同运行级别的脚本程序,根据运行级别不同,系统会运行rc0.d到rc6.d中相应的脚本程序,来完成相应的初始化和启动相应的服务。
- 执行/etc/rc.d/rc.local。rc.local就是在一切初始化后,linux留给用户进行个性化的地方,你可以把你想要设置和启动的东西放在这里。
- 执行/bin/login,进入登录状态
3.小结
本次实验有很多地方都有很多不透明的地方,也有很多困惑。本次实验也就是进行启动步骤的第5步,完成了内核的初始化,执行到了initrd里的init。至于启动前是否是grub引导还不敢乱说。