COMPILATION
編譯與執行

1 開發環境

因為 GRUB2 只能在 LINUX 中編譯,至少目前是這樣,所以建置一個LINUX環境是必要的。 筆者使用UBUNTU 10.10 DESKTOP 和 FEDORA 15 做為開發平台。

在 UBUNTU 10.10 DESKTOP 上編譯 GRUB2,需要另外安裝三個套件 GNU FLEX、GNU M4、GNU BISON。 這是因為編譯 GRUB2 的過程中會使用到套件 GNU BISON 和套件 GNU FLEX,而 GNU BISON 又需要套件 GNU M4。 讀者要上網,取得 GNU FLEX、GNU M4、GNU BISON 三個套件的原始碼檔案,只要打入關鍵字就可以找到下載的網站。 解壓縮後,執行 ./configure、make、make install 三個步驟將該程式安裝到作業系統。

使用 FEDORA15 編譯 GRUB2 時,可以直接編譯,但編譯完成後不要執行 make install。 因為 FEDORA 的載入程式是使用 GRUB 0.98 版,筆者不知道安裝後會發生怎樣的問題。 只是用 FEDORA15 平台做為開發環境而已,只要能順利編譯 GRUB2 就夠了。


2 下載 GRUB2

GRUB2 的原始碼很多地方都有。筆者使用的是 ftp://ftp.gnu.org/gnu/grub/ 中的檔案 grub-1.99.tar.gz。 取得該檔後,建立一個目錄,將檔案解壓縮,會得到 grub-1.99 的目錄資料,此即為 grub2 原始碼。 將 grub-1.99 改名成 grub2,在後面的章節中會以 grub2/ 做為 GRUB2 原始碼的根目錄,說明 GRUB2 的程式內容。


3 編譯 GRUB2

筆者使用 ubuntu 編譯 grub2,無法順利完成。 發現 ubuntu 缺了一些軟體,包括 bison、m4、flex。 只要到網頁上收尋 gnu bison、gnu m4、gnu flex,就可以找到下載位址。 其中 m4 是 bison 的依賴軟體,必須先安裝 m4,才能安裝 bison。 安裝方式是,先執行 ./configure,再執行 make install,即可。

到 grub2/ 目錄中,執行
1 #./configure
2 #make


檔案 configure 是 grub2/ 中的組態描述檔,用於編譯前的組態設定。 將 GRUB2 的組態設定為 I386-PC 的模式,並產生 Makefile ,準備便進行程式碼的編譯程序。 編譯執行器 make 會讀取 Makefile,進行編譯。 編譯過程會產生四種主要類型的檔案,工具執行檔,工具描述檔,核心執行檔,精簡模組檔。

核心執行檔是 GRUB2 執行時的核心程式。 精簡模組檔是一般模組檔經過處理後得到的模組檔,提供核心所需要的所有功能檔案。 工具執行檔和工具描述檔是處理核心執行檔和精簡模組檔的工具群,用以生成各種不同功能的載入程式。

模組檔彼此之間有相依性。因為 A 模組可能會呼叫 B 模組的函式,編譯過程中產生相依關係檔 /gurb-core/moddep.lst。 此檔會由 grub-mkimage 讀取以產生 grub 開機映像。使用者不需要詳細列出相依模組,只要指定注意的模組名稱,即可。
至於,編譯系統為什麼知道他們的相依關係呢? 筆者沒有仔細的追這部分的編譯思路,不過應該和每個程式碼目錄中的 .deps-core 和 .deps-util 有關。 目錄 .deps-core 和核心的相依性有關,目錄 .deps-util 和工具程式的相依性有關。
這裡列出的主要是是核心模組的相依性。

