--- tags: Linux Kernel Internals, 作業系統 --- # Linux 核心設計: Rust for Linux ## 環境建置 :::info 可交叉搭配 [Linux 核心設計: 開發、測試與除錯環境](https://hackmd.io/@RinHizakura/SJ8GXUPJ6)。這裡只簡單敘述建置步驟。 ::: ### Linux > 完整安裝方式可以參考 [Rust - Quick Start](https://docs.kernel.org/rust/quick-start.html),下面僅針對特定情況做舉例 執行以下可以確認要建構 Rust for Linux 缺少的套件。 ``` make LLVM=1 rustavailable ``` 如果顯示缺少 bindgen 的話,可以根據以下的命令取得。注意這裡需使用 kernel 內建的 scripts 來下載到正確的版本。 ``` cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli ``` 對齊要求的 rustc 版本。 ``` rustup override set $(scripts/min-tool-version.sh rustc) rustup component add rust-src ``` 準備完所有必備的套件後,執行以下並開啟 `CONFIG_RUST` ``` make LLVM=1 defconfig make LLVM=1 menuconfig (General setup --> Rust support) ``` 可以順手也打開一些範例的 Rust module ``` (Kernel hacking --> Sample kernel code --> Rust samples --> ...) ``` :::info 目前的 Rust for Linux (v6.6) 支援的平台是有限的,像是對 ARM、RISC-V 目前都是不支援的,何以得知呢? 我們可以執行下面命令,然後在介面中搜尋 `CONFIG_RUST`: ``` make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- LLVM=1 menuconfig ``` ![](https://hackmd.io/_uploads/Hk3Xnr3gp.png) 畫面中告訴我們 `CONFIG_RUST` 依賴其他 config 首先被正確的設置。而 `CONFIG_HAVE_RUST` 這一項是根據硬體決定是否設置的,由於在 RISC-V 上其為關閉,進而 `CONFIG_RUST` 也就沒辦法在 menu 中被選擇。詳細說明可參考 [Arch Support](https://docs.kernel.org/rust/arch-support.html)。 ::: 一切搞定後,可以正式編譯核心! ``` make LLVM=1 -j$(nproc) ``` ### Busybox 我們選擇透過 [Busybox](https://zh.wikipedia.org/zh-tw/BusyBox) 來作為 initrd。下載該專案後,首先建立設定檔 `.config`。 ``` make defconfig ``` 需要調整 `.config`,以靜態連結的方式來讓將函式庫產生到執行檔中。 ```diff +CONFIG_STATIC=y ``` 接著就可以進行編譯: ``` make -j$(nproc) make CONFIG_PREFIX='rootfs' install ``` 完成後,底下會出現一個名為 `rootfs` 的資料夾,進入並建立和更動一些內容。 ``` cd rootfs mv linuxrc init mkdir -p proc sys dev etc/init.d ``` 接著,在 etc/init.d 底下建立檔案 rcS,並將以下內容複製貼上到其中。 ``` #!/bin/sh mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpfs none /dev mount -t debugfs none /sys/kernel/debug ``` 完成後,調整檔案權限使得該腳本得以被執行。 ``` chmod 777 etc/init.d/rcS ``` 一開始對 `rootfs` 資料夾的變動可以同樣仿造上面作法。但除此之外,在 `rootfs/etc` 資料夾下我們需另外建立 inittab 這個檔案,寫入以下內容。 ``` ::sysinit:/etc/init.d/rcS ::askfirst:-/bin/sh ::restart:/sbin/init ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a ``` 最後,透過以下命令就可以建立出最終需要的 image `root.img`。 ``` find . | cpio -H newc -o | gzip > ../root.img ``` ### 啟動 Linux 環境 可將上述方式得到的 image 透過以下命令載入執行。 ``` qemu-system-x86_64 \ -nographic \ -kernel linux/arch/x86_64/boot/bzImage \ -serial mon:stdio \ -append 'console=ttyS0' \ -initrd busybox/root.img ``` 以開啟 `rust_mininal` 為範例,在開機訊息中應該可以看見類似以下的訊息,這就表示成功開啟 Rust module 了! ``` [ 1.927179] rust_minimal: Rust minimal sample (init) [ 1.927404] rust_minimal: Am I built-in? true ``` ## 撰寫 Rust Kernel Modules ## Reference * [Rust - Quick Start](https://docs.kernel.org/rust/quick-start.html) * [Rust for Linux](https://rust-for-linux.com/)