æŠèŠ
æ¬èšäºã§ã¯ãRust ã§æžãã Linux kernel module ããã«ãããŠåããããã®ç°å¢ãæ§ç¯ããŸãã ãŽãŒã«ã¯ã以äžã® Rust module ã miscdrv.ko ãšããŠãã«ãããŠãVM äžã§ insmod ãããšãããŸã§ã§ãã
use kernel::prelude::*;
module! {
type: MiscDrv,
name: "miscdrv",
authors: ["ymgyt"],
description: "Rust misc device lab",
license: "GPL",
}
struct MiscDrv;
impl kernel::Module for MiscDrv {
fn init(_module: &'static ThisModule) -> Result<Self> {
pr_info!("loaded\n");
Ok(Self)
}
}
impl Drop for MiscDrv {
fn drop(&mut self) {
pr_info!("unloaded\n");
}
}æçµçã«ã¯ãVM äžã§ä»¥äžã®ããã« module ã load/unload ã§ããããã«ãªããŸãã
root@localhost:~# insmod /mnt/drivers/miscdrv.ko
[ 5930.423638] miscdrv: loaded
root@localhost:~# rmmod miscdrv
[ 5982.685953] miscdrv: unloadedãã«ã㯠host ã§è¡ããå®è¡ã¯ VM äžã§è¡ããŸãã VM 㯠KVM/QEMU ã§åãããlibvirt ã§ç®¡çããŸããKVM/QEMU/libvirt ã«ã€ããŠã¯åæã®ç¢ºèªã®ç¯ã§ç°¡åã«è§ŠããŸããããã詳ãã㯠Mastering KVM Virtualization ããªã¹ã¹ã¡ã§ãã
kernel module ãäœãã®ãåããŠã®æ¹ãæ³å®ããŠããŸãã
æ¬èšäºã®ã³ãŒãã¯ãã¹ãŠ ymgyt/drivers repo ã§ç¢ºèªã§ããŸããqemu ã rustc ãšãã£ãäŸåã¯ãã¹ãŠ Nix ã§å®£èšããŠãããéçºç°å¢ã®ç¯ã§æºåããŸãã
åæã®ç¢ºèª
Kernel module ãšã¯
kernel module ãšã¯ãå®è¡äžã® kernel ã«å®è¡ã³ãŒããåçã«è¿œå ããä»çµã¿ã§ãã kernel ã®ãã«ãã·ã¹ãã (Makefile)ã« module ãäœæããããã®ã¬ã·ã(target)ãçšæãããŠããŸãã æ¬èšäºã§ã¯ãmiscdrv.rs ãã miscdrv.ko ãçæããŸãã .ko ã®å®äœã¯ ELF Relocatable file(ET_REL)ã§ãã
⯠readelf --file-header miscdrv.ko | rg Type:
Type: REL (Relocatable file)[f]init_module() ãšãã module ã load ããããã® system call ããããinsmod ãæçµçã« finit_module() ãåŒãã§ããŸãã
kernel module 㯠kernel ãšåãã¢ãã¬ã¹ç©ºéã»åãç¹æš©ã¬ãã«ã§åäœããŸãã module ãã㯠kernel æ¬äœã EXPORT_SYMBOL[_GPL] ãã颿°ãåŒã¶ããšãã§ããŸãã
ãããã®ããã°å
éš API ã«ã¯ãmemory å²åœåŠç(kmalloc())ãåçš® subsystem ãžã®ç»é²åŠç(misc_register() ãªã©)ãå«ãŸããŠããŸãã ãã ããäºææ§ã«ã€ããŠã¯ãuserspace(system callãABI)ãšã¯ç°ãªããäžåä¿èšŒãããŸãã(stable-api-nonsense)ã ãããã£ãŠããã«ãæã«æ³å®ããŠãã foo() ã load æã® kernel ã«åã signature ã§ååšããä¿èšŒã¯ãããŸããã
ãã®ããããã«ãæã«åç
§ããŠãã颿°(symbol)ã®ã¡ã¿ããŒã¿(CRC)ã .ko ã«åã蟌ãã§ãããload æã«æ€èšŒããä»çµã¿ããããŸãã ãã®ã¡ã¿ããŒã¿ãåã蟌ãããã«ãmodule ã®ãã«ãåã« kernel image ããã«ãããModule.symvers file ãçæããŠããå¿
èŠããããŸãã
以äžã®ããã«ãå®éã« module ã«åã蟌ãŸããŠãã printk ã® CRC 0xca2eebaa ã¯ããã«ãæã«åç
§ãã kernel ã® Module.symvers ã®å€ãšäžèŽããŠããŸããã
⯠modprobe --show-modversions handson/miscdrv/module/miscdrv.ko
0xca2eebaa _RNvNtCse297zByDW5v_6kernel5print11call_printk
0xd272d446 __x86_return_thunk
0x7406cc83 module_layout
⯠rg _RNvNtCse297zByDW5v_6kernel5print11call_printk .build/rust-next/Module.symvers
4821:0xca2eebaa _RNvNtCse297zByDW5v_6kernel5print11call_printk vmlinux EXPORT_SYMBOL_GPLmodprobe ã® src ãã¿ããšãELF ã® __versions section ãããããã®æ
å ±ãååŸããŠããããšãããããŸãã
以äžãããkernel module ããã«ãããã«ã¯ãload å
ãšãªã kernel ãå
ã«ãã«ãã㊠Module.symvers ãçæããŠããå¿
èŠããããŸãã
Kernel config ãšã¯
次㫠kernel ããã«ãããéã®èšå®æ¹æ³ã«ã€ããŠã§ãã kernel ã®ãœãŒã¹ã³ãŒãã«ã¯ä»¥äžã®ããã« CONFIG_XXX ã«ãã conditional compile ããããŸãã
struct task_struct {
/* ... */
#ifdef CONFIG_MEM_ALLOC_PROFILING
struct alloc_tag *alloc_tag;
#endif
/* ... */Rust ã§ã¯ #[cfg()] ã䜿ãããŸãã 以äžã¯æŠèŠã«èŒãã module! ãã¯ãã®å±éçµæã®äžéš(rust/macros/module.rs ãçæããã³ãŒã)ã§ãMODULE ã¯ãmodule ãšããŠãã«ããããŠããããã衚ã cfg ã§ãã
#[cfg(MODULE)]
static THIS_MODULE: ::kernel::ThisModule = unsafe {
extern "C" {
static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
};
::kernel::ThisModule::from_ptr(__this_module.get())
};
#[cfg(not(MODULE))]
static THIS_MODULE: ::kernel::ThisModule = unsafe {
::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
};åããœãŒã¹ã³ãŒãããmodule ãšããŠãã«ããããå Žå㯠kernel ã load æã«çšæãã __this_module ãåç
§ããkernel æ¬äœã«çµã¿èŸŒãŸããå Žå(built-in)㯠null ã䜿ãããšããããã«åå²ããŠããŸãã
kernel ããã«ãããéã«ã¯ãæçµçã«ã¯å
šãŠã®èšå®ã解決ãã .config ãçšæããŸãã .config ã®é
ç®ã¯ on/off ã ãã§ã¯ãªããå€ãã®æ©èœã y/m/n ã® 3 å€(tristate)ããšããŸãã
y: kernel image ã«çµã¿èŸŒã(built-in)m: module(.ko)ãšããŠãã«ãããå®è¡æã« load ããn: ãã«ãããªã
äŸãã° virtio ã® block driver ã¯ãDebian ã® config ã§ã¯ module ã§ãããæ¬èšäºã§æçµçã«äœ¿ã config ã§ã¯ kernel ã«çµã¿èŸŒãã§ããŸãã
⯠rg '^CONFIG_VIRTIO_BLK=' dev/kernel/config/debian-13-amd64 .build/rust-next/.config
.build/rust-next/.config
1968:CONFIG_VIRTIO_BLK=y
dev/kernel/config/debian-13-amd64
2691:CONFIG_VIRTIO_BLK=mDebian ã®ãããªæ±çš distro ã¯ãå¹
åºãããŒããŠã§ã¢ã«å¯Ÿå¿ãã€ã€ã䜿ããªãæ©èœã memory ã«èŒããªãããã«ãå¯èœãªéã m ãéžã¶æ¹éããšã£ãŠããŸããå®éãDebian ã® config ã§ã¯èšå®ãããŠãã 6,896 é
ç®ã®ãã¡ 4,049 é
ç®ã =m ã§ããã ã©ã®æ©èœã y ã«ããã©ãã m ã®ãŸãŸã«ãããã¯ãåŸã® Kernel config ã®äœæã®ç¯ã§è¡ãäœæ¥ã®äžå¿ã«ãªããŸãã
.config ã§èšå®ã§ããé
ç®ã¯èšå€§ã§ãŒãããå
šãŠãèšå®ããŠæå³ãããã«ããå®çŸããã®ã¯å€§å€ã§ãã ããã§æ¬èšäºã§ã¯ Debian 13 ã® VM ãçšæããŠãããã§å©çšãããŠãã .config ãåºçºç¹ã«ããã¢ãããŒããæ¡ããŸããã
ãªããHow many ways are there to configure the Linux kernel? ã«ãããšã6.16ã®æ®µéã§ãx86_64 ã§ã32,468ã®èšå®é ç®ãããããã§ãã
KVM/QEMU/libvirt
VM ãäœããšã¯ãå¥ã® OS(kernel)ã host äžã® 1 ã€ã® process ãšããŠåããããšã ãšèããŠã¿ãŸãã ãã ã kernel ã¯ãèªåã HW ãçŽæ¥å¶åŸ¡ã§ããåæã§æžãããŠããŸããdevice ã® register ã memory address ã« map ããŠèªã¿æžãããã(Memory-Mapped I/OãMMIO)ãä»®æ³ã¢ãã¬ã¹ãšç©çã¢ãã¬ã¹ã®ãããã³ã°ãå®è¡ãã process ã«å¿ããŠæžãæãããããŸãã userspace ã® process ã«ãã®ãããªæäœãèš±å¯ããããšã¯ã§ããŸãããããã§ãguest ãå®è¡ããŠãguest å ã§åŠçã§ããªãæäœãèµ·ãããå¶åŸ¡ãæ»ã£ãŠãããã㪠API ãèããŸãã
fn run_vm() {
loop {
match exec_guest() {
Exit::Mmio(addr) => emulate_hw(addr),
Exit::IoPort(port) => emulate_io(port),
Exit::Halt => break,
}
}
}CPU ã®ä»®æ³åæ¯æŽæ©èœ(Intel VT-x / AMD-V)ãæœè±¡åããŠãæŠãäžèšã®æ©èœãæäŸããŠãããã®ã KVM ã§ãã KVM 㯠/dev/kvm ãšãã device file ã userspace ã«å
¬éããŠãããKVM_RUN ioctl ãéã㊠guest ãå®è¡ã§ããŸãã(ãã®ãããã®è©±ããã³ãšããªããŠãå¿é
ããªãã§ãã ãããäžåºŠ driver ãæžããŠã¿ããšè
¹èœã¡ããŸã) ãã®ãšã guest ã®åœä»€ã¯ãsoftware ãè§£éã»å€æããŠããããã§ã¯ãªããå® CPU ãçŽæ¥å®è¡ããŠããŸããKVM 㯠VMLAUNCH / VMRESUME åœä»€(Intel ã®å Žå)ã§ CPU ã guest çšã®å®è¡ mode ã«åãæ¿ããguest å
ã§åŠçã§ããªãæäœãèµ·ãããš CPU ã host ã«å¶åŸ¡ãæ»ããŸã(VM exit)ã VM exit ã§å¶åŸ¡ãæ»ãå
ã¯ãKVM_RUN ãåŒã³åºãã userspace process ã§ã¯ãªãããŸã host kernel å
ã® KVM ã§ããKVM å
ã§åŠçã§ããå Žå㯠guest ãåéããuserspace ã§ã®åŠçãå¿
èŠãªå Žåã« KVM_RUN ã KVM_EXIT_MMIO ã®ãã㪠exit reason ãšãšãã« return ããŸãã ãã®åãæ¿ããè¡ã£ãŠããã®ã arch/x86/kvm/vmx/vmenter.S ã® __vmx_vcpu_run ã§ãassembly ã§ vmlaunch / vmresume ãå®è¡ããŠããç®æã確èªã§ããŸãã æèå®éšã§ã¯ memory ã®ãããã³ã°å€æŽãåé¡ãšããŠæããŸããããæ¬äŒŒã³ãŒãã® loop ã«ã¯ç»å ŽããŠããŸãããCPU ã® 2 段éã®ã¢ãã¬ã¹å€æ(Intel ã§ã¯ EPTãAMD ã§ã¯ NPT)ãå©çšããå Žåãéåžžã® CR3 ã®å€æŽã guest page table ã®æŽæ°ã VM exit ãããå¿
èŠããªãããã§ããCPU 㯠guest ã®ä»®æ³ã¢ãã¬ã¹ããguest ã管çãã page table ã§ guest ã®ç©çã¢ãã¬ã¹ã«å€æããããã« host ã管çããå€æè¡šã§å®éã®ç©çã¢ãã¬ã¹ã«å€æããŸããããã«ãã guest kernel ã¯ãèªåã® page table ã®å€æŽã KVM ã QEMU ã«äžã€ã〠emulate ãããããšãªã process ããšã®ãããã³ã°ãåãæ¿ããããŸããäžæ¹ãguest ã®ç©çã¢ãã¬ã¹ã«å¯Ÿå¿ããäºæ®µç®ã®ãããã³ã°ãååšããªãå Žåãæš©éã«éåããå Žå㯠VM exit ãçºçãããããå®éã®ç©çã¢ãã¬ã¹ãžã®ãããã³ã°ã¯ host ã®ç®¡çäžã«çãŸããŸãã
ãã㊠KVM ã®å®äœã¯ kernel module(kvm ãš kvm_intel / kvm_amd)ã§ããæ¬èšäºã§æ±ã kernel module ãšããä»çµã¿ã®äžã«ãä»®æ³ååºç€ãå®è£
ãããŠããŸãã
ãã ããKVM ã ãã§ã¯å®å
šãª VM ã«ã¯ãªããŸãããKVM ã userspace ã«è¿ãã device æäœãåŠçãããemulate_hw() ã®å®è£
ãå¥ã«å¿
èŠã§ããguest å
ã§ block device driver ã«ããæžã蟌ã¿ãè¡ãããããhost åŽã§ãªãããã®æ¹æ³ã§æ°žç¶åãããšãã£ãåŠçãå¿
èŠã§ãã ãããæäŸããŠãããã®ã QEMU ã§ããäžèšã® loop ãåããŠããã®ã QEMU ã§ãVM 1 å°ã¯ host ããèŠããš 1 ã€ã® QEMU process ã§ããæ¬èšäºã§ã¯ãqcow2 file ããã®æ°žç¶åå
ã«ãªããŸãã å®éãæ¬äŒŒã³ãŒãã® loop 㯠QEMU ã® kvm_cpu_exec() ã«ã»ãŒãã®ãŸãŸã®åœ¢ã§ååšããKVM_RUN ioctl ã®åŒã³åºããšãè¿ã£ãŠãã exit_reason ã«ããåå²(KVM_EXIT_IOãKVM_EXIT_MMIOã...)ã確èªã§ããŸãã
ããã«ãQEMU ã VirtualBoxãXen ãªã©ãæœè±¡åããŠãçµ±äžç㪠API(interface)ã§ç®¡çå¯èœã«ããŠãããã®ã libvirt ã§ãã host ã§ libvirtd ãšãã daemon ãåããvirsh ã¯ãã® client ã§ããVM ã®å®çŸ©ã¯ domain XMLãdisk 㯠storage pool ãšããåäœã§ç®¡çãããŸãã以éã®ç¯ã®ãã°ã«åºãŠãã --connect qemu:///system ã¯ããã® libvirtd ãžã®æ¥ç¶å
ãæå®ããŠããŸãã ãªããflake.nix ã§å
¥ãã®ã¯ virsh ãªã©ã® client åŽãªã®ã§ãlibvirtd 㯠host ã§åãããŠããå¿
èŠããããŸã(NixOS ã§ããã° virtualisation.libvirtd.enable)ã
ããããä»®æ³åãšã¯äœãã«ã€ããŠã¯ãäœã£ãŠçè§£ããä»®æ³åæè¡ ãéåžžã«ãªã¹ã¹ã¡ã§ããæ¬èšäºã§ç»å Žãã virtio ã®èª¬æãå®è£ (virtio-blk)ããããŸãã
virtiofs ã«ãã file å ±æ
æ¬èšäºã§ã¯ãhost ãš VM ã® file å ±æã« virtiofs ãå©çšããŠããŸãã
åæãšããŠãFUSE(Filesystem in Userspace)ãšããä»çµã¿ããããŸããfilesystem ã®åŠçã kernel ã®å€ã® process ã«ç§»è²ããããã®ãã®ã§ãopen/read/write ãšãã£ãåŠçã® request/response 圢åŒããããã³ã«ãšããŠæ±ºãŸã£ãŠããŸãã virtiofs ã¯ããã® FUSE ãããã³ã«ã転çšããŸããguest å ã§ mount ãã virtiofs ãžã®åŠçäŸé Œã FUSE ã® request ã« serialize ãã転éå ããåããã·ã³ã® userspaceãã§ã¯ãªããhost åŽãã«å·®ãæ¿ãããã®ã virtiofs ã§ãã host åŽã§ã¯ virtiofsd ãšãã daemon(libvirt ã VM èµ·åæã«ç«ã¡äžããŸã)ã request ãåããå ±æå¯Ÿè±¡ã® directory äžã§å®éã® file æäœãè¡ã£ãŠ response ãè¿ããŸããguest ãã read ããã° host ã® file ã®äžèº«ãè¿ã£ãŠããã®ã¯ãã®ããã§ãã
guest ã® virtiofs driver ãš host åŽã® backend ãšã®éä¿¡ã«ã¯ virtio ãå©çšããŸããvirtio ã¯ãç¹å®ã® physical device ãåçŸããã®ã§ã¯ãªããguest driver ãš host backend ã device request ãåãæž¡ãããã®å
±é interface ãå®ããŠããŸããrequest ãš buffer ã®äœçœ®ã memory äžã® queue(virtqueue)ãžè¿œå ããqueue ãæŽæ°ãããããšã ãã host åŽãžéç¥ããŸããè€æ°ã® request ã memory äžã§ãŸãšããŠåãæž¡ãããããdevice æäœã®ãã³ã« VM exit ããŠå
容ã emulate ããå¿
èŠããããŸããã ã€ãŸããVM(guest)å
ã§å®è¡ãããããšãåæã«ãdevice ã«å¯Ÿãã request/response ãã§ããã ã memory ã«èŒããŠãhost ã«åŠçãæ»ã MMIO ã®é »åºŠãæããèšèšã® device driver ãšãããŸãã æ¬èšäºã§ã¯ file å
±æ(virtiofs)ã®ã»ããdisk(virtio-blk)ãåãä»çµã¿ã§ããåŸã® Kernel config ã®äœæã§ FUSE_FS ã VIRTIO_FSãVIRTIO_BLK ãæå¹ã«ããã®ã¯ããã® guest åŽ driver ã kernel ã«çµã¿èŸŒãããã§ãã ãªããvirtiofsd 㯠QEMU ãšã¯å¥ã® process ãªã®ã§ãvirtqueue ãå«ã guest ã® memory ã«ã¢ã¯ã»ã¹ã§ãããããVM ã® memory ã¯å
±æå¯èœãªæ¹åŒã§ç¢ºä¿ããå¿
èŠããããŸããdomain XML ã® memoryBacking(memfd + shared)ããã®èšå®ã§ãã
å šäœã®æµã
äžè¿°ã®éããkernel module ããã«ãããã«ã¯ãload å ãšãªã kernel ãå ã«ãã«ãããŠããå¿ èŠããããŸãã ãŸãããã«ããã kernel ã§ãããRust for Linux ã®éçº branch ã§ãã rust-next ãå©çšããŸããRust é¢é£ã®å€æŽã mainline ããå ã«ããã«åã蟌ãŸãããããåžžã«ææ°ã®å€æŽã詊ããããã§ãã ãã ããmainline ã§ãåé¡ãããŸãããrust-next ã®å€æŽã¯ merge window ããšã« mainline ã«åã蟌ãŸããrust-next èªäœã mainline ã® rc çã base ã«ããŠãããããäž¡è ã«å€§ããªä¹é¢ã¯ãããŸããã
kernel ã®ãã«ãã«å¿
èŠãª .config ã¯ãDebian ã® config ãåºçºç¹ã«ããŸãããã®ããã«ããŸã Debian VM(deb13)ãäœæããconfig ãš lsmod ãæ¡åããŸãã lsmod ã«ã¯å®éã« load ãããŠãã module äžèЧãå«ãŸããŠããŸãããããå©çšããŠãkernel ãã«ãæã«ãã«ããã module(driver)ã®æ°ãæžãããŸãã
ãã«ããã kernel ã¯ãVM ã« install ãã代ããã«ãQEMU ã® direct kernel boot ã§èµ·åããŸãã QEMU 㯠disk å
ã® bootloader ãçµç±ããã«ãhost äžã® kernel image ãçŽæ¥ load ã㊠boot ã§ããŸãã kernel ãäœãçŽããã³ã« VM å
ã§ã® install äœæ¥ãäžèŠã«ãªãäžæ¹ãinitramfs ã䜿ããªã boot ã«ãªããããboot ã«å¿
èŠãª driver(virtio ã ext4)㯠module ã§ã¯ãªã y ã§ kernel ã«çµã¿èŸŒãã§ãããŸãã
æåŸã«ããã® kernel ã«å¯Ÿã㊠miscdrv module ããã«ãããvirtiofs ã®å
±æ directory çµç±ã§ VM ã«æž¡ã㊠insmod ããŸãã
éçºç°å¢
ãŸããrust-next ãšæ¬èšäºã® repo ã clone ããŸããdrivers åŽã® task ã ../linux ãåç
§ããããã2 ã€ã® repo ã¯åã directory ã«äžŠã¹ãåæã§ããRust-for-Linux/linux 㯠default branch ã rust-next ãªã®ã§ãbranch ã®æå®ã¯äžèŠã§ãã
git clone https://github.com/Rust-for-Linux/linux.git
git clone https://github.com/ymgyt/drivers.git
cd drivers
git checkout blog-r4l-setup
nix developéçºã«å¿
èŠãªäŸå㯠flake.nix ã«å®£èšããŠãããnix develop ã§æå¹ã«ãªããŸããå
èš³ã¯å€§ãã 3 ã€ã§ãã
- VM ã®ç®¡ç: libvirt(
virsh)ãQEMUãimage ã®ååŸã«äœ¿ã curl ãªã© - kernel ã®ãã«ãã«å¿ èŠãª host tool 矀: makeãflexãbisonãbcãperlãpython3 ãªã©
- Rust for Linux ã® toolchain: clang/LLVMãlldãrustcãbindgen(å·çæç¹ã§ã¯ clang 21.1.8ãrustc 1.96.1ãbindgen 0.72.1)
kernel ã¯ãã«ãã«å¿ èŠãª tool ã®æäœ version ã changes.rst ã§èŠå®ããŠããŸã(å·çæç¹ã§ Rust 㯠1.85.0ãbindgen 㯠0.71.1 以äž)ã
flake.nix ã® shellHook ã§ã¯ãç°å¢å€æ°ãããããŠèšå®ããŠããŸãã
shellHook = ''
export CC="${llvm.clang-unwrapped}/bin/clang"
export HOSTCC="${llvm.clang}/bin/clang"
export HOSTCXX="${llvm.clang}/bin/clang++"
export BINDGEN="${pkgs.rust-bindgen-unwrapped}/bin/bindgen"
export KERNEL_MAKE_ARGS="LLVM=1 CC=$CC HOSTCC=$HOSTCC HOSTCXX=$HOSTCXX RUSTC=$RUSTC BINDGEN=$BINDGEN"
exec nu
'';KERNEL_MAKE_ARGS ã¯ã以éã®ç¯ã§ just ãå®è¡ãã make ã«ãã®ãŸãŸæž¡ãããŸãããã°ã«åºãŠãã LLVM=1 CC=/nix/store/... RUSTC=/nix/store/... ãšããé·ãåŒæ°ã®æ£äœã¯ããã§ãã LLVM=1 㯠kernel ã GCC ã§ã¯ãªã clang/LLVM ã§ãã«ãããæå®ã§ããRust åŽã® bindgen ã libclang ãå©çšãããããC åŽãåã LLVM ã«æããŠããŸãã CC ã«ã ã unwrapped ã® clang ã䜿ã£ãŠããã®ã¯ Nix ç¹æã®äºæ
ã§ããNix ã® clang wrapper 㯠Nix ç°å¢åãã® compile flag ãæé»ã«æ³šå
¥ãããããflag ãå³å¯ã«ç®¡çãã kernel æ¬äœã®ãã«ãã«ã¯åããŸãããäžæ¹ããã«ãäžã« host åŽã§åãã tool ã®ãã«ã(HOSTCC)ã«ã¯ãæšæº library ã®è§£æ±ºãããŠããã wrapper ã®æ¹ãéœåãè¯ãããã§ãã
toolchain ãæã£ãŠãããã¯ãkernel ãçšæããŠãã rustavailable target ã§ç¢ºèªã§ããŸãã
⯠just kernel rustavailable
make -C "<linux>" "O=<drivers>/.build/rust-next" LLVM=1 CC=/nix/store/<hash>-clang-21.1.8/bin/clang HOSTCC=/nix/store/<hash>-clang-wrapper-21.1.8/bin/clang HOSTCXX=/nix/store/<hash>-clang-wrapper-21.1.8/bin/clang++ RUSTC=/nix/store/<hash>-rustc-wrapper-1.96.1/bin/rustc BINDGEN=/nix/store/<hash>-rust-bindgen-unwrapped-0.72.1/bin/bindgen rustavailable
make: Entering directory '<linux>'
make[1]: Entering directory '<drivers>/.build/rust-next'
Rust is available!
make[1]: Leaving directory '<drivers>/.build/rust-next'
make: Leaving directory '<linux>'ãªããshellHook ã®æåŸã® exec nu ã«ãããnix develop åŸã® shell 㯠nushell ã«ãªããŸãããã® repo ã® task(just)ã nushell ãåæã«ããŠããããã§ãã
Debian VM(deb13)ã®äœæ
ãŸã Debian VM ãäœæããŸããhost ã§ kernel image ããã«ãããéã®åºæºãšãªãèšå®(config ãš lsmod)ãååŸããããã§ãã
libvirt ã§ã¯ãVM ã® disk ãªã©ã® storage ã pool ãšããåäœã§ç®¡çããŸããdir type ã® pool ã®å®äœã¯ãã ã® directory ã§ããã®äžã® file ã volume ãšããŠæ±ãããŸããããã§ã¯ repo å
ã® vm/storage/ ã drivers ãšããååã® pool ãšããŠç»é²ããŸãã
⯠just vm pool define
command: virsh --connect qemu:///system pool-define-as drivers dir --target <drivers>/vm/storage
Pool drivers defined
⯠just vm pool start
command: virsh --connect qemu:///system pool-start drivers
Pool drivers startedVM ã® base image ãšããŠå©çšãã Debian cloud image ãååŸããŸãã Debian ã® cloud image ã¯ãAWS ãªã©ã® cloud platform äžã§ cloud-init ãšããä»çµã¿ã«ãã£ãŠåæèšå®(user ã®äœæã SSH éµã®æå ¥ãªã©)ãè¡ãããããšãåæãšãã variant ãäžå¿ã§ãã ä»å㯠cloud ã§ã¯ãªãæå ã® libvirt ã§äœ¿ããããcloud-init ãå«ãŸããboot åŸãã®ãŸãŸ serial console ãããã°ã€ã³ããŠäœ¿ãå§ãããã nocloud variant ãå©çšããŸãã
nocloud: Does not run cloud-init and boots directly to a root prompt. Useful for local VM instantiation with tools like QEMU.
⯠just vm image
image: downloading debian-13-nocloud-amd64-20260810-2566.qcow2
image: verifying SHA-512
image: checksum verified
pool: refreshing drivers
command: virsh --connect qemu:///system pool-refresh drivers
Pool drivers refreshed
volume: debian-13-nocloud-amd64-20260810-2566.qcow2
command: virsh --connect qemu:///system vol-info debian-13-nocloud-amd64-20260810-2566.qcow2 --pool drivers
Name: debian-13-nocloud-amd64-20260810-2566.qcow2
Type: file
Capacity: 3.00 GiB
Allocation: 387.25 MiBååŸãã base image ã VM ã® disk ãšããŠçŽæ¥äœ¿ãã®ã§ã¯ãªããbase image ã backing file ãšãã copy-on-write ã® volume(overlay)ã VM ããšã«äœæããŸããæžã蟌ã¿ã¯ overlay åŽã«ã®ã¿èšé²ãããbase image ã¯å€æŽãããŸãããåŸã§äœæãã rust VM ãåã base image ãå ±æããããããèªåã® overlay ãæã¡ãŸãã
⯠just vm overlay deb13
volume: creating deb13.qcow2
command: virsh --connect qemu:///system vol-create-as drivers deb13.qcow2 3221225472 --format qcow2 --backing-vol debian-13-nocloud-amd64-20260810-2566.qcow2 --backing-vol-format qcow2
Vol deb13.qcow2 created
volume: deb13.qcow2
command: virsh --connect qemu:///system vol-info deb13.qcow2 --pool drivers
Name: deb13.qcow2
Type: file
Capacity: 3.00 GiB
Allocation: 196.00 KiBäœæçŽåŸã® overlay ã¯ãCapacity 3.00 GiB ã«å¯Ÿã㊠Allocation(å®éã«ç¢ºä¿ããã容é)ã 196.00 KiB ãããªãããšããããŸã ã»ãšãã©äœãæžã蟌ãŸããŠããªãããšã確èªã§ããŸãã
⯠just vm define deb13
domain: rendered vm/domains/deb13/domain.xml
domain: defining deb13
command: virsh --connect qemu:///system define vm/domains/deb13/domain.xml --validate
Domain 'deb13' defined from vm/domains/deb13/domain.xml
command: virsh --connect qemu:///system dominfo deb13
Id: -
Name: deb13
UUID: 6e62dce4-6248-4db5-bfbb-2049bcbc5dc5
OS Type: hvm
State: shut off
CPU(s): 2
Max memory: 2097152 KiB
Used memory: 2097152 KiB
Persistent: yes
Autostart: disable
Autostart Once: disable
Managed save: no
Security model: none
Security DOI: 0VM ã«æ¥ç¶ããŸãã
⯠just vm boot deb13
<boot log...>
Linux localhost 6.12.101+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.101-1 (2026-08-05) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@localhost:~# uname -a
Linux localhost 6.12.101+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.101-1 (2026-08-05) x86_64 GNU/Linuxconfig ãš lsmod ã®æ¡å
host ãšã® file ã®ãããšãã«ã¯ virtiofs ãå©çšããŸããdomain XML ã§ãhost ã® vm/shared/ directory ã drivers ãšããååã§ guest ã« export ããŠãããguest ãã㯠virtiofs ãšã㊠mount ããããšã§ã¢ã¯ã»ã¹ã§ããŸãã
root@localhost:~# mkdir -p /mnt/drivers
root@localhost:~# mount -t virtiofs drivers /mnt/drivers
root@localhost:~# findmnt /mnt/drivers
TARGET SOURCE FSTYPE OPTIONS
/mnt/drivers drivers virtiofs rw,relatime
root@localhost:~# cp /boot/config-$(uname -r) /mnt/drivers/ç¶ããŠãload ãããŠãã module ã®äžèŠ§ãæ¡åããŸããããã¯åŸã® Kernel config ã®äœæã§å©çšããŸãã
lsmod > /mnt/drivers/lsmod-$(uname -r)host åŽã§ãæ¡åãã config ã repo ã®ç®¡çäžã« copy ããŸãã
⯠file vm/shared/config-6.12.101+deb13-amd64
vm/shared/config-6.12.101+deb13-amd64: Linux make config build file, ASCII text
⯠cp vm/shared/config-6.12.101+deb13-amd64 dev/kernel/config/debian-13-amd64Kernel config ã®äœæ
æ¡åãã Debian ã® config ãåºçºç¹ã«ãrust-next çšã® .config ãäœæããŸãã kernel ã®ãã«ã㯠source tree ãæ±ããªã build(make O=<dir>)ã§è¡ãã.config ãå«ãææç©ã¯ãã¹ãŠ .build/rust-next ã«çœ®ããŸãããŸã seed ãšãªã config ã build directory ã« copy ããŸãã
⯠just kernel initconfig
mkdir -p "<drivers>/.build/rust-next"
cp --force "<drivers>/dev/kernel/config/debian-13-amd64" "<drivers>/.build/rust-next/.config"seed 㯠kernel 6.12 åœæã® config ãªã®ã§ãrust-next(7.2-rc1 base)ã® Kconfig ã«åãããŠæŽæ°ããŸãããããè¡ãã®ã olddefconfig target ã§ãã
æ¢åã® .config ã base ã«ãæ°ããå¢ããé
ç®ã察話ãªãã§ default å€ã«èšå®ããŸãã
⯠just kernel olddefconfig
make -C "<linux>" "O=<drivers>/.build/rust-next" olddefconfig
make: Entering directory '<linux>'
make[1]: Entering directory '<drivers>/.build/rust-next'
.config:1420:warning: symbol value 'm' invalid for NETFILTER_NETLINK
.config:6870:warning: symbol value 'm' invalid for FB_BACKLIGHT
.config:8650:warning: symbol value 'm' invalid for HYPERV
.config:9969:warning: symbol value 'm' invalid for ANDROID_BINDER_IPC
.config:10916:warning: symbol value 'm' invalid for CRYPTO_LIB_CURVE25519_GENERIC
.config:10922:warning: symbol value 'm' invalid for CRYPTO_LIB_POLY1305_GENERIC
.config:11203:warning: symbol value 'n' invalid for BOOTPARAM_SOFTLOCKUP_PANIC
.config:11215:warning: symbol value 'n' invalid for BOOTPARAM_HUNG_TASK_PANIC
#
# configuration written to .config
#
make[1]: Leaving directory '<drivers>/.build/rust-next'
make: Leaving directory '<linux>'warning ã¯ã6.12 ãã 7.2 ã®éã«é
ç®ã®åãå€ãã£ãããšã瀺ããŠããŸããäŸãã° NETFILTER_NETLINK 㯠tristate ãã bool ã«å€ãã£ããã m ããBOOTPARAM_SOFTLOCKUP_PANIC 㯠bool ãã int ã«å€ãã£ããã n ãããããã invalid ãšå ±åãããŠããŸãããããã olddefconfig ãæ°ããåã® default å€ã§èšå®ãçŽãã®ã§ã察å¿ã¯äžèŠã§ãã
次㫠Rust support ãæå¹åããŸããscripts/config 㯠.config ã command line ããç·šéããããã® kernel ä»å±ã® script ã§ãã
⯠just kernel rustconfig
"<linux>/scripts/config" --file "<drivers>/.build/rust-next/.config" --enable GENDWARFKSYMS --enable RUSTRUST ãšåæã« GENDWARFKSYMS ãæå¹åããŠããã®ã¯ãinit/Kconfig ã«äŸåãå®çŸ©ãããŠããããã§ãã
config RUST
bool "Rust support"
...
select EXTENDED_MODVERSIONS if MODVERSIONS
depends on !MODVERSIONS || GENDWARFKSYMSåæã®ç¢ºèªã§èŠã symbol ã® CRC ã¯ãC ã®ã³ãŒãã§ã¯ genksyms ãšãã parser ãèšç®ããŸãããgenksyms 㯠Rust ã®ã³ãŒããè§£æã§ããŸãããGENDWARFKSYMS ã¯ãCRC ã DWARF debug æ
å ±ããèšç®ãã代æ¿ã®ä»çµã¿ã§ããseed ã® config 㯠CONFIG_MODVERSIONS=y ãªã®ã§ãGENDWARFKSYMS ãªãã§ã¯ RUST ãæå¹ã«ã§ããŸããã
次ã«ãVM ã® boot ã«å¿
èŠãª driver ãæå¹åããŸããå
šäœã®æµãã§è¿°ã¹ããšãããdirect kernel boot ã§ã¯ initramfs ã䜿ããªããããboot ã«å¿
èŠãª driver 㯠module ã§ã¯ãªã kernel æ¬äœã«çµã¿èŸŒãã§(=y)ããå¿
èŠããããŸãã
⯠just kernel vmconfig
"<linux>/scripts/config" --file "<drivers>/.build/rust-next/.config" --enable VIRTIO_MENU --enable VIRTIO_PCI --enable VIRTIO_BLK --enable EXT4_FS --enable EFI_PARTITION --enable FUSE_FS --enable VIRTIO_FS --enable SERIAL_8250 --enable SERIAL_8250_CONSOLE --enable VFAT_FS --enable NLS_CODEPAGE_437 --enable NLS_ASCII --enable EFIVAR_FSæå¹ã«ããŠããã®ã¯ãroot filesystem ã® mount ã«å¿
èŠãª virtio disk ãš ext4(VIRTIO_PCI, VIRTIO_BLK, EXT4_FS, EFI_PARTITION)ãhost ãšã® file å
±æã«äœ¿ã virtiofs(FUSE_FS, VIRTIO_FS)ãserial console(SERIAL_8250, SERIAL_8250_CONSOLE)ãããã³ EFI é¢é£(VFAT_FS, EFIVAR_FS ãªã©)ã§ãã
æåŸã«ãæ¡åãã lsmod ãçšããŠããã«ããã module ãå®éã« load ãããŠãããã®ã«çµã蟌ã¿ãŸããlocalmodconfig 㯠.config ã® =m ã®é
ç®ã®ãã¡ãLSMOD ã§æå®ããäžèЧã«èŒã£ãŠããªã module ãç¡å¹ã«ããŸã(=y ã®é
ç®ã«ã¯è§ŠããŸãã)ãyes "" ãå眮ããŠããã®ã¯ãéäžã§èããã質åã«ãã¹ãŠ default ã§åçããããã§ãã
⯠just kernel localmodconfig vm/shared/lsmod-6.12.101+deb13-amd64
yes "" | make -C "<linux>" "O=<drivers>/.build/rust-next" LLVM=1 CC=/nix/store/<hash>-clang-21.1.8/bin/clang HOSTCC=/nix/store/<hash>-clang-wrapper-21.1.8/bin/clang HOSTCXX=/nix/store/<hash>-clang-wrapper-21.1.8/bin/clang++ RUSTC=/nix/store/<hash>-rustc-wrapper-1.96.1/bin/rustc BINDGEN=/nix/store/<hash>-rust-bindgen-unwrapped-0.72.1/bin/bindgen "LSMOD=<drivers>/vm/shared/lsmod-6.12.101+deb13-amd64" localmodconfig
make: Entering directory '<linux>'
make[1]: Entering directory '<drivers>/.build/rust-next'ããã«ãããseed ã®æç¹ã§ 4,049 åãã£ã =m ã®é
ç®ã¯æçµçã« 49 åãŸã§æžããkernel ã®ãã«ãæéã倧å¹
ã«çããªããŸãã
Kernel image ã® build
config ãã§ããã®ã§ãkernel image ããã«ãããŸãã
⯠just kernel image
make -C "<linux>" "O=<drivers>/.build/rust-next" LLVM=1 CC=/nix/store/<hash>-clang-21.1.8/bin/clang HOSTCC=/nix/store/<hash>-clang-wrapper-21.1.8/bin/clang HOSTCXX=/nix/store/<hash>-clang-wrapper-21.1.8/bin/clang++ RUSTC=/nix/store/<hash>-rustc-wrapper-1.96.1/bin/rustc BINDGEN=/nix/store/<hash>-rust-bindgen-unwrapped-0.72.1/bin/bindgen -j14 bzImage
make: Entering directory '<linux>'
make[1]: Entering directory '<drivers>/.build/rust-next'
SYNC include/config/auto.conf
HOSTRUSTC scripts/generate_rust_target
...
Kernel: arch/x86/boot/bzImage is ready (#4)Rust VM ã®åæå
ãã«ããã kernel ã§ boot ãã VM ãäœæããŸããæé 㯠deb13 ãšåãã§ããåã base image ãã rust çšã® overlay ãäœããdomain ãå®çŸ©ããŸãã
⯠just vm define rust
exists: vm/storage/debian-13-nocloud-amd64-20260810-2566.qcow2
image: verifying SHA-512
image: checksum verified
pool: refreshing drivers
command: virsh --connect qemu:///system pool-refresh drivers
Pool drivers refreshed
volume: debian-13-nocloud-amd64-20260810-2566.qcow2
command: virsh --connect qemu:///system vol-info debian-13-nocloud-amd64-20260810-2566.qcow2 --pool drivers
Name: debian-13-nocloud-amd64-20260810-2566.qcow2
Type: file
Capacity: 3.00 GiB
Allocation: 387.25 MiB
volume: creating rust.qcow2
command: virsh --connect qemu:///system vol-create-as drivers rust.qcow2 3221225472 --format qcow2 --backing-vol debian-13-nocloud-amd64-20260810-2566.qcow2 --backing-vol-format qcow2
Vol rust.qcow2 created
volume: rust.qcow2
command: virsh --connect qemu:///system vol-info rust.qcow2 --pool drivers
Name: rust.qcow2
Type: file
Capacity: 3.00 GiB
Allocation: 196.00 KiB
domain: rendered vm/domains/rust/domain.xml
domain: defining rust
command: virsh --connect qemu:///system define vm/domains/rust/domain.xml --validate
Domain 'rust' defined from vm/domains/rust/domain.xml
command: virsh --connect qemu:///system dominfo rust
Id: -
Name: rust
UUID: 5ecd39df-0b03-4cb6-9d9d-5ebed3d88a51
OS Type: hvm
State: shut off
CPU(s): 2
Max memory: 2097152 KiB
Used memory: 2097152 KiB
Persistent: yes
Autostart: disable
Autostart Once: disable
Managed save: no
Security model: none
Security DOI: 0deb13 ãšã®å®è³ªçãªéãã¯ãdomain XML ã® <os> ã ãã§ãã
<os firmware='efi'>
<type arch='x86_64' machine='pc-q35-10.2'>hvm</type>
- <boot dev='hd'/>
+ <kernel>${KERNEL_IMAGE}</kernel>
+ <cmdline>root=PARTUUID=6cf4a790-ccd9-46ad-a256-5f853165c65e ro console=tty0 console=ttyS0,115200 earlyprintk=ttyS0,115200 consoleblank=0</cmdline>
</os>deb13 ã® <boot dev='hd'/> 㯠disk ãã boot ããæå®ã§ããEFI firmware ã disk å
ã® bootloader ãèµ·åããbootloader ã disk ã« install ããã Debian ã® kernel ãš initramfs ã load ããŸãã rust VM ã§ã¯ããã <kernel> ã«çœ®ãæããŠããŸããããã QEMU ã® direct kernel boot ã§ãbootloader ãçµç±ããã«ãQEMU ã host äžã® kernel image ãçŽæ¥ load ããŠèµ·åããŸãã${KERNEL_IMAGE} 㯠domain XML ã® render æã« .build/rust-next/arch/x86/boot/bzImage ã«å±éãããã®ã§ãkernel ããã«ããçŽããã VM ãèµ·åãçŽãã ãã§æ°ãã kernel ã boot ããŸãã
<cmdline> ã¯ãæ¬æ¥ bootloader ã kernel ã«æž¡ã command line ãèªåã§æå®ãããã®ã§ãã root=PARTUUID=... 㯠root filesystem ã®å Žæã瀺ããŸããinitramfs ããªããããkernel ã¯èªåã§ãã® partition ãèŠã€ã㊠mount ã§ããå¿
èŠããããŸããKernel config ã®äœæã§ VIRTIO_BLK ã EXT4_FS ã =y ã«ããã®ã¯ããã®äžè¡ã®ããã§ãã PARTUUID ã®å€ã¯ deb13 å
ã§ blkid ãå®è¡ãããšç¢ºèªã§ããŸãã
root@localhost:~# blkid
/dev/vda15: SEC_TYPE="msdos" UUID="2041-A3EB" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="e65fb8b6-cb05-404f-ba6f-37e2770a43cf"
/dev/vda1: UUID="ed2d1185-cebf-4062-a788-eeab651e6ad2" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="6cf4a790-ccd9-46ad-a256-5f853165c65e"
/dev/vda14: PARTUUID="f6363e47-3332-4fac-8258-9f606b790ff1"root filesystem ã§ãã ext4 partition(/dev/vda1)ã® PARTUUID ã cmdline ã«æå®ããå€ã§ããdeb13 ãš rust ã¯åã base image ããäœã£ã overlay ãªã®ã§ãåãå€ã«ãªããŸããPARTUUID 㯠image ã® build ããšã«å€ãããããå¥ã® image ã§è¿œè©Šããå Žåã¯èªã¿çŽãå¿
èŠããããŸãã ã¡ãªã¿ã« vfat ã® partition(/dev/vda15)㯠EFI System Partition ã§ãKernel config ã®äœæã§ VFAT_FS ãæå¹ã«ããã®ã¯ãboot åŸã«ããã mount ã§ããããã«ããããã§ãã console=ttyS0,115200 㯠kernel log ã®åºåå
ã serial console ã«ããæå®ã§ãvirsh console ã§èŠããã®ã¯ãã®åºåã§ãã
⯠just vm boot rust
root@localhost:~# uname -a
Linux localhost 7.2.0-rc1+ #4 SMP PREEMPT_DYNAMIC Sat Aug 15 13:21:42 JST 2026 x86_64 GNU/LinuxModule ã® build
ãããã miscdrv ããã«ãããŸãããã®åã«ãin-tree ã® module ããã«ãããŠãããŸãã
⯠just kernel modulesåæã®ç¢ºèªã§èŠããšãããout-of-tree module ã®ãã«ãã«ã¯ãkernel ã export ãã symbol ã® CRC å°åž³ã§ãã Module.symvers ãå¿
èŠã§ããbzImage ã®ãã«ãã§çæãããã®ã¯ vmlinux å(vmlinux.symvers)ãŸã§ã§ãModule.symvers ã¯ãã® modules target ã§çæãããŸãã
miscdrv åŽã® Makefile ã¯ä»¥äžã®ãšããã§ãã
ifneq ($(KERNELRELEASE),)
obj-m := miscdrv.o
else
KDIR ?= ../../../.build/rust-next
.PHONY: modules modules_prepare clean
modules: modules_prepare
$(MAKE) -C "$(KDIR)" M="$$PWD" $(KERNEL_MAKE_ARGS) modules
modules_prepare:
$(MAKE) -C "$(KDIR)" $(KERNEL_MAKE_ARGS) modules_prepare
clean:
$(MAKE) -C "$(KDIR)" M="$$PWD" clean
endifout-of-tree module ã®ãã«ãã¯ãkernel ã®ãã«ãã·ã¹ãã (kbuild)ãžã®äŸé Œãšãã圢ããšããŸã(Documentation/kbuild/modules)ãmake -C <kernel build directory> M=<module ã® directory> modules ã§ããM= ã«ãã module ããã«ãããããšäŒããŸãã ãã® Makefile 㯠2 åèªãŸããŸããæå
ã§ make modules ãå®è¡ãããš else åŽãè©äŸ¡ãããkbuild ã«äŸé Œãé£ã³ãŸããkbuild ã M= ã® directory ãåŠçããéã«åã³ãã® Makefile ãèªã¿(ãã®ãšã㯠KERNELRELEASE ãå®çŸ©ãããŠããŸã)ãä»åºŠã¯ obj-m := miscdrv.o ã ããè©äŸ¡ãããŸãã obj-m 㯠module ãšããŠãã«ããã object ã®å®£èšã§ããkbuild 㯠miscdrv.o ã® source ãšã㊠miscdrv.rs ãèŠã€ããrustc ã§ã³ã³ãã€ã«ã㊠miscdrv.ko ãŸã§çµã¿ç«ãŠãŸãã
⯠cd handson/miscdrv/module/
⯠make modules
⯠modinfo miscdrv.ko
filename: <drivers>/handson/miscdrv/module/miscdrv.ko
author: ymgyt
description: Rust misc device lab
license: GPL
name: miscdrv
depends:
vermagic: 7.2.0-rc1+ SMP preempt mod_unload modversions
retpoline: Yåºåã® vermagic ã«æ³šç®ããŠãã ãããkernel release ãšäž»èŠãªæ§æ(SMPãpreemptãmodversions)ãæååãšã㊠module ã«åã蟌ãŸããŠãããload æã« kernel èªèº«ã®å€ãšæ¯èŒãããäžèŽããªããã°æåŠãããŸããåæã®ç¢ºèªã§èŠã symbol åäœã® CRC ç §åãšããã® vermagic ã® 2 段æ§ãã§ãmodule ã load å ã® kernel ãšæŽåããŠããããšãæ€æ»ãããŸãã
Module ã®å®è¡
ãã«ããã miscdrv.ko ã virtiofs ã®å
±æ directory ã«çœ®ããVM å
ãã insmod ããŸãã
⯠cd ../../..
⯠cp handson/miscdrv/module/miscdrv.ko vm/shared
⯠just vm console rust
root@localhost:~# mkdir -p /mnt/drivers
root@localhost:~# mount -t virtiofs drivers /mnt/drivers
root@localhost:~# ls /mnt/drivers
config-6.12.101+deb13-amd64 lsmod-6.12.101+deb13-amd64 miscdrv.ko
root@localhost:~# insmod /mnt/drivers/miscdrv.ko
[ 5930.419675] miscdrv: loading out-of-tree module taints kernel.
[ 5930.421134] miscdrv: module verification failed: signature and/or required key missing - tainting kernel
[ 5930.423638] miscdrv: loaded
root@localhost:~# lsmod | grep miscdrv
miscdrv 12288 0
root@localhost:~# rmmod miscdrv
[ 5982.685953] miscdrv: unloadedinsmod æã®æåã® 2 è¡ã¯ warning ã§ãããæ³å®ã©ããã®ãã®ã§ãã1 è¡ç®ã® taint ã¯ããã® kernel 㯠tree å€ã® code ãå«ãã§ããããšããå°ã§ãout-of-tree module ã load ãããšå¿
ãä»ããŸãã2 è¡ç®ã¯ module ã®çœ²åæ€èšŒã«å€±æãããšãããã®ã§ãèªåã§ãã«ãããæªçœ²åã® module ãªã®ã§ãããæ³å®ã©ããã§ãã ãã㊠3 è¡ç®ã® miscdrv: loaded ããæŠèŠã«èŒãã init() ã® pr_info! ã®åºåã§ããrmmod ãããš Drop ãåŒã°ããunloaded ãåºåãããŸããã
ããã§ã€ãã«ãkernel module ããã«ãã㊠VM å ã§æ€èšŒããæµããã§ããŸããã
ãŸãšã
æåã¯ãmodule! ã®ä»çµã¿(ãªããš kernel å
ã§ synãquote ã䜿ããŸã)ãæžãããšããŠããã®ã§ãããç°å¢æ§ç¯ã®ç« ãé·ããªã£ãã®ã§èšäºãåããããšã«ããŸããã Rust ãã kernel ã®åçš®æ©èœ(memory å²åœãlock ååŸãtimerãsubsystem ç»é²ã...)ãžã®ã¢ã¯ã»ã¹ãæäŸãã kernel crate ã¯çµ¶è³éçºäžã§ãæ¥ã
æ©èœè¿œå ãç¶ããŠããŸãã Rust for Linux project ã®ãããã§ãä»ãŸã§ C éçºè
ã®ç¹æš©ã ã£ã module/driver éçºã Rust ãããè¡ããã®ã¯éåžžã«ãããããã§ãã ã¡ãªã¿ã«ãkernel å
ã® Rust ã«å¯Ÿããã¹ã¿ã³ã¹ã¯ subsystem ããšã«æ§ã
ã§ãã
DRM subsystem ã§ã¯ 2025 幎 12 æã®æ®µéã§
It was still perhaps surprising, though, when Airlie (the DRM maintainer) said that the subsystem is only "about a year away" from disallowing new drivers written in C and requiring the use of Rust.
(ããã§ããã¯ãé©ãã ã£ãã®ã¯ãDRM subsystem ã® maintainer ã§ãã Airlie æ°ããC ã§æžãããæ°ãã driver ãåãå ¥ãã Rust ã®äœ¿çšãå¿ é ãšããã®ã¯ãããš 1 幎çšåºŠãå ã®è©±ã ããšè¿°ã¹ãããšã§ãã)
ãšãã話ããLWN ã§ç޹ä»ãããŠããŸããã