系统启动

1、史前阶段:BIOS

1、上电自检(Power-On Self-Test):用来检测有什么设备,以及这些设备是否能正常工作
2、初始化硬件设备。
3、搜索一个操作系统来启动。根据BIOS的设置或者用户配置的顺序,从软盘、硬盘、光盘中读取第一个扇区(引导扇区),用来启动系统
4、将找到的第一个有效设备的第一个扇区拷贝到RAM,地址为0x00007c00处,并且开始执行这段代码。

2、远古时代:引导装入程序

软盘启动:
将软盘第一个扇区中的指令装载到RAM,然后执行这些指令(boot loader)将包含内核映像的所有其他扇区都拷贝到RAM

硬盘启动:
a、Linux的引导装入程序叫做LILO(Linux Loader)
b、GRUB(Grand unified bootloader)是另一种Linux引导装入程序,比LILO更加先进。可以识别基于磁盘的文件系统,从文件中读取部分引导程序。
c、LILO分为两部分。因为太大无法装入一个单独的扇区
d、BIOS将第一部分装入0x00007c00处.执行这部分的指令,它将自己移动到0x00096a00,建立实模式栈(0x00098000~0x000969ff),并将第二部分装入到RAM,0x00096c00
e、第二部分依次从磁盘读取可用的操作系统的映射表,供用户选择启动的系统。然后将相应分区的引导扇区拷贝到RAM执行,或者直接拷贝内核镜像到RAM。



3、中世纪:setup()函数

a、setup()位于内核映像文件的偏移量0x200处
b、初始化硬件设备,为内核程序的执行建立环境
c、建立物理内存布局表
d、设置键盘重复延时和速率
e、初始化视频卡
f、重新初始化磁盘控制器并检测硬盘参数
g、检查IBM微通道总线(MCA)
i、检查PS/2指针设备(总线鼠标)
j、检查对高级电源管理(APM)BIOS的支持
k、如果BIOS支持增强磁盘驱动服务(Enhanced Disk drive service,EDD),它就调用相应的BIOS过程在RAM中建立系统可用的硬盘表
l、如果内核映像被低装载到RAM中,就把它移动到XX;如果是高装载,就不用移动。
m、置位8042键盘控制器的A20引脚
n、建立临时中断描述符(IDT),临时全局描述符表(GDT)
o、如果需要,重置浮点单元(FPU)
p、重新编写可编程中断控制器(PIC),屏蔽所有中断,保留IRQ2
q、跳转到startup_32()

4、文艺复兴时期:startup_32()函数

第一个startup_32():
a
、初始化段寄存器和临时堆栈
b、清零eflags寄存器带所有位。
c、用0填充_edate和_end符号标识的内核未初始化数据区
d、调用decompress_kernel()函数来解压内核映像。
e、跳转到物理地址0x00100000处。

第二个startup_32():
a、为第一个Linux进程(进程0)建立执行环境。

5、现代:start_kernel()函数

a、初始化调度程序:sched_init()
b、初始化内存管理区: build_all_zonelists()
c、初始化伙伴系统分配程序: page_alloc_init()
d、初始化IDT: trap_init()
e、初始化软中断: softing_init()
f、初始化系统日期和时间: time_init()
g、初始化slab分配器: kmem_cache_init()
h、初始化CPU时钟到速度: calibrate_delay()
i、为内核进程1创建内核线程: kernel_thread()

原文地址:https://www.cnblogs.com/lipeil/p/4779319.html