Compiling FreeBSD kernel module directly with Rust without invoking C and FreeBSD build system.

Compiling FreeBSD kernel module directly with Rust without invoking C and FreeBSD build system.

In the previous article, the Rust crates: Kernel Module Interface and Kernel Programming Interface were introduced and it was described how to use it. Also it was promised to find out the way to compile the project without invoking the FreeBSD build system. So, this is it, but with some drawbacks like it still requires to invoke the objcopy manually and separately.

The template for the module is located there freebsd-kmod-native-template.

Current stage of Cargo development allows to achieve this goal. To do so, the cargo should be instructed with the following: which linker should be called, which ABIs should be prohibited, what is the target and a linker script.

In the “x86_64-unknown-freebsd-kernel.json” the following changes were made:

  1. llvm-target should be generic x86_64. The goal of this project was just to successfully compile the module and the CPU target is x86. For ARM or RISC-V the llvm-target should be specified correspondently. However, the KMI and KPI crates (at the moment) does not support other CPU architectures.
  2. linker-flavor is LD and the path to it on the FreeBSD system. You can not crosscompile this project on Linux. You need either a FreeBSD guest running in the VM or some other container.
  3. post-link-args was taken from the build script. The linker script is taken directly from the kernel sources “/usr/src/sys/conf/ldscript.kmod.amd64” which should be available at the compile time.
  4. unsupported-abis are all ABIs available.
  5. executables flag should be true.

A “cargo build –release” should be invoked and a module ELF binaries will be generated at “$projectroot/target/x86_64-unknown-freebsd-kernel/release/”. This is a non stripped “ko” file.

The next step is to call a “post_build.sh” which is provided at the project root. This is a script which performs manipulations on the binary file which includes:


  1. Creates a directory “kmod” in the project root.
  2. Copies a binary to “kmod” dir.
  3. Invokes the awk-script (which is taken directly from FreeBSD sources) which extracts export_sums.
  4. Performs objcopy creating a project.ko.debug file.
  5. Performs objcopy creating a final, stripped copy of your kernel module.

The argument of the script is a name of the binary (usually a title of the project which is provided in crate). i.e "./post_build rust-kpi-test"

Unfortunately, cargo does not provide a post-build functionality, so you need to call everything manually and in two steps.

The “post_clean.sh” is a housekeeping helper which is followed after “cargo clean”. It removes the “kmod” directory.


要查看或添加评论,请登录

Aleksandr M.的更多文章

社区洞察

其他会员也浏览了