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
相关推荐
●^●1 分钟前
Linux 命令行与 vi/vim 编辑器完全指南
linux·编辑器·vim
哈哈幸运8 分钟前
Linux Awk 深度解析:10个生产级自动化与云原生场景
linux·云原生·自动化·awk·三剑客
Linux运维老纪15 分钟前
Linux之七大难命令(The Seven Difficult Commands of Linux)
linux·运维·服务器·云计算·运维开发
漫谈网络30 分钟前
Ollama工具调用(Tool Calls)业务应用案例
linux·ai·aigc·工具调用·ollama·tool calls
unique_落尘31 分钟前
java操作打印机直接打印及详细linux部署(只适用于机器和打印机处于同一个网段中)
java·linux·打印机
努力奋斗的小杨33 分钟前
学习MySQL的第十一天
数据库·笔记·sql·学习·mysql·navicat
景天科技苑1 小时前
【Rust结构体】Rust结构体详解:从基础到高级应用
开发语言·后端·rust·结构体·关联函数·rust结构体·结构体方法
苏近之1 小时前
说明白 Rust 中的泛型: 泛型是一种多态
设计模式·rust
weixin_457885821 小时前
Discuz!+DeepSeek:传统论坛的智能化蜕变之路
人工智能·学习·discuz·deepseek
SophiaSSSSS2 小时前
无标注文本的行业划分(行业分类)算法 —— 无监督或自监督学习
学习·算法·分类