rust_for_linux驱动完整版记录

文章目录

  • [[清华开源操作系统训练营]《Rust fox Linux》课程的练习1-2完整版记录。](#[清华开源操作系统训练营]《Rust fox Linux》课程的练习1-2完整版记录。)
    • [1. 环境搭建](#1. 环境搭建)
    • [2. 编译rust内核](#2. 编译rust内核)
      • [2.1 下载源代码](#2.1 下载源代码)
      • [2.2 安装rust支持](#2.2 安装rust支持)
      • [2.3 检查linux内核是否支持rust](#2.3 检查linux内核是否支持rust)
      • [2.4 编译linux内核](#2.4 编译linux内核)
    • [3. aarch64的qemu环境](#3. aarch64的qemu环境)
    • [4. 准备debian文件系统](#4. 准备debian文件系统)
      • [4.1 下载文件系统](#4.1 下载文件系统)
      • [4.2 解压缩](#4.2 解压缩)
      • [4.3 测试下载的内核和文件系统](#4.3 测试下载的内核和文件系统)
    • [5. 运行自己编译的内核](#5. 运行自己编译的内核)
      • [5.1 拷贝自己编译的内核](#5.1 拷贝自己编译的内核)
      • [5.2 运行自己编译的内核](#5.2 运行自己编译的内核)
    • [6. rust模块](#6. rust模块)
      • [6.1 编译linux中的rust用例](#6.1 编译linux中的rust用例)
      • [6.2 自己编写一个rust的helloworld驱动](#6.2 自己编写一个rust的helloworld驱动)

[清华开源操作系统训练营]《Rust fox Linux》课程的练习1-2完整版记录。

1. 环境搭建

我们基于Ubuntu22.04进行环境搭建,需要安装编译内核的包和LLVM等包:

c 复制代码
sudo apt-get -y install binutils build-essential libtool texinfo gzip zip unzip patchutils curl git make cmake ninja-build automake bison flex gperf grep sed gawk bc zlib1g-dev libexpat1-dev libmpc-dev libglib2.0-dev libfdt-dev libpixman-1-dev libelf-dev libssl-dev clang-format clang-tidy clang-tools clang clangd libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python3-clang llvm

2. 编译rust内核

2.1 下载源代码

c 复制代码
git clone https://github.com/Rust-for-Linux/linux -b rust-dev

我们使用Rust-for-Linux的rust-dev分支进行学习。

2.2 安装rust支持

c 复制代码
cd linux-rust
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

2.3 检查linux内核是否支持rust

c 复制代码
jian@jian:~/share/linux-rust$ make LLVM=1 rustavailable
Rust is available!

2.4 编译linux内核

首先生成配置文件.config

c 复制代码
make ARCH=arm64 LLVM=1 O=build defconfig

然后修改配置文件,把CONFIG_RUST设置为y

c 复制代码
make ARCH=arm64 LLVM=1 O=build menuconfig

最后编译内核

c 复制代码
cd build && make ARCH=arm64 LLVM=1 -j8

3. aarch64的qemu环境

3.1.下载源代码

c 复制代码
https://download.qemu.org/qemu-7.0.0.tar.xz

3.2. 解压编译安装

c 复制代码
tar -xf qemu-7.0.0.tar.xz
cd qemu-7.0.0
mkdir build-aarch64 && cd build-aarch64
../configure --target-list=aarch64-softmmu,aarch64-linux-user
make -j $(nproc)

3.3. 配置环境变量

在~/.bashrc文件中添加下面语句:

c 复制代码
export PATH=$PATH:/home/jian/share/qemu/qemu-7.0.0/build-aarch64
export PATH=$PATH:/home/jian/share/qemu/qemu-7.0.0/build-aarch64/aarch64-softmmu
export PATH=$PATH:/home/jian/share/qemu/qemu-7.0.0/build-aarch64/aarch64-linux-user

3.4.验证

新开一个控制台输入下面:

c 复制代码
jian@jian:~/share/qemu/qemu-7.0.0$ qemu-system-aarch64 --version
QEMU emulator version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
jian@jian:~/share/qemu/qemu-7.0.0$ qemu-aarch64 --version
qemu-aarch64 version 7.0.0
Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers
jian@jian:~/share/qemu/qemu-7.0.0$ 

4. 准备debian文件系统

4.1 下载文件系统

Debian官方网站上下载 Images for arm64-virt 版本的压缩包:

https://people.debian.org/\~gio/dqib/

4.2 解压缩

c 复制代码
unzip arm64-virt.zip

解压缩后可以看到下面的内容:

c 复制代码
jian@jian:~/share/arm64-virt$ tree
.
├── arm64-virt.zip
└── dqib_arm64-virt
    ├── Image
    ├── image.qcow2
    ├── initrd
    ├── kernel
    ├── mymake
    ├── readme.txt
    ├── ssh_user_ecdsa_key
    ├── ssh_user_ed25519_key
    └── ssh_user_rsa_key

1 directory, 10 files

4.3 测试下载的内核和文件系统

执行下面的命令可以尝试把整个的debian文件系统跑起来:

c 复制代码
qemu-system-aarch64 -machine 'virt' -cpu 'cortex-a57' -m 1G -device virtio-blk-device,drive=hd -drive file=image.qcow2,if=none,id=hd -device virtio-net-device,netdev=net -netdev user,id=net,hostfwd=tcp::2222-:22 -kernel kernel -initrd initrd -nographic -append "root=LABEL=rootfs console=ttyAMA0"

5. 运行自己编译的内核

5.1 拷贝自己编译的内核

c 复制代码
cp ~/share/linux-rust/build/arch/arm64/boot/Image /home/jian/share/arm64-virt/dqib_arm64-virt

5.2 运行自己编译的内核

c 复制代码
qemu-system-aarch64 -machine 'virt' -cpu 'cortex-a57' -m 1G -device virtio-blk-device,drive=hd -drive file=image.qcow2,if=none,id=hd -device virtio-net-device,netdev=net -netdev user,id=net,hostfwd=tcp::2222-:22 -kernel Image -initrd initrd -nographic -append "root=LABEL=rootfs console=ttyAMA0"

6. rust模块

6.1 编译linux中的rust用例

c 复制代码
make ARCH=arm64 LLVM=1 O=build menuconfig
cd build && make ARCH=arm64 LLVM=1 -j8

把CONFIG_SAMPLE_RUST_PRINT和CONFIG_SAMPLE_RUST_MINIMAL选上。然后在编译。

可以看到下面的输出:

c 复制代码
[    2.836088] rust_minimal: Rust minimal sample (init)
[    2.836386] rust_minimal: Am I built-in? true
[    2.837094] rust_print: Rust printing macros sample (init)
[    2.837225] rust_print: Emergency message (level 0) without args
[    2.837379] rust_print: Alert message (level 1) without args
[    2.837610] rust_print: Critical message (level 2) without args
[    2.837805] rust_print: Error message (level 3) without args
[    2.838325] rust_print: Warning message (level 4) without args
[    2.838456] rust_print: Notice message (level 5) without args
[    2.838579] rust_print: Info message (level 6) without args
[    2.838712] rust_print: A line that is continued without args
[    2.839166] rust_print: Emergency message (level 0) with args
[    2.839481] rust_print: Alert message (level 1) with args
[    2.839803] rust_print: Critical message (level 2) with args
[    2.840127] rust_print: Error message (level 3) with args
[    2.840456] rust_print: Warning message (level 4) with args
[    2.840587] rust_print: Notice message (level 5) with args
[    2.841027] rust_print: Info message (level 6) with args
[    2.841338] rust_print: A line that is continued with args
[    2.841794] rust_print: 1
[    2.842115] rust_print: "hello, world"
[    2.842667] rust_print: [../samples/rust/rust_print.rs:34] c = "hello, world"

6.2 自己编写一个rust的helloworld驱动

线进入samples/rust目录,编写一个rust的驱动rust_hello.rs:

c 复制代码
// 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(_name: &'static CStr, _module: &'static ThisModule) -> Result<Self> {
	fn init(_module: &'static ThisModule) -> Result<Self> {
      pr_info!("Hello World from Rust module");
      Ok(RustHelloWorld {})
  }
}

然后在Makefile文件中添加:

c 复制代码
obj-y        += rust_hello.o

最后再次编译和运行,可以看到下面的输出:

c 复制代码
[    2.843635] rust_helloworld: Hello World from Rust module
相关推荐
adore.9683 分钟前
3.11 复试学习
学习
自传丶5 分钟前
【学习笔记】大模型应用开发系列(二)Embedding 模型
笔记·学习·embedding
AryShaw20 分钟前
macOS 上搭建 RK3568 交叉编译环境
linux·macos
芒果披萨37 分钟前
Linux文件类基础命令行1
linux·运维·服务器
学嵌入式的小杨同学42 分钟前
STM32 进阶封神之路(八):外部中断 EXTI 实战 —— 按键检测从轮询到中断(库函数 + 寄存器双版本)
linux·stm32·单片机·嵌入式硬件·mcu·架构·硬件架构
杨云龙UP2 小时前
ODA服务器RAC节点2/u01分区在线扩容操作记录及后续处理流程(Linux LVM + ext4 文件系统在线扩容操作手册)_20260307
linux·运维·服务器·数据库·ubuntu·centos
爱写代码的小朋友4 小时前
人工智能驱动下个性化学习路径的构建与实践研究——以K12数学学科为例
人工智能·学习
不灭锦鲤10 小时前
网络安全学习第48天
学习
jyfool10 小时前
Ubuntu 远程桌面配置踩坑实录:从 TightVNC 到 x11vnc 的折腾之旅
linux·运维·ubuntu
安当加密10 小时前
基于 RADIUS 的 Linux 服务器双因子认证:从 FreeRADIUS 到轻量级 ASP 方案的演进
linux·运维·服务器