自制一個 Linux 作業系統(3) — Run OS run!

YC
5 min readMar 2, 2020

--

這系列的文章會記錄我嘗試做出一個 Linux OS kernel的過程,要主是依照 https://littleosbook.github.io/ 這系列的文章,加上自已踩下的坑,希望能幫助同樣有做一個作業系統夢想的各位。

續上篇:自制一個 Linux 作業系統(2) — Linking the Kernel

我們進入到 GRUB 的環節。(忘了 GRUB 是什麼的同事可以點這裡重新複習。)

這邊使用的是 GRUB Legacy,但是不論是 GRUB Legacy 或是 GRUB 2 都可以產生我們要的 OS Image。因為我們希望以 CD-ROM 的方式開機,所以 GRUB 會使用一個特別的模式,稱之為 stage2_eltorito。但是作者有說到因為正常在 GRUB 0.97 source code 拿到 config scrpit 在 ubuntu 上不太好用,所以這邊文章中有提供修正後的 stage2_eltorito。

這邊下載。

已經把 GRUB 也準備好了,下一步,制作我們的 ISO Image

我們會使用 genisoimage 來制作我們的 kernel ISO image。我們先建好資料夾來存放我們之前做好的 kernel.elfstage2_eltorito

mkdir -p iso/boot/grub              # create the folder structure
cp stage2_eltorito iso/boot/grub/ # copy the bootloader
cp kernel.elf iso/boot/ # copy the kernel

然後我們需要建立一個 屬於 GRUB 的 config 檔,叫 menu.lst。這檔告訴 GRUB 會用到 kernel 的位置與一些資料。

default=0
timeout=0
title os
kernel /boot/kernel.elf

menu.lst 放到 iso/boot/grub/。現在資料夾結構如下 :

iso
|-- boot
|-- grub
| |-- menu.lst
| |-- stage2_eltorito
|-- kernel.elf

最後,我們回到 iso 資料夾的上一層,使用以下指令來生成 ISO Image :

genisoimage -R                              \
-b boot/grub/stage2_eltorito \
-no-emul-boot \
-boot-load-size 4 \
-A os \
-input-charset utf8 \
-quiet \
-boot-info-table \
-o os.iso \
iso

讓我們看一下 genisoimage 的相關指令代表什麼意思 :

  1. -R : 根據 Rock Ridge 協定產生的 SUSP 和 RR 記錄。(不知道是什麼意思,待補說明。)
  2. -b : 當我們要製作的 CD 是給 x86 用的 El Torito bootable CD,需要指定 boot image 的路徑與檔名。如果 boot image 不是磁片的 image,則需要再加上 -no-emul-boot
  3. -boot-load-size : 指定要在 no-emulation mode 下加載的“虛擬”(512字節)扇區的數量。預設是加載整個啟動文件。如果不是4的倍數,則某些BIOS 可能會出現問題。
  4. -A : CD 的描述內容。
  5. -quiet : 隱藏執行 genisoimage 時的詳細資料。
  6. -boot-info-table : Boot Information Table 是一個 56-byte 長的 table。 (很多太深入的內容,請看 EL TORITO BOOT INFO TABLE )

ISO 有了,來到模擬機上運行吧! 這會是我們第一個 OS !

現在我們可以使用 Bochs 來運行 os.iso ISO image。等等,Bochs 需要先做一點 config 才可以開始運作。

megs:            32
display_library: sdl
romimage: file=/usr/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest
ata0-master: type=cdrom, path=os.iso, status=inserted
boot: cdrom
log: bochslog.txt
clock: sync=realtime, time0=local
cpu: count=1, ips=1000000

因為安裝 Bochs 的方式可能不一樣,可能需要修改 romimage and vgaromimage 的位置。

儲存檔案為 bochsrc.txt,然後運行以下指令 :

bochs -f bochsrc.txt -q
  1. -f : 指定 config 檔。
  2. -q : 略過 start menu。

運行後,我們要先回到 Terminal 按下 “ c ” 鍵,Bochs 才會真的運行起來。否則 OS 並不會被載入。

在載入 OS 後,可以關掉 Bochs,然後我們來顯示 Bochs 的 log :

cat bochslog.txt 

然後找到經由模擬器的 CPU registers 產生的RAX=00000000CAFEBABEEAX=CAFEBABE 值,這就代表成功了 !

坑出現了!坑出現了!坑出現了!坑出現了!

如果你沒有使用圖形介面,你的 Bochs 會無法正常顯示。所以,請使用有 GUI 的 Ubuntu 進行開發。(類似 ISSUE )

下一章,我們會進到第三節,Getting to C
快看 : 自制一個 Linux 作業系統(4) — Ready for C

如果你覺得我的文章幫助到你,希望你也可以化讚為賞,加入 Liker ,再按下方的綠色拍手按鈕,為文章點讚!為作者增加收益,再回饋更多好文章!

--

--

YC

提供更精確的技術內容為目標,另創立「程式愛好者」專頁。資深軟體工程師,專研後端技術、物件導向、軟體架構。