01 videotest: font video gfxmenu
01 loopback: extcmd
01 gcry_des: crypto
01 memrw: extcmd
01 terminfo: extcmd
01 part_gpt:
01 read:
01 gcry_arcfour: crypto
01 aout:
01 vga_text:
01 elf:
01 password_pbkdf2: crypto gcry_sha512 pbkdf2 normal
01 gcry_seed: crypto
01 bsd: elf serial extcmd vbe video aout boot cpuid relocator mmap
01 sfs: fshelp
01 reiserfs: fshelp
01 part_sunpc:
01 gfxmenu: trig bitmap_scale gfxterm font normal bitmap video
01 jfs:
01 help: extcmd normal
01 configfile: normal
01 ohci: cs5536 usb boot pci
01 afs: fshelp
01 xzio: gcry_crc
01 usb_keyboard: keylayouts usb
01 search_fs_file:
01 vga: video video_fb
01 usbms: scsi usb
01 test_blockarg: extcmd normal
01 true:
01 affs: fshelp
01 iso9660: fshelp
01 gfxterm: bitmap_scale font extcmd bitmap video
01 xfs: fshelp
01 functional_test: extcmd
01 sleep: extcmd normal
01 pxecmd: pxe
01 memdisk:
01 gcry_rijndael: crypto
01 gettext:
01 gcry_sha1: crypto
01 cmp:
01 befs_be: fshelp
01 usb: pci
01 hashsum: crypto extcmd normal
01 halt: extcmd acpi
01 search_fs_uuid:
01 linux: normal vbe video boot relocator mmap
01 keystatus: extcmd
01 part_sun:
01 sendkey: extcmd boot
01 video_bochs: video pci video_fb
01 bufio:
01 usbserial_ftdi: serial usb usbserial_common
01 cpuid: extcmd
01 hdparm: extcmd
01 gcry_blowfish: crypto
01 test:
01 nilfs2: fshelp
01 minicmd:
01 ata: scsi pci
01 udf: fshelp
01 gzio:
01 xnu_uuid: gcry_md5
01 uhci: usb pci
01 terminal:
01 raid:
01 crypto:
01 part_bsd: part_msdos
01 cs5536: pci
01 lsapm:
01 gcry_sha512: crypto
01 biosdisk:
01 password: crypto normal
01 fshelp:
01 efiemu: gcry_crc normal acpi
01 xnu: bitmap_scale extcmd normal video bitmap boot relocator efiemu
01 mmap: boot
01 iorw: extcmd
01 zfsinfo: zfs
01 cmostest:
01 blocklist:
01 ext2: fshelp
01 drivemap: extcmd boot mmap
01 part_acorn:
01 videoinfo: video
01 btrfs: gzio
01 lsmmap:
01 bitmap:
01 vbe: video video_fb
01 ntfs: fshelp
01 multiboot: vbe video boot relocator mmap lsapm
01 gcry_crc: crypto
01 png: bufio bitmap
01 jpeg: bufio bitmap
01 regexp: extcmd normal
01 parttool: normal
01 usbserial_pl2303: serial usb usbserial_common
01 cpio:
01 gcry_rmd160: crypto
01 fat:
01 zfs:
01 raid6rec: raid
01 ntldr: boot video relocator
01 minix2:
01 lsacpi: extcmd acpi
01 loadenv: extcmd
01 bitmap_scale: bitmap
01 datehook: datetime normal
01 probe: extcmd
01 tar:
01 hfs:
01 boot:
01 keylayouts:
01 kernel:
01 usbtest: usb
01 relocator:
01 acpi: extcmd mmap
01 tga: bufio bitmap
01 reboot:
01 serial: extcmd terminfo
01 befs: fshelp
01 dm_nv: raid
01 font: bufio video
01 raid5rec: raid
01 datetime:
01 video:
01 example_functional_test: functional_test
01 pci:
01 hfsplus: fshelp
01 gcry_cast5: crypto
01 extcmd:
01 gcry_whirlpool: crypto
01 pxe: bufio
01 gcry_tiger: crypto
01 video_fb: video
01 search: search_fs_uuid search_fs_file extcmd search_label
01 lspci: extcmd pci
01 trig:
01 afs_be: fshelp
01 msdospart: parttool
01 gcry_twofish: crypto
01 testload:
01 part_apple:
01 hexdump: extcmd
01 ata_pthru: ata
01 pbkdf2: crypto
01 gcry_sha256: crypto
01 date: datetime normal
01 usbserial_common: serial usb
01 ls: extcmd normal
01 ntfscomp: ntfs
01 video_cirrus: video pci video_fb
01 scsi:
01 hello: extcmd
01 normal: terminal gfxterm crypto extcmd boot
01 linux16: boot video relocator mmap
01 cat: extcmd
01 ufs1:
01 mdraid09: raid
01 lvm:
01 chain: boot video
01 ufs2:
01 setpci: extcmd pci
01 search_label:
01 gptsync:
01 setjmp:
01 multiboot2: vbe boot video relocator mmap lsapm acpi
01 gcry_rfc2268: crypto
01 mdraid1x: raid
01 legacycfg: linux crypto password gcry_md5 normal
01 play:
01 part_amiga:
01 minix:
01 echo: extcmd
01 gcry_serpent: crypto
01 gcry_md4: crypto
01 gcry_md5: crypto
01 part_msdos:
01 gcry_camellia: crypto
01 at_keyboard: keylayouts boot


