fig 1. 向 bootboot 致敬 |
source code: https://gitlab.com/bztsrc/bootboot 放在 gitlab 很少見, 一般都是放在 github, 作者似乎和 ms 有什麼恩怨的樣子。
圖示很有趣, 是一雙短靴 (不是 fig 1 那張照片), 我一開始以為跑到女性服飾的購物網站, 不過 boot 就是這個意思。
結果另外發現作者提供很多語言版本的 kernel, 除了我想要的 pascal 還有 ada ..., 另外還有其他平台的 bootloader/kernel 版本, 例如 Raspberry Pi4 ...
程式分為兩個部份, 一個是 bootloader, 以 x86 來說有提供 legacy bios, uefi; 另外就是 kernel, 這個就有多語言版本。編譯 pascal 寫的 kernel 要安裝 Free Pascal Compiler (fpc)。
以下介紹的 image 開發環境以 x86-64 uefi 為主, 舊的東西就不說了。其他平台我沒力看了。
編譯 bootboot/x86_64-efi 需要安裝 gnu-efi, 否則會看到缺少 efi.h 的錯誤, 這是一個 efi 開發環境, 有 efi runtime, 讓你不用面對 edk2 這個大傢伙, edk2 太複雜, 僅僅開發 bootloader 用 gnu-efi 就可以。
apt-get install gnu-efi
先來看看怎麼執行裡頭的 image, 以 x86_64-efi 的執行方式, 使用 qemu, 先來把這個 disk-x86.img image 執行起來。
先切到 origin/binaries branch:
git checkout origin/binaries -b binaries cd images另外需要 OVMF.fd, qemu 才能使用 uefi, 請自行搜尋下載。
qemu-system-x86_64 -bios OVMF.fd -hda disk-x86.img -net none這樣就會看到一個圖形畫面, 是 kernel 執行的結果 (fig 2), 整個過程是 uefi bootloader 開機執行之後, load BOOTBOOT/INITRD, INITRD 裡頭有 sys/core, core 就是 kernel。
fig 2 預設 image 執行結果 |
影片是整個執行過程:
由於我已經會用 c 寫 uefi loader, 然後載入 kernel, 但看看他設計的方式也不錯。但讓我真的更感興趣的是用 pascal 寫的 kernel。
再來看看 disk-x86.img, 如何更新編譯後的 kernel? 步驟有點煩雜, 如果對於 uefi, linux initrd 不熟, 可能會難倒你, 需要使用 cpio。我花了一些功夫理解整個 disk-x86.img 的設計。
fig 3. pascal 寫的 kernel |
fig 3 是我修改 pascal kernel 多印一個 pascal 字樣, 以示區別。再來介紹如何更新 image, 換上自己編譯的 kernel。
cd bootboot/mykernel/pas makefile mykernel.x86_64.elf
如果失敗, 可以參考 list 1 的改法。
Makefile 寫的有些錯誤, 在我的環境無法編譯, list 1 是我修正後的結果。
首先用以下指令把 disk-x86.img image 解出來。
# fdisk -lu disk-x86.img Disk disk-x86.img: 128 MiB, 134217728 bytes, 262144 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: gpt Disk identifier: 66AEEDA9-9F6A-2448-34BD-DEE6347D5A4E Device Start End Sectors Size Type disk-x86.img1 128 32895 32768 16M EFI System losetup /dev/loop1 disk-x86.img -o $((128*512)) mount /dev/loop1 a/
整個流程是這樣: uefi 開機之後 load BOOTX64.EFI, BOOTX64.EFI, 會去找 BOOTBOOT/INITRD, INITRD 是一個 cpio 再 gzip 之後的檔案, 類似 linux 的 initrd, 裡頭長這樣:
sys/core 就是編譯出來的 pascal kernel。所以 BOOTX64.EFI load BOOTBOOT/INITRD 之後再去執行 sys/core。
解開 BOOTBOOT/INITRD:
mv INITRD INITRD.gz gzip -d INITRD.gz mkdir a cd a cpio -idv < ../INITRD就會看到 list 3 的目錄結構, 把編譯好的 pascal kernel 複製到 sys/core 即可, 然後製作 cpio 檔案。
cd a find . | cpio -ov > /tmp/object.cpio gzip /tmp/object.cpio cp /tmp/object.cpio.gz BOOTBOOT/INITRD
再來執行 qemu, 不需要製作 image 的檔案, qemu 可以直結讀取一個目錄當作 image file,
qemu-system-x86_64 -drive if=ide,file=fat:rw:img,index=0,media=disk -bios OVMF.fd -net none
img 就是我解開 disk-x86.img 的目錄。如果不熟 linux 這些 image 指令操作, 相信夠你忙一陣子。
另外也可自己打指令把 uefi loader 執行起來。
另外 disk-x86.img 似乎也同時支援 legacy bios, qemu-system-x86_64 -hda disk-x86.img 也可以看到 kernel 畫面。
至於我有興趣的 pascal kernel, 果然對 pascal 不熟, 有很多東西看不懂, 但大多是語法的部份, 關鍵的地方我已經弄懂, 本來應該自己挑戰一個試試, 不過我得先把時間花在別的地方。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。