Linux0.11仅支持x86架构。它的内核引导启动程序在文件夹boot内,共有三个汇编代码文件。按照启动流程依次是:
(1)bootsect.s。boot是启动引导的意思,sect即sector,是扇区的意思,二者合在一起启动引导扇区。这是磁盘引导程序。
(2)setup.s
(3)head.s
前两个汇编程序采用近似Intel的汇编语言语法,第三个采用GNU的AT&T语法。必须采用相应的编译器才能进行编译。
系统上电后,Intel的CPU自动进入实模式,CS:IP=FFFF:0000,也就是说CPU在上电或者复位时总是执行物理地址0xFFFF0处的代码。这个地址默认是ROM-BIOS中的地址,在嵌入式系统来说,这里存放的是一级bootloader的执行代码。它完成的操作就是执行系统自检,在物理地址0x00000处开始初始化中断向量表。最后,将启动盘的第一个扇区(0磁道,0磁头,引导扇区)装载到物理地址0x07C00处,并且跳转到这里开始执行此处的代码。而此处代码的作用是将自己移到物理地址0x90000处,因为第一个扇区的代码共512KB=0x0200,所以复制过去的范围就是0x90000-0x901FF。然后,把启动设备中第二个扇区开始的连续4个扇区共2KB代码(setup.s)读入到物理地址0x90200处,内核的其他部分(system模块)则被读入到物理地址0x10000处。因为当时system模块的长度不会超过0x80000字节大小,所以不会覆盖0x90000处开始的bootsect和setup模块。装入完成后,控制转向setup.s。
setup.s首先设置一些硬件设备,然后将内核文件从0x10000处移至0x00000处。系统转入保护模式,执行0x00000处的代码。内核文件的头部是用汇编语言编写的代码,即head.s。
head.s会把IDT(中断向量表)、GDT(全局段描述符表)、LDT(局部段描述符表)的首地址装入到相应的寄存器里,初始化处理器和协处理器,设置好分页,最后调用init/main.c中的main()程序。
这个流程跟嵌入式系统中的bootloader要完成的功能是一致的。在AT91RM9200上移植U-boot时,也是要有三个文件load.bin、boot.bin、u-boot.bin。它们共同点都是先从上电起始位置(硬件设置)跳转到ROM的一级bootloader处,经过处理,跳转到二级bootloader处。完成引导,就可以启动内核,挂载文件系统了。下面的工作是详细分析三个汇编程序完成的工作,对整个启动过程有进一步的了解。以后还要研究一下AT91RM9200的bootloader部分,争取自己写一个比较简单的bootloader。
阅读(921) | 评论(0) | 转发(0) |