本文使用 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 {#编译-linux-for-rust}
源码与 rust 环境 {#源码与-rust-环境}
*
01
*
02
*
03
*
04
*
05
*
06
*
07
*
08
*
09
# 下载源码
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
</code>
</pre>
如果 make LLVM=1 rustavailable 提示 Rust is available! 就ok了。
### 内核设置 {#内核设置}
````````````````prism language-bash
# 创建默认配置
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
# ^ 按空格开启 即 [*]
</code>
</pre>
>
>
> * ` make menuconfig ` : 老的 ncurses 界面,被 ` nconfig ` 取代
>
>
> * ` make nconfig ` : 新的命令行 ncurses 界面
>
>
> * ` make xconfig ` : 用户友好的图形界面,需要安装 https://archlinux.org/packages/?name=packagekit-qt5 包。建议没有经验的用户使用此方法。
>
>
> * ` make gconfig ` : 和 xconfig 类似的图形界面,使用 gtk.
>
>
>
### 制作 rust hello world 模块 {#制作-rust-hello-world-模块}
#### 源码 {#源码}
```````````````prism language-bash
vim samples/rust/rust_helloworld.rs
</code>
</pre>
填入以下内容
``````````````prism language-rust
// 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 {})
}
}
</code>
</pre>
#### 配置 {#配置}
`````````````prism language-bash
vim samples/rust/Kconfig
</code>
</pre>
添加以下内容
> 要在 if SAMPLES_RUST 和 endif # SAMPLES_RUST 之间添加
>
>
````````````prism language-makefile
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.
</code>
</pre>
```prism language-bash
vim samples/rust/Makefile
```
添加以下内容
```````````prism language-makefile
obj-$(CONFIG_SAMPLE_RUST_HELLOWORLD) += rust_helloworld.o
</code>
</pre>
#### 修改 .config 开启 rust hello world {#修改-.config-开启-rust-hello-world}
``````````prism language-bash
make ARCH=x86_64 LLVM=1 O=build nconfig
</code>
</pre>
> Kernel hacking
> ---\> Sample Kernel code
> ---\> Rust samples
> ---\> Print Helloworld in Rust (NEW)
>
>
`````````prism language-bash
# 检查
cat build/.config | grep SAMPLE_RUST_HELLOWORLD
cat build/.config | grep SAMPLES_RUST
# CONFIG_SAMPLE_RUST_HELLOWORLD=m
# CONFIG_SAMPLES_RUST=y
</code>
</pre>
### 构建内核 {#构建内核}
````````prism language-bash
# 构建内核
cd build
make ARCH=x86_64 LLVM=1 -j12
# Kernel: arch/x86/boot/bzImage is ready (#3)
</code>
</pre>
### 构建 initramfs.img {#构建-initramfs.img}
> 建议查看: https://wiki.archlinuxcn.org/wiki/Mkinitcpio#%E5%B8%B8%E7%94%A8%E9%92%A9%E5%AD%90
>
>
```````prism language-bash
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
</code>
</pre>
内核和 initramfs 已经完成,但我们需要一个硬盘来运行一切
### 创建 raw 并安装 archlinux {#创建-raw-并安装-archlinux}
``````prism language-bash
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
</code>
</pre>
> $ genfstab -U /mnt
> # /dev/loop0
> UUID=920290b2-8f5e-4222-96b5-ae911205eef7 / ext4 rw,relatime 0 1
>
>
> /swapfile none swap defaults 0 0
>
>
`````prism language-bash
# 把环境切换到新系统的/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
</code>
</pre>
### 启动 arch linux for rust 操作系统 {#启动-arch-linux-for-rust-操作系统}
> 必读: https://wiki.archlinuxcn.org/wiki/Arch_%E7%9A%84%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B
>
>
````prism language-bash
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"
</code>
</pre>
> 如果出现 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 模块 {#运行-rust_helloworld-模块}
```prism language-bash
dmesg -C
# 运行模块
insmod /rust_helloworld.ko
dmesg
# [ 65.603974] rust_helloworld: Hello World from Rust module
# 卸载模块
rmmod rust_helloworld
</code>
</pre>
最后 {#最后}
--------
现在你应该知道Linux 本身并不是 一个 操作系统。它只是一个内核。操作系统的一部分。整个操作系统由内核、附带的 initramfs、根文件系统和社区组成。
```
````
`````
``````
```````
````````
`````````
``````````
```````````
````````````
`````````````
``````````````
```````````````
````````````````