本篇文章記錄我在 Ubuntu 24.04 機器上撰寫編譯 init 程式、製作 initramfs 並使用 QEMU 搭配 bzImage 啟動 Linux kernel v6.12。
請先參考 在 Ubuntu 24 編譯精簡 Linux Kernel 文章,完成 Linux Kernel 的編譯。
建立 C 專案結構
1
2
3
mkdir -p my-init/bin
cd my-init
touch init.c
編輯 init.c
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// init.c
#include <stdio.h>
#include <unistd.h>
int main() {
while (1) {
printf("$ ");
fflush(stdout);
char input[256];
if (fgets(input, sizeof(input), stdin) == NULL) break;
printf("Sorry, I don't know how to do that.\n");
}
return 0;
}
把所有需要的函式庫一起打包進 ELF 可執行檔,這樣 kernel 不需要提供任何外部環境就能執行它。
1
gcc init.c -static -o bin/init
建立 initramfs 映像
1
2
3
4
cd bin
chmod +x init
cd ..
find . -print0 | cpio --null --create --verbose --format=newc | gzip -9 > ../initrd
這會產生一個 initrd
,是 gzip 壓縮過的 cpio
檔案,裡面包含你剛剛寫的 init
可執行檔。
啟用 Kernel 支援
1
make menuconfig
開啟這幾個選項:
- General setup —> Initial RAM filesystem and RAM disk (initramfs/initrd) support
- Executable file formats —> Kernel support for ELF binaries
- Processor type and features —> 64-bit kernel
使用 QEMU 啟動
1
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd initrd
預期輸出:
$ Sorry, I don't know how to do that.
$ Sorry, I don't know how to do that.
...
每次輸入都會回應這句話,因為這就是你設計的最小的 shell。