2010年10月25日 星期一

GRUB FOR DOS 的總體框架

文章出處:http://www.linuxeden.com/blog/?uid-19847-action-viewspace-itemid-5490
GRUB FOR DOS 的總體框架
bendany 建議我寫一寫 GRUB4DOS 的大致結構,以便準備投入開發 GRUB4DOS 的朋友們能夠對此有一個快速的瞭解。我試試吧,就寫了這篇短文。文章有什麼不妥的,或者需要補充的,希望大家提出來,我再加以完善。幾年前寫過兩三篇 GRUB4DOS 的技術文章,雖然某些內容有些陳舊,但似乎也還可以用。有需要的朋友,可以在各大搜索引擎中搜索grub for dos 或者 grub.exe 或者 grldr 等字眼,應該能夠找到那些文章。這次不重複那些文章的內容了,主要面向準備繼續開發 Grub4dos 的朋友們。
[@more@]
  GRUB for DOS 是 GNU GRUB 的功能擴展,是以 GNU GRUB 為基礎的。有關 GNU GRUB 的技術資訊,可以由 Linux 下的 info grub 命令獲得。這裏主要說說 GRUB for DOS 的特有資訊,並且只是粗略的、輪廓性的介紹。詳細的資訊還是要通過源代碼才能得到。在關鍵的地方,源代碼中都有比較詳細的注釋。
1。啟動過程,啟動方式
  GNU GRUB 的啟動過程大致是這樣的:512 位元組的 stage1,放在 MBR 或者軟碟第一磁區,它從 BIOS 那裏獲得控制,然後它負責查找 stage1.5 或者 stage2。其實,stage1 在被放置到 MBR 或者軟碟第一磁區的時候,已經把 stage1.5 或者 stage2 的物理磁區位置記錄到 stage1 的某個區域中了,這通常稱為硬編碼。這些都不重要,重要的是,stage1 和 stage1.5 都不是 GRUB 的主體,它們都是為了把 stage2 裝入到記憶體中,除此之外,它們沒有別的用處。
  stage2 又分兩部分:第一部分是 512 位元組的開頭,它像 stage1 一樣,裏面含有 stage2 的物理磁區位置列表,整個磁區沒有別的用處,僅僅只是為了尋找 stage2 的後續部分(也就是從第二磁區開始一直到檔結尾)。這第二部分才是 GRUB 的主程序體,它叫做 pre_stage2。也就是說,stage2 = 512 位元組的頭部 + pre_stage2
stage1 和 stage2 中都含有磁區絕對定位資訊,這些資訊,是在將 GNU GRUB 安裝到 MBR 或者軟碟第一磁區時,由 setup 命令計算之後寫入的。
  說了這麼多,其實只是為了說明一點:pre_stage2 才是對我們的 GRUB FOR DOS 有用的。所以,你在程式中會看到 pre_stage2_start 這個標號。
  GRUB FOR DOS 主要有兩大類啟動方式。一類是從作業系統中啟動(grub.exe),一類是由 BIOS 引導啟動(GRLDR)。
  GRLDR 也可以由 NTLDR 啟動,不過這其實也類似於從 BIOS 啟動,因為由 NTLDR 所賦予的啟動環境,沒有破壞 BIOS 中斷向量。
  GRUB.EXE 可以從 DOS/Windows9x 下運行,也可以經由 kexec 而從 Linux 下運行,或者也可以經由 LILO 或者 syslinux 這類引導器而啟動運行。這又分為兩種情況:在 DOS/Windows9x 下,GRUB.EXE 是被作為 DOS 的可執行檔或者可以作為 CONFIG.SYS 裏的設備驅動檔而運行。在其他情況下,GRUB.EXE 是作為 LINUX 內核格式而被啟動運行的。
2。檔結構
  GRLDR 的檔結構相對來說比較單一,源代碼文件是 grldrstart.S。它的第一磁區,是啟動代碼,如果這是在 MBR 上,它負責裝入位於硬碟第一磁軌上的其餘磁區。如果是經由 NTLDR 啟動,那麼 NTLDR 會裝入 GRLDR 的開頭 16 個磁區。這些磁區中的代碼,負責查找各個硬碟各個分區根目錄下的 grldr 檔,並裝載整個 grldr 檔到記憶體中。緊接著 GRLDR 開頭的 16 磁區,就是 pre_stage2 了。GRLDR 開頭的 16 磁區代碼,負責把 pre_stage2 放到 0000:8200 處,並把控制交給 pre_stage2。在 GNU GRUB 中,0000:8000 處放置的是 stage2,由於我們不用 stage2 的第一磁區,所以,我們直接把 pre_stage2 放置在 0000:8200 了。
  bootlace.com 可以用來將 grldr 的啟動代碼寫入到 MBR 或者軟碟的第一磁區上。其實,寫入到 MBR 上的,不完全就是 GRLDR 開頭的 16 磁區,而是 GRLDR.MBR 檔的內容(只有第一磁區的若干個控制位元組會被改動,以及硬碟分區表會被加入到第一磁區,而第二磁區可以放置硬碟上原來的 MBR 作為備份,其餘磁區都原封不動地被拷貝到第一磁軌的相應磁區上)。bootlace.com 是雙重可執行檔格式:它可以在 DOS 下運行(作為 .com 可執行檔),也可以在 Linux 下運行(作為 ELF 可執行檔)。GRLDR.MBR 檔將來可以增大到 63 個磁區那麼長,這是一個磁軌長度的最大上限。但是 GRLDR 檔的開頭部分卻只能有 16 個磁區那麼長,因為 NTLDR 只能裝入這麼長,它不能為我們直接裝入全部的 GRLDR 檔。GRLDR.MBR 的源代碼文件是 mbrstart.S。bootlace.com 的源代碼文件是 bootlacestart.S。
  GRUB.EXE 是三重檔格式。它的結構比較複雜。首次看源代碼的時候,可以先忽略它作為 DOS 設備驅動程式檔格式的那些代碼,因為那可能比較難以理解。而作為 DOS 的 EXE 格式以及作為 LINUX 的 bzImage 格式,都是比較容易理解的,因為這方面的資料很容易找到。源代碼文件是 dosstart.S。像 GRLDR 的情況那樣,GRUB.EXE 也是由開頭的啟動代碼以及 pre_stage2 這兩部分構成的。
  pre_stage2 的源代碼文件是 asm.S,它會調用其他 C 語言程式檔。這些 C 檔和 asm.S 一起編譯生成 pre_stage2 檔。builtins.c 檔含有各種命令的代碼,包括 map 命令。如果要為 GRUB 增添拷貝檔或者創建檔的命令,則需要修改 fsys_*.c 檔,它們是各種檔系統的驅動程式檔。
3。記憶體的使用
在物理位址 0x800 到 0x17FF 這 4K,放置嵌入到 GRUB.EXE 命令行的那些命令。只有從 CONFIG.SYS 中用 device=grub.exe --config-file="GRUB_COMMANDS" 的方式,才可以嵌入接近 4K 的 GRUB 命令,其他方式都受具體環境的限制。比如,DOS 命令行不超過 127 個字元。GRUB.EXE 作為 Linux 內核格式,它也只能接受最多 512 位元組的命令行。
  物理位址 2M 處放置備份的 640K 的 DOS 常規記憶體,以便 quit 命令可以恢復 DOS 的現場。

沒有留言:

張貼留言