51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

编译 linux for rust 并制作 initramfs 最后编写 rust_helloworld 内核驱动 并在 qemu 环境加载

本文使用 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、根文件系统和社区组成。


```


````


`````


``````


```````


````````


`````````


``````````


```````````


````````````


`````````````


``````````````


```````````````


````````````````

赞(0)
未经允许不得转载:工具盒子 » 编译 linux for rust 并制作 initramfs 最后编写 rust_helloworld 内核驱动 并在 qemu 环境加载