Linux引导启动程序程序在boot目录下,有bootset.s, head.s和setup.s(编译后),其中:
bootset.s
系统启动时首先是进入实模式,从地址0xffff0(这地址映射的rom-bios在内存的地址)处开始执行bios代码,然后执行系统检测(也就是自检过程),然后初始化实模式的中断向量表(实模式中断向量在内存物理地址0处)。然后将启动设备的第一个扇区(512字节,也就是bootset.s编译完成的内容)内容读取到内存0x7c00(31kB)处,并且跳转到这里。
跳转到bootset.s后,bootset.s主要做如下工作:
bootset.s在最前面的几句代码先将自己移动到内存0x90000(576kB)处;
bootset.s将启动设备第2个扇区到第五个扇区内容(4个扇区里面存放的是setup.s的内容)读取到内存0x90200处,也就是bootset.s后面;
将内核其他模块读取到0x10000(64KB)处,读取的大小为192KB,对于当时的内核来说确实是足够大了;
在bootset.s偏移508处定义了根文件系统的设备号,并且根据编译选项进行了赋值操代码默认启动驱动器是软盘a,然后就是bootset.s,setup.s,和内核镜像都成放在软盘a中;
setup.s
将系统的一些参数存放在0x90000处,覆盖之前的bootset.s,参数主要包括,内存大小,硬盘参数,显存的参数信息以及根文件系统的设备号;
定义了GDT表,最后加载了gdtr和ldtr,最后跳到保护模式GDT表定义在setup.s,也就是在0x90200的那段内存中,LDT还没有定义。
head.s
其被编译到内核镜像中。重新定义了GDT表(目前就一个第二个段描述符有效)和并定义LDT表(表中中断处理程序目前还是指向一个默认的处理程序),并加载相应的寄存器;
内存开始处设置页目录表,一共有4个叶目录,初始化页目录,然后开启分页,最后跳到主函数main()。
至此,系统启动引导完成。
The link of this page is https://blog.nooa.tech/articles/6c138ff9/ . Welcome to reproduce it!