注:这篇博文部分内容参考《深入理解linux内核》
启动概念:
在计算机的世界里,启动表示把一部分操作系统装载到主存中并让处理器执行它,也表示内核数据结构的初始化、一些用户进程的创建以及把控制权转移到其中某个进程。
启动的几个阶段:
(1)bios阶段
所谓的bios就是Basic Input/Output System,就是基本输入/输出系统,这个系统的程序在一个ROM芯片上存放着,它是一个只读、持久的存储芯片。
当我们按下电源开关的时候,此时还没有操作系统,这个时候有一个特殊的电路会在cpu的一个引脚上产生RESET信号,RESET之后,会把一些寄存器设置为固定的值,并且执行0xfffffff0处的代码,硬件会把这个地址映射到ROM中,而ROM中存放的就是bios程序。
bios使用的是实模式的地址,因为计算机加电启动时只有这些可以使用。
bios阶段主要执行4个操作。
1)对计算机的硬件进行测试,看这些硬件有没有出现问题,是否工作正常。
2)初始化硬件设备,当这个阶段结束之后,会显示系统中所有安装的pci设备。
3)搜索一个操作系统来启动,这个其实就是我们平常熟悉的开机之后从usb启动呢,还是从cd中启动。
4)找到一个有有效的启动设备之后,就会把相应设备的第一个扇区的内容拷贝到内存中从0x00007c00开始的位置,并且跳到这个地址处开始执行。
(2)引导装入程序阶段
引导装入程序(boot loader)是由BIOS用来把操作系统的内核映像装载到RAM中所调用的一个程序。
磁盘的第一个扇区是MBR(Master Boot Record)——主引导记录,这个扇区包括分区表和一个小的程序,这个小程序就是用来装载被启动的操作系统所在分区的第一个扇区。
如果从磁盘启动linux内核需要一个两步的引导装入程序。linux的引导装入程序叫做LILO,但是比LILO更为先进的是GRUB,因为它可以识别多个基于磁盘的文件系统,而且可以从文件中读入部分引导程序。
LILO可以装在MBR上,代替那个小的应用程序,或者可以装在每个磁盘分区的引导扇区上,但是不管装在哪里,这个时候,我们可以通过选项来选择我们要装入的操作系统。
如果linux内核映像必须被装入,LILO引导装入程序依赖于BIOS过程,主要执行以下步骤:
1)调用一个BIOS过程显示“Loading”信息;
2)调用一个BIOS过程从磁盘装入内核映像的初始化部分,也就是将内核映像的第一个512字节存入从0x00090000开始的RAM中,而将setup()函数的代码存入从0x00090200处开始的RAM中;
3)调用一个BIOS过程从磁盘中装载其他的内核映像;
4)跳转到setup()处。
(3)setup()函数的执行阶段
setup()函数是用来初始化计算机的硬件设备,并为内核程序的执行建立环境。虽然在BIOS阶段已经初始化了大部分硬件设备,但是linux并不依赖于BIOS,而是以自己的方式重新初始化硬件设备,这样做是为了增强linux操作系统的可移植性和健壮性。
硬件设备初始化完毕之后,就会跳转到startup_32()汇编语言的函数处。
(4)startup_32()函数的执行阶段
有两个不同的startup_32()函数。
第一个startup_32()函数主要执行以下的操作:初始化段寄存器和一个临时堆栈、清零eflags寄存器的所有位等,之后就会跳转到0x00100000位置。
第二个startup_32()函数为第一个linux进程(0号进程)建立执行环境。
(5)start_kernel()函数
start_kernel()函数主要完成linux内核的初始化工作。几乎所有的内核部件都是由这个函数仅次那个初始化的。比如调度程序,内存管理去,伙伴系统分配程序,初始化系统的日期和时间,为1号进程创建内核线程。
这些完了之后,就会在控制台出现登录提示符,通知用户。