在上一部分将硬件进行初始化后,接下来就是Boot loader的工作了,这段代码从0x7c00处开始。
那这段代码是从哪里来的呢
在材料中已经给出:
When the BIOS finds a bootable floppy or hard disk, it loads the 512-byte boot sector into memory at physical addresses 0x7c00 through 0x7dff, and then uses a jmp instruction to set the CS:ip to 0000:7c00, passing control to the boot loader
从磁盘中读取一个扇区到内存中,每个扇区固定是512KB。
然后BIOS初始化完成以后再将第一个扇区的内容读到7C00处后,工作就结束了,控制权转交给bios loader
boot loader主要工作是:
1.开启从实模式到32位保护模式
2.把内核代码从磁盘中加载到内存中
在这里实模式和保护模式的区别材料里已经给出
because it is only in this mode that software can access all the memory above 1MB in the PRocessor's physical address space
即访问更高地址的内存,并且从16位变为32位。
首先打开A20地址线
至于为什么要开和为什么这么开,下面有传送门,主要是历史发展的原因为了兼容以前的机子,打开的方法的话主要是和CPU的具体的打开的引脚有关系。
传送门:http://blog.csdn.net/lightseed/article/details/4305865
然后用新的GDT
真正做到从实模式到保护模式的其实就是改变CR0这个寄存器的值。
在这之后,就有虚拟地址和物理地址之分了。
这也是为什么要重新定义GDT,之前的GDT是直接寻址到物理地址的,在这里增加了虚拟地址,所以段表里的东西也会相应进行修改,但是就这个系统的话,到这里即使开了虚拟地址,物理内存还是等于虚拟内存地址的。
这里有一个分段的思想,在LAB2虚拟内存中会详细说明,即把内存分为一段一段用段表进行管理。
跳转指令,跳转到32位的代码段进行执行。就是下面的
从寄存器也能看到从16位变成了32位,上面的一直是eax而到了这里就是ax。在这里为初始化保护模式的寄存器。
接着初始化了一个堆栈,然后就可以调用C程序了。
能够进行函数运算的都需要堆栈,所以之前一直是汇编写的,因为没有堆栈来调用C语言。在这里初始化了寄存器,并且初始化了一个堆栈给C语言有运行的环境。
esp就是栈顶指针,从这里可以看出,把0X7C00这个作为现在的栈顶了。
然后就可以调用Bootmain这个C语言程序了。
新闻热点
疑难解答