Setting Up an Environment for Writing Linux Kernel Modules in RustImage Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
$
者,表示其執行在 host 端;而前綴為 #
者,表示其須執行在 guest 端
從 GitHub 下載 linux 的原始碼,
使用 qemu-busybox-min.config 作為設定檔的基底
設定完畢後開始編譯核心
完成後,在 linux 專案目錄底下會產生 vmlinux
輸出檔,這是我們後續開機時要載入虛擬機的系統執行檔。
接著我們開始著手製作 initrd,initrd 的全稱是 initial ram disk,作用是在開機的早期提供系統一些必要的設定檔與工具程式,以利系統進一步開啟與掛載像是檔案系統等重要的子系統。
而這邊挑選的是 busybox
我們一樣可以從 GitHub 上下載 busybox 的原始碼
而這邊可以直接使用預設的設定檔
需要調整的地方是,我們希望產生出來的執行檔,使用靜態連結的方式來連結函式庫。而這樣的好處就是系統不需要先載入動態函式庫,就可以使用 busybox 的執行檔。
設定完成後,就可以開始編譯專案
完成後,可以使用以下命令建立一個簡易的 ramdisk 架構
上述的指令會在專案目錄底下生成一個 _install
的目錄,其中包含 ramdisk 的目錄結構、shell、ls、ps 等工具程式和基本的設定檔。
進入 busybox/_install
中,並使用下列命令產生 ramdisk 映像檔
首先我們先在電腦上安裝 QEMU,這邊使用 apt-get
來進行安裝
安裝完畢後,就可以使用我們在先前建置的核心映像檔來啟動虛擬,,
進入 console 畫面之後,可以發現系統並未順利啟動。這是正常的狀況,因為我們並未引入 ramdisk,因此 kernel 發現無法掛載檔案系統與其他程式
使用 Ctrl - A + X 結束 QEMU 執行,並在啟動的參數中加入先前打包好的 ramdisk 映像檔
再次開啟虛擬機時,可以發現這次 shell 可以被順利開啟,且可以開始鍵入命令來執行各項操作。但是卻會不斷的跳出 tty 無法掛載的訊息。原因就在 BusyBox 的 init
程式預設會開啟 tty[2-5],但是這在的測試環境中並不會被使用,因此我們回到 busybox/_install
目錄來指定我們欲使用的設定
首先需要先在 ramdisk 中建立 etc
目錄,並將範例的設定檔複製到其中
接著編輯 etc/inittab
,將 tty[2-5] 的設定刪除
重複前述打包的動作,重新製作 ramdisk 後,開啟虛擬機,可以發現不會再出現 tty 無法開啟的錯誤訊息。
即使我們修復了 tty 開啟異常的錯誤,我們仍可以在開機的過程中看到如下的錯誤訊息:
且我們也無法使用 ps
來查看當前運行中的程序有哪些
而原因就如同 ps
的錯誤訊息所述,就是目前我們的系統並不會掛載 /proc
的目錄。
我們可以直接用以下的命令來手動掛載 procfs
但考慮到每次開啟虛擬機都需要這樣手動掛載檔案系統,實在是不太實際,因此我們回到 busybox 的目錄底下,透過新增 etc/init.d/rcS
來自動化整個掛載的流程
最後一個我們想要解決的問題是,虛擬機無法連線到網路的問題。首先我們先使用 ifconfig
啟動 loopback interface
這樣如果我們有執行一些簡易的伺服器服務,就可以透過 127.0.0.1
來與服務連線。
而連線到像是 google.com 或是 facebook.com 等外部網路顯然是無法透過啟動 loopback address 就可以達成的,因此我們關閉虛擬機,並在 QEMU 的參數加入網路介面卡的設定
重新啟動虛擬機後,我們就可以看到新的網路界面出現在 ip link
的結果中:
接著我們就可以使用 udhcpc
向 DHCP Server 請求配置 IP 位址
從輸出的結果中,我們可以知道我們所取得的 IP 位址是 10.0.2.3
/etc/init.d/rcS
中,這樣開機時就會自動請求動態 IP 位址
並可以順利連上外部網路
linux