本文使用 archlinux 进行操作

配置环境

安装 base-devel包组 软件组,这个组包含了 make包 等我们需要的软件包。参考 Arch 默认内核的 PKGBUILD,同时可能需要安装以下软件包:xmlto包、kmod包、inetutils包、 mkinitcpio包、 bc包、libelf包、git包、cpio包、perl包、tar包、xz包。

安装 llvm 工具链:clang lld lldb llvm libc++

安装 rustup: rustup

安装 qemu: qemu-full

编译 linux for rust

源码与 rust 环境

# 下载源码
git clone https://github.com/Rust-for-Linux/linux -b rust-dev
cd linux
# 配置环境
rustup override set $(scripts/min-tool-version.sh rustc)
rustup component add rust-src
cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli
# 验证环境
make LLVM=1 rustavailable

如果 make LLVM=1 rustavailable 提示 Rust is available! 就ok了。

内核设置

# 创建默认配置
make ARCH=x86_64 LLVM=1 O=build defconfig
# 你也可以使用 zcat /proc/config.gz > 。./build/.config 把你当前的内核配置写入.config
make ARCH=x86_64 LLVM=1 O=build nconfig
#General setup
#        ---> [*] Rust support
#              ^ 按空格开启 即 [*]
  • make menuconfig: 老的 ncurses 界面,被 nconfig 取代
  • make nconfig: 新的命令行 ncurses 界面
  • make xconfig: 用户友好的图形界面,需要安装 packagekit-qt5包。建议没有经验的用户使用此方法。
  • make gconfig: 和 xconfig 类似的图形界面,使用 gtk.

制作 rust hello world 模块

源码

vim samples/rust/rust_helloworld.rs

填入以下内容

// SPDX-License-Identifier: GPL-2.0
//! Rust minimal sample.
      
use kernel::prelude::*;
      
module! {
  type: RustHelloWorld,
  name: "rust_helloworld",
  author: "whocare",
  description: "hello world module in rust",
  license: "GPL",
}
      
struct RustHelloWorld {}
      
impl kernel::Module for RustHelloWorld {
  fn init(_module: &'static ThisModule) -> Result<Self> {
      pr_info!("Hello World from Rust module");
      Ok(RustHelloWorld {})
  }
}

配置

vim samples/rust/Kconfig

添加以下内容

要在 if SAMPLES_RUST 和 endif # SAMPLES_RUST 之间添加

config SAMPLE_RUST_HELLOWORLD
  tristate "Print Helloworld in Rust"
  help
    This option builds the Rust HelloWorld module sample.

    To compile this as a module, choose M here:
    the module will be called rust_helloworld.

    If unsure, say N.
vim samples/rust/Makefile

添加以下内容

obj-$(CONFIG_SAMPLE_RUST_HELLOWORLD)        += rust_helloworld.o

修改 .config 开启 rust hello world

make ARCH=x86_64 LLVM=1 O=build nconfig

Kernel hacking
—> Sample Kernel code
—> Rust samples
—> Print Helloworld in Rust (NEW)

# 检查
cat build/.config | grep SAMPLE_RUST_HELLOWORLD
cat build/.config | grep SAMPLES_RUST
# CONFIG_SAMPLE_RUST_HELLOWORLD=m
# CONFIG_SAMPLES_RUST=y

构建内核

# 构建内核
cd build
make ARCH=x86_64 LLVM=1 -j12
# Kernel: arch/x86/boot/bzImage is ready  (#3)

构建 initramfs.img

建议查看:https://wiki.archlinuxcn.org/wiki/Mkinitcpio#常用钩子

sudo make ARCH=x86_64 LLVM=1 modules_install
# 也可以 HOOKS=(base systemd autodetect modconf block filesystems keyboard fsck)
echo "HOOKS=(base udev resume autodetect modconf block filesystems keyboard fsck)" > ./mkinitcpio.conf
sudo mkinitcpio -k $(pwd)/arch/x86_64/boot/bzImage -c ./mkinitcpio.conf -g ./initramfs.img
sudo chmod ugo+r ./initramfs.img

内核和 initramfs 已经完成,但我们需要一个硬盘来运行一切

创建 raw 并安装 archlinux

dd if=/dev/zero of=rawhd bs=1M count=4096
# 格式化硬盘
mkfs.ext4 ./rawhd
# 挂载硬盘
sudo mount rawhd /mnt
sudo pacman -S arch-install-scripts
# 安装 archlinux
sudo pacstrap /mnt base base-devel vim
# 复制我们编写的 rust_helloworld
sudo cp samples/rust/rust_helloworld.ko /mnt/
genfstab -U /mnt

$ genfstab -U /mnt
# /dev/loop0
UUID=920290b2-8f5e-4222-96b5-ae911205eef7 / ext4 rw,relatime 0 1

/swapfile none swap defaults 0 0

# 把环境切换到新系统的/mnt 下
sudo arch-chroot /mnt
echo "UUID=920290b2-8f5e-4222-96b5-ae911205eef7    /        ext4       rw,relatime   0 1" > /etc/fstab
# 设置 root 密码
passwd root
exit
sudo umount rawhd

启动 arch linux for rust 操作系统

必读:https://wiki.archlinuxcn.org/wiki/Arch_的启动流程

qemu-system-x86_64 -kernel arch/x86_64/boot/bzImage -initrd initramfs.img -m 1G -drive file=rawhd -nographic -append "root=/dev/sda console=ttyS0"

如果出现 ERROR: Root device mounted successfully, but /sbin/init does not exist.

把 -append “root=/dev/sda console=ttyS0” 改为 -append “root=/dev/sda init=/lib/systemd/systemd console=ttyS0”

运行 rust_helloworld 模块

dmesg -C
# 运行模块
insmod /rust_helloworld.ko
dmesg
# [   65.603974] rust_helloworld: Hello World from Rust module
# 卸载模块
rmmod rust_helloworld

最后

现在你应该知道Linux 本身并不是一个操作系统。它只是一个内核。操作系统的一部分。整个操作系统由内核、附带的 initramfs、根文件系统和社区组成。