在上一部分將硬件進行初始化后,接下來就是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語言程序了。
新聞熱點
疑難解答