编译rust for linux内核源码(5.16.0-rc3)
本文针对rust for linux内核源码进行编译,跟主线版本的linux编译稍有不同,因为引入了rust,编译rust需要安装相关工具,以下部分会详细介绍如何编译rust for linux。
目录
①、General setup->Rust support 启用
②、Kernel hacking->Sample kernel code->Rust sample 启用
③、Kernel hacking->Compile-time checks and compiler options->Compile the kernel with debug info 禁用
编译linux内核源码,我在这篇文章中有详细介绍。本文针对rust for linux内核源码进行编译,跟主线版本的linux编译稍有不同,因为引入了rust,编译rust需要安装相关工具,以下部分会详细介绍如何编译rust for linux。
本文编译环境为Fedora server 35 x86_64:
[root@fedora-yg ~]# uname -a
Linux fedora-yg 5.14.10-300.fc35.x86_64 #1 SMP Thu Oct 7 20:48:44 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
[root@fedora-yg ~]#
[root@fedora-yg ~]# cat /etc/os-release |head -4
NAME="Fedora Linux"
VERSION="35 (Server Edition)"
ID=fedora
VERSION_ID=35
[root@fedora-yg ~]#
[root@fedora-yg ~]# cat /etc/fedora-release
Fedora release 35 (Thirty Five)
[root@fedora-yg ~]#
[root@fedora-yg ~]# cat /proc/version
Linux version 5.14.10-300.fc35.x86_64 (mockbuild@bkernel01.iad2.fedoraproject.org) (gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1), GNU ld version 2.37-10.fc35) #1 SMP Thu Oct 7 20:48:44 UTC 2021
[root@fedora-yg ~]#
一、获取rust-for-linux内核源码
可以直接使用git clone官网https://github.com/Rust-for-Linux/linux,由于git clone比较慢,我是下载zip包,然后解压到本地:
注:我这里用的commit是:
675846f923385f32310b61f0409581d89806273d
可以拉取最新版的内核源码即可。
二、编译构建内核源码环境部署
1、基本开发环境套件安装
[root@fedora-yg linux-rust]# dnf group install "Development Tools"
2、额外要安装的软件包
[root@fedora-yg linux-rust]# dnf install ncurses-devel zstd bison flex elfutils-libelf-devel openssl-devel
3、安装llvm/clang套件
rust代码编译依赖llvm/clang套件,故还需要安装llvm/clang套件
[root@fedora-yg linux-rust]# dnf install llvm clang lld
注:编译rust for linux内核源码需要llvm/clang版本在10.0.1及以上版本;编译内核时需要加CC=clang或者LLVM=1.
4、安装rustup
①、安装rustup比较简单,直接执行如下命令
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
[root@fedora-yg linux-rust]# curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
info: downloading installer
Welcome to Rust!
This will download and install the official compiler for the Rust
programming language, and its package manager, Cargo.
Rustup metadata and toolchains will be installed into the Rustup
home directory, located at:
/root/.rustup
This can be modified with the RUSTUP_HOME environment variable.
The Cargo home directory located at:
/root/.cargo
This can be modified with the CARGO_HOME environment variable.
The cargo, rustc, rustup and other commands will be added to
Cargo's bin directory, located at:
/root/.cargo/bin
This path will then be added to your PATH environment variable by
modifying the profile files located at:
/root/.profile
/root/.bash_profile
/root/.bashrc
You can uninstall at any time with rustup self uninstall and
these changes will be reverted.
Current installation options:
default host triple: x86_64-unknown-linux-gnu
default toolchain: stable (default)
profile: default
modify PATH variable: yes
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>
info: profile set to 'default'
info: default host triple is x86_64-unknown-linux-gnu
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
686.2 KiB / 686.2 KiB (100 %) 127.9 KiB/s in 7s ETA: 0s
info: latest update on 2021-12-02, rust version 1.57.0 (f1edd0429 2021-11-29)
info: downloading component 'cargo'
6.3 MiB / 6.3 MiB (100 %) 72.1 KiB/s in 1m 17s ETA: 0s
.
.
.
stable-x86_64-unknown-linux-gnu installed - rustc 1.57.0 (f1edd0429 2021-11-29)
Rust is installed now. Great!
To get started you may need to restart your current shell.
This would reload your PATH environment variable to include
Cargo's bin directory ($HOME/.cargo/bin).
To configure your current shell, run:
source $HOME/.cargo/env
[root@fedora-yg linux-rust]#
②、配置rustup环境变量生效
[root@fedora-yg linux-rust]# source /root/.cargo/env
[root@fedora-yg linux-rust]#
③、安装指定版本rustc,目前为1.57.0
注:rustup override set 1.57.0命令要在内核源码根目录执行
[root@fedora-yg linux-rust]# rustup override set 1.57.0
info: syncing channel updates for '1.57.0-x86_64-unknown-linux-gnu'
686.2 KiB / 686.2 KiB (100 %) 223.7 KiB/s in 3s ETA: 0s
info: latest update on 2021-12-02, rust version 1.57.0 (f1edd0429 2021-11-29)
info: downloading component 'cargo'
.
.
.
info: installing component 'rust-std'
24.9 MiB / 24.9 MiB (100 %) 11.2 MiB/s in 2s ETA: 0s
info: installing component 'rustc'
53.9 MiB / 53.9 MiB (100 %) 13.1 MiB/s in 4s ETA: 0s
info: installing component 'rustfmt'
info: override toolchain for '/home/linux-rust' set to '1.57.0-x86_64-unknown-linux-gnu'
1.57.0-x86_64-unknown-linux-gnu installed - rustc 1.57.0 (f1edd0429 2021-11-29)
[root@fedora-yg linux-rust]#
④、下载rust标准库代码
[root@fedora-yg linux-rust]# rustup component add rust-src
info: downloading component 'rust-src'
info: installing component 'rust-src'
[root@fedora-yg linux-rust]#
⑤、安装bindgen
需要安装指定版本的bindgen包,目前为0.56:
[root@fedora-yg linux-rust]# cargo install --locked --version 0.56.0 bindgen
Updating crates.io index
Downloaded bindgen v0.56.0
Downloaded 1 crate (198.3 KB) in 3.09s
Installing bindgen v0.56.0
Downloaded glob v0.3.0
...
...
...
Compiling regex v1.4.2
Compiling clap v2.33.3
Compiling cexpr v0.4.0
Compiling env_logger v0.8.1
Finished release [optimized] target(s) in 4m 21s
Installing /root/.cargo/bin/bindgen
Installed package `bindgen v0.56.0` (executable `bindgen`)
[root@fedora-yg linux-rust]#
5、磁盘容量检查及扩容
执行df -h查看要编译的内核源码所在分区剩余磁盘容量,如果大于10G的话,此步骤可以跳过。
安装Fedora server 35的时候,如果你没有手动修改磁盘配置,则默认只分配15G给/根目录,剩余可用就6.8GB了,这个容量编译内核是不够的,make执行半天会给你报个no space left on disk错误,然后终止编译,所以还是需要先扩容根目录(源码所在磁盘分区)。
[root@fedora ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 777M 1.5M 776M 1% /run
/dev/mapper/fedora_fedora-root 15G 8.3G 6.8G 55% /
tmpfs 1.9G 4.0K 1.9G 1% /tmp
/dev/sda1 1014M 196M 819M 20% /boot
tmpfs 389M 0 389M 0% /run/user/0
[root@fedora ~]#
可以看到根目录只有15G,但是我创建虚拟机的时候是配置了60G的:
[root@fedora ~]# fdisk -l
Disk /dev/sda:60 GiB,64424509440 字节,125829120 个扇区
磁盘型号:VMware Virtual S
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
磁盘标签类型:dos
磁盘标识符:0x70b5f1da
设备 启动 起点 末尾 扇区 大小 Id 类型
/dev/sda1 * 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 125829119 123729920 59G 8e Linux LVM
Disk /dev/mapper/fedora_fedora-root:15 GiB,16106127360 字节,31457280 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 512 字节
I/O 大小(最小/最佳):512 字节 / 512 字节
Disk /dev/zram0:3.79 GiB,4070572032 字节,993792 个扇区
单元:扇区 / 1 * 4096 = 4096 字节
扇区大小(逻辑/物理):4096 字节 / 4096 字节
I/O 大小(最小/最佳):4096 字节 / 4096 字节
[root@fedora ~]#
可以看出/dev/sda2有59G,但是只给/分配了15G。
因为是lvm管理方式,我们可以先vgdisplay -v查看下:
[root@fedora ~]# vgdisplay -v
--- Volume group ---
VG Name fedora_fedora
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 2
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 1
Max PV 0
Cur PV 1
Act PV 1
VG Size <59.00 GiB
PE Size 4.00 MiB
Total PE 15103
Alloc PE / Size 3840 / 15.00 GiB
Free PE / Size 11263 / <44.00 GiB
VG UUID ps339S-G9Qu-pL0E-kQrH-iwL4-sSML-7pZrcD
--- Logical volume ---
LV Path /dev/fedora_fedora/root
LV Name root
VG Name fedora_fedora
LV UUID 93KIqS-Wfji-N97j-ISe0-6j3y-mXRS-vT33fc
LV Write Access read/write
LV Creation host, time fedora, 2021-12-05 19:11:56 +0800
LV Status available
# open 1
LV Size 15.00 GiB
Current LE 3840
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 256
Block device 253:0
--- Physical volumes ---
PV Name /dev/sda2
PV UUID XPmIl8-V0WJ-Vp8i-5cOS-mdD0-VDaQ-RDzXLY
PV Status allocatable
Total PE / Free PE 15103 / 11263
[root@fedora ~]#
可以看到卷组fedora_fedora只分配出去15G,空闲约44.00 GiB,可以直接执行lvextent扩容,下面是给/dev/fedora_fedora/root增加40G:
[root@fedora ~]# lvextend -L +40G /dev/fedora_fedora/root
Size of logical volume fedora_fedora/root changed from 15.00 GiB (3840 extents) to 55.00 GiB (14080 extents).
Logical volume fedora_fedora/root successfully resized.
[root@fedora ~]#
之后需要执行resize2fs或者xfs_growfs使修改生效,因为我这里扩容的/dev/fedora_fedora/root是xfs文件系统类型,所以执行xfs_growfs命令:
[root@fedora ~]# xfs_growfs /dev/fedora_fedora/root
meta-data=/dev/mapper/fedora_fedora-root isize=512 agcount=4, agsize=983040 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=0
= reflink=1 bigtime=0 inobtcount=0
data = bsize=4096 blocks=3932160, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
data blocks changed from 3932160 to 14417920
[root@fedora ~]#
此时,再查看下根目录容量,已经生效:
[root@fedora ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 777M 1.5M 776M 1% /run
/dev/mapper/fedora_fedora-root 55G 8.5G 47G 16% /
tmpfs 1.9G 4.0K 1.9G 1% /tmp
/dev/sda1 1014M 196M 819M 20% /boot
tmpfs 389M 0 389M 0% /run/user/0
[root@fedora ~]#
三、配置启用支持rust的内核参数
1、复用本机config文件
[root@fedora-yg linux-rust]# cp -v /boot/config-5.14.10-300.fc35.x86_64 .config
'/boot/config-5.14.10-300.fc35.x86_64' -> '.config'
[root@fedora-yg linux-rust]#
2、执行make menuconfig启用rust支持
①、General setup->Rust support 启用
②、Kernel hacking->Sample kernel code->Rust sample 启用
③、Kernel hacking->Compile-time checks and compiler options->Compile the kernel with debug info 禁用
这个选项是要禁用掉的,具体原因我在这篇文章解释过。
④、退出并保存配置
四、编译rust-for-linux内核源码
编译之前,先贴下我机器的编译工具版本:
下面开始编译,我虚拟机配了4核cpu,这里加-j4加速编译:
[root@fedora-yg linux-rust]# make LLVM=1 -j4
上面几个选项可以随便选,接下来就是漫长的等待了(看机器性能了,可能需要数十分钟到数小时)。
注:如果编译过程出现报错,最简单的方法就是全部清理下,重新配置内核参数重新编译(从头来过)。
比如我就遇到下面这个报错:
HDRINST usr/include/linux/hash_info.h
make[1]: *** No rule to make target '/root/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/lib.rs', needed by 'rust/core.o'. Stop.
make: *** [Makefile:1271: prepare0] Error 2
make: *** Waiting for unfinished jobs....
HDRINST usr/include/linux/hdlc.h
HDRINST usr/include/linux/hdlc/ioctl.h
重新清理配置后编译就好了:
[root@fedora-yg linux-rust]# make mrproper
CLEAN arch/x86/tools
CLEAN usr/include
CLEAN scripts/basic
CLEAN scripts/kconfig
CLEAN scripts/mod
CLEAN scripts/selinux/genheaders
CLEAN scripts/selinux/mdp
CLEAN scripts
CLEAN include/config include/generated arch/x86/include/generated .config .config.old
[root@fedora-yg linux-rust]#
[root@fedora-yg linux-rust]# make clean
[root@fedora-yg linux-rust]#
[root@fedora-yg linux-rust]# cp -v /boot/config-5.14.10-300.fc35.x86_64 .config
'/boot/config-5.14.10-300.fc35.x86_64' -> '.config'
[root@fedora-yg linux-rust]#
[root@fedora-yg linux-rust]# make menuconfig
HOSTCC scripts/basic/fixdep
UPD scripts/kconfig/mconf-cfg
HOSTCC scripts/kconfig/mconf.o
HOSTCC scripts/kconfig/lxdialog/checklist.o
HOSTCC scripts/kconfig/lxdialog/inputbox.o
HOSTCC scripts/kconfig/lxdialog/menubox.o
HOSTCC scripts/kconfig/lxdialog/textbox.o
HOSTCC scripts/kconfig/lxdialog/util.o
HOSTCC scripts/kconfig/lxdialog/yesno.o
HOSTCC scripts/kconfig/confdata.o
HOSTCC scripts/kconfig/expr.o
LEX scripts/kconfig/lexer.lex.c
YACC scripts/kconfig/parser.tab.[ch]
HOSTCC scripts/kconfig/lexer.lex.o
HOSTCC scripts/kconfig/menu.o
HOSTCC scripts/kconfig/parser.tab.o
HOSTCC scripts/kconfig/preprocess.o
HOSTCC scripts/kconfig/symbol.o
HOSTCC scripts/kconfig/util.o
HOSTLD scripts/kconfig/mconf
x x -*- Include all symbols in kallsyms x x
x x [*] Enable userfaultfd() system call x x
x x [ ] Embedded system x x
x x Kernel Performance Events And Counters ---> x x
x x [ ] Disable heap randomization x x
x x Choose SLAB allocator (SLUB (Unqueued Allocator)) ---> x x
x x [ ] Allow slab caches to be merged x x
x x [*] Randomize slab freelist x x
x x [*] Harden slab freelist metadata x x
x x [*] Page allocator randomization x x
x x [*] SLUB per cpu partial cache x x
x x [*] Profiling support x x
configuration written to .config
*** End of the configuration.
*** Execute 'make' to start the build or try 'make help'.
[root@fedora-yg linux-rust]#
[root@fedora-yg linux-rust]#
[root@fedora-yg linux-rust]#
[root@fedora-yg linux-rust]#
[root@fedora-yg linux-rust]# make LLVM=1 -j4
HOSTCC scripts/basic/fixdep
UPD scripts/kconfig/mconf-cfg
HOSTCC scripts/kconfig/mconf.o
HOSTCC scripts/kconfig/lxdialog/checklist.o
漫长等待后,make执行完:
LD [M] sound/synth/emux/snd-emux-synth.ko
LD [M] sound/synth/snd-util-mem.ko
LD [M] sound/usb/6fire/snd-usb-6fire.ko
LD [M] sound/usb/bcd2000/snd-bcd2000.ko
LD [M] sound/usb/caiaq/snd-usb-caiaq.ko
LD [M] sound/usb/hiface/snd-usb-hiface.ko
LD [M] sound/usb/line6/snd-usb-line6.ko
LD [M] sound/usb/line6/snd-usb-pod.ko
LD [M] sound/usb/line6/snd-usb-podhd.ko
LD [M] sound/usb/line6/snd-usb-toneport.ko
LD [M] sound/usb/line6/snd-usb-variax.ko
LD [M] sound/usb/misc/snd-ua101.ko
LD [M] sound/usb/snd-usb-audio.ko
LD [M] sound/usb/snd-usbmidi-lib.ko
LD [M] sound/usb/usx2y/snd-usb-us122l.ko
LD [M] sound/usb/usx2y/snd-usb-usx2y.ko
LD [M] sound/virtio/virtio_snd.ko
LD [M] sound/x86/snd-hdmi-lpe-audio.ko
LD [M] sound/xen/snd_xen_front.ko
LD [M] virt/lib/irqbypass.ko
[root@fedora-yg linux-rust]#
五、编译生成内核压缩镜像
make成功后,此时,先检查下在arch/x86/boot/下有没有生成bzImage, 如果在arch/x86/boot/下没有生成bzImage的话,后面在make install会报错:
[root@fedora-yg linux-rust]# make install
sh ./arch/x86/boot/install.sh 5.16.0-rc3 \
arch/x86/boot/bzImage System.map "/boot"
*** Missing file: arch/x86/boot/bzImage
*** You need to run "make" before "make install".
make: *** [arch/x86/Makefile:262: install] Error 1
[root@fedora-yg linux-rust]#
ls查看arch/x86/boot/bzImage文件并没有生成:
[root@fedora-yg linux-rust]# ls arch/x86/boot/bzImage
ls: cannot access 'arch/x86/boot/bzImage': No such file or directory
[root@fedora-yg linux-rust]#
此时还需执行命令生成内核压缩镜像:
[root@fedora-yg linux-rust]# make LLVM=1 bzImage
因为我之前没有安装zstd,然后这步出错了:
安装之后,重新make LLVM=1 bzImage:
可以看到bzImage已经生成。
六、编译安装新生成的内核模块(驱动)
执行如下命令:
[root@fedora-yg linux-rust]# make modules_install
输出如下:
[root@fedora-yg linux-rust]# make modules_install
INSTALL /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/aegis128-aesni.ko
SIGN /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/aegis128-aesni.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/blake2s-x86_64.ko
SIGN /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/blake2s-x86_64.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/blowfish-x86_64.ko
SIGN /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/blowfish-x86_64.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/camellia-aesni-avx-x86_64.ko
SIGN /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/camellia-aesni-avx-x86_64.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/camellia-aesni-avx2.ko
SIGN /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/camellia-aesni-avx2.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/camellia-x86_64.ko
SIGN /lib/modules/5.16.0-rc3/kernel/arch/x86/crypto/camellia-x86_64.ko
.
.
.
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/usb/line6/snd-usb-variax.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/usb/line6/snd-usb-variax.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/usb/misc/snd-ua101.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/usb/misc/snd-ua101.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/usb/snd-usb-audio.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/usb/snd-usb-audio.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/usb/snd-usbmidi-lib.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/usb/snd-usbmidi-lib.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/usb/usx2y/snd-usb-us122l.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/usb/usx2y/snd-usb-us122l.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/usb/usx2y/snd-usb-usx2y.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/usb/usx2y/snd-usb-usx2y.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/virtio/virtio_snd.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/virtio/virtio_snd.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/x86/snd-hdmi-lpe-audio.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/x86/snd-hdmi-lpe-audio.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/sound/xen/snd_xen_front.ko
SIGN /lib/modules/5.16.0-rc3/kernel/sound/xen/snd_xen_front.ko
INSTALL /lib/modules/5.16.0-rc3/kernel/virt/lib/irqbypass.ko
SIGN /lib/modules/5.16.0-rc3/kernel/virt/lib/irqbypass.ko
DEPMOD /lib/modules/5.16.0-rc3
[root@fedora-yg linux-rust]#
七、编译安装新内核
执行如下命令:
[root@fedora-yg linux-rust]# make install
sh ./arch/x86/boot/install.sh 5.16.0-rc3 \
arch/x86/boot/bzImage System.map "/boot"
[root@fedora-yg linux-rust]#
此时可以看到/boot下面已经有了我们新编译的5.16.0-rc3内核版本相关的文件了:
八、修改内核引导项
Fedora及其衍生系统RHEL/CentOS/Oracle linux等上可以使用grub2-mkconfig(旧版本系统可以使用grub-mkconfig)命令来更新内核引导项:
修改后使用grubby命令查看修改效果。
九、 重启系统生效
[root@fedora-yg ~]# reboot
可以看到,前面新编译生成的内核已经在默认启动项了,进去系统后,执行uname -a看下内核版本:
[root@fedora-yg ~]# uname -a
Linux fedora 5.16.0-rc3 #3 SMP PREEMPT Tue Dec 9 10:35:32 CST 2021 x86_64 x86_64 x86_64 GNU/Linux
[root@fedora-yg ~]#
到此,大功告成,接下来我们可以在此系统上使用rust编写内核模块了。
更多推荐
所有评论(0)