4 製作開機映像

經過編譯過程後,所有需要用到的檔案都已經預備好,可以用來製作開機映像。
GRUB2 可以做軟碟開機映像,光碟開機映像,硬碟開機映像 (直接安裝)。
可以將編譯好的 GRUB2,直接執行 make install,就會將 GRUB2 直接安裝成該主機的載入程式。
也可以使用 grub-mkrescue 製作開機映像檔,再寫入軟碟片或光碟片中,用來開機。


筆者製作開機映像的方法是,把編譯完成的 grub2 複製,改名稱為 grub2ools。
再把目錄 grub2ools/grub-core/ 的檔案(不包含目錄)複製到目錄 grub2ools/。
過程中會有檔案覆蓋的情形,直接覆蓋即可,因為那些檔案是建構系統的檔案,完成編譯後就不需要了。
這樣做的目的是要讓所有的工具程式、工具描述檔、GRUB 核心執行檔、精簡模組檔都在同一個目錄。
這樣就不用打很多的路徑字串,直接打檔名就好了。


接下來,在目錄 grub2ools/ 中建立目錄 images,用來存放產生的映像檔。
在命令列上打入下列命令,製作 GRUB2 映像,此映像將會包含啟動程式、GRUB核心映像、normal 模組檔 和 normal 模組的相依模組群。
normal 模組的相依模組群列在 moddep.lst,包括 boot、gfxterm、extcmd、crypto、terminal 等模組。

01 $./grub-mkimage -o core.img -O i386-pc -d . normal
02 $ cat cdboot.img core.img > images/cd-g2ldr
03 $ mkisofs -R -J -no-emul-boot -boot-info-table -boot-load-size 4 -b cd-g2ldr -o images/grub2cd.iso images/

行號說明
01 製作 GRUB2 映像。
-o core.img 表示輸出檔為 core.img。
-O i386-pc 表示 I386-PC 格式。
-d . normal 表示取用目前目錄的 normal 模組檔案。
core.img = diskboot.img + compressed(kernel.img+modules)。
02 將光碟啟動映像和GRUB核心映像加入 cd-g2ldr。
cd-g2ldr=cdboot.img + core.img。
如果是軟碟開機映像則是 floppy.img = boot.img+core.img。(應該是這樣.)
03 製作開機光碟映像,產生 grub2cd.iso。此檔可燒成光碟,也可以用 QEMU 模擬,或者用 VIRTUALBOX 模擬。

5 模擬

開機映像檔也可用於虛擬機器(如 QEMU,VIRTUALBOX) 模擬 GRUB 的開機動作。 QEMU 是 LINUX 上使用普遍的虛擬機器,VURTUALBOX 是 WINDOWS 上普遍的虛擬機器。

在 QEMU 上使用光碟開機映像的指令是 $qemu -m 32 -cdrom grub2cd.iso -boot d 即可。

筆者是用 VIRTUALBOX 模擬 UBUNTU 10.10 DESKTOP,再執行 QEMU 模擬 GRUB2。
QEMU 模擬 GRUB2 的畫面:

GRUB2

VIRTUALBOX 模擬 GRUB2 的畫面:

GRUB2

5 軟碟模擬

在 QEMU 上使用軟碟開機映像的指令是 $qemu -m 32 -fda floppy_os.img -boot a,即可。
在 linux 上則是 $kvm -m 32 -fda floppy_os.img -boot a,之後,按 ctrl+alt 釋放滑鼠,再關閉模擬器。