Linux0.11的内核引导启动流程

         Linux0.11的内核引导启动程序由boot/目录下的bootsect.s、setup.s和head.s完成,由于内核的启动涉及到硬件操作比较多,所以均是汇编文件。

     讲述内核引导启动流程前,先了解Linux0.11中的bootsect.s、setup.s和head.s的大小,因为能够帮助后续理解。

     bootsect.s-----5052bytes(小于5KB)

     setup.s --------5364bytes(小于6KB)

     head.s --------5938bytes(小于6KB)

    但是这里要特别注意,文件的未编译大小是远远大于编译后的大小的,而PC运行的是编译后的文件,也就是机器码。只有这样,下面的过程分析才能合理的理解。

    总体过程描述:

PC上电后,CPU会自动从地址0xFFFF0地址开始自动执行程序代码,这个地址通常是ROM-BIOS中的地址,其中ROM-BIOS相当于是PC的BIOS,是计算机厂家编写的。PC机的BIOS将执行某系系统检测,并且在物理地址0处开始初始化中断向量,然后,PC将可启动设备的第一个扇区(就是引导扇区,操作系统的引导代码,其实就是bootsect.s、setup.s和head.s)读入绝对地址0x7C00处,并跳转到这个地方。

      Linux0.11的最前面部分就是引导部分的bootsect.s,它被BIOS读入到内存绝对地址0x7C00(31K)处,当bootsect.s被执行时,它会将自己移动到绝对地址0x90000(576kb)处,然后将启动设备(硬盘)中的后2KB代码(boot/setup.s)移动到0x90200处,而内核的其他部分(system模块:所有剩余的*.c等文件编译后的模块)被读到0x10000处,因为system模块的长度不会超过0x80000字节(512kb),所以它并不会覆盖0x90000后面的bootset和setup模块。

     bootsect.s的主要作用-“搬运代码”:是将自己移动到内存0x90000处,然后将setup模块从磁盘加载到内存(0x90200),紧接着bootsect,利用BIOS终端0x13取磁盘参数表中当前启动引导盘的参数,在屏幕上显示“Loading system...”,然后将system模块从磁盘加载到0x10000处,然后确定根文件系统设备号,保存设备号于root_dev,最后长跳转到setup程序的开始出(0x90200)执行setup程序。

    setup.s的作用是-“获取硬件配置参数,进行“安装”各种硬件配置参数”:利用ROM BIOS中断读取机器系统数据,将这些数据保存到0x90000处(覆盖掉bootsect,因为此时bootsect已经没用),这些参数将被内核中相关程序使用,如字符设备驱动程序。然后将system模块从0x10000-0x8fff整块向下移动到内核绝对位置0x0000,加载中断描述符寄存器和全局描述符寄存器,开启A20地址线,设置CPU进入保护模式,跳转到system模块的最前部分head.s程序继续运行。

    head.s的主要作用-“正式进入linux前的工作”:加载数据段寄存器,设置中断描述符表idt,共256项,使各个表项均指向一个只报错误的哑中断程序,然后重新设置全局描述符表gdt,设定管理内存的分页处理机制,利用返回指令,将预先防止在堆栈中的/init/main.c程序的入口地址弹出,去运行main()程序。

    系统加电后,运行程序流程如下图1所示:

Linux0.11的内核引导启动流程_第1张图片

    启动引导内核时,内核在内存中的位置及移动后的位置情况如下图2所示:

Linux0.11的内核引导启动流程_第2张图片


你可能感兴趣的:(Linux-0.11注解)