Linux-Kernel

WSL 2 沒有 /lib/modules/

  • May 12, 2022

我有一個 hello world 核心模組的原始碼,它可以在筆記型電腦的 Ubuntu 20 中執行。現在我正在嘗試在 Ubuntu 20 中但在 WSL2 中編譯相同的程式碼。為此,我正在使用這個:

make -C /sys/modules/$(shell uname -r)/build M=$(PWD) modules

問題是它/lib/modules是空的。似乎WSL2沒有帶來任何東西/lib/modules/4.19.104-microsoft-standard/build

我嘗試使用以下方法獲取標題:

sudo apt search linux-headers-`uname -r`

Sorting... Done
Full Text Search... Done

但是模組文件夾中沒有填充任何內容

為了該文件夾包含所有必需的模組,我需要做些什麼嗎?

$$ EDIT $$ 感謝@HannahJ,讓我們更加親近。

我在做:

> sudo make -C /home/<user>/WSL2-Linux-Kernel M=$(pwd) modules

SL2-Linux-Kernel M=$(pwd) modules
make: Entering directory '/home/<user>/WSL2-Linux-Kernel'
 CC [M]  /home/<user>/containers-assembly-permissionsdemo/demo-2/lkm_example.o
 Building modules, stage 2.
 MODPOST 1 modules
 CC      /home/<user>/containers-assembly-permissionsdemo/demo-2/lkm_example.mod.o
 LD [M]  /home/<user>/containers-assembly-permissionsdemo/demo-2/lkm_example.ko
make: Leaving directory '/home/<user>/WSL2-Linux-Kernel'

最後,我lkm_example.ko創建了文件。

在那之後:

> sudo insmod lkm_example.ko
insmod: ERROR: could not insert module lkm_example.ko: Invalid module format

> dmesg
[200617.480635] lkm_example: no symbol version for module_layout
[200617.480656] lkm_example: loading out-of-tree module taints kernel.
[200617.481542] module: x86/modules: Skipping invalid relocation target, existing value is nonzero for type 1, loc 0000000074f1d70f, val ffffffffc0000158


> sudo modinfo lkm_example.ko
filename:       /home/<user>/containers-assembly-permissionsdemo/demo-2/lkm_example.ko
version:        0.01
description:    A simple example Linux module.
author:         Carlos Garcia
license:        GPL
srcversion:     F8B272146BAA2381B6332DE
depends:
retpoline:      Y
name:           lkm_example
vermagic:       4.19.84-microsoft-standard+ SMP mod_unload modversions

這是我的 Makefile

obj-m += lkm_example.o
all:
   make -C /home/<usr>/WSL2-Linux-Kernel M=$(PWD) modules
clean:
   make -C /home/<usr>/WSL2-Linux-Kernel M=$(PWD) clean
test:
   # We put a — in front of the rmmod command to tell make to ignore
   # an error in case the module isn’t loaded.
   -sudo rmmod lkm_example
   # Clear the kernel log without echo
   sudo dmesg -C
   # Insert the module
   sudo insmod lkm_example.ko
   # Display the kernel log
   dmesg
unload:
   sudo rm /dev/lkm_example
   sudo rmmod lkm_example

$$ Edit2 $$ 這是我的核心模組:

   #include <linux/init.h>
   #include <linux/module.h>
   #include <linux/kernel.h>
   #include <linux/fs.h>
   #include <asm/uaccess.h>
   #include <linux/init_task.h>
   
   MODULE_LICENSE("GPL");
   MODULE_AUTHOR("Carlos Garcia");
   MODULE_DESCRIPTION("A simple example Linux module.");
   MODULE_VERSION("0.01");
   
   /* Prototypes for device functions */
   static int device_open(struct inode *, struct file *);
   static int device_release(struct inode *, struct file *);
   static ssize_t device_read(struct file *, char *, size_t, loff_t *);
   static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
   static int major_num;
   static int device_open_count = 0;
   static char msg_buffer[MSG_BUFFER_LEN];
   static char *msg_ptr;
   
   /* This structure points to all of the device functions */
   static struct file_operations file_ops = {
       .read = device_read,
       .write = device_write,
       .open = device_open,
       .release = device_release
   };
   
   /* When a process reads from our device, this gets called. */
   static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset)
   {
    ...
   }
   
   /* Called when a process tries to write to our device */
   static ssize_t device_write(struct file *flip, const char *buffer, size_t len, loff_t *offset)
   {
      ...
   }
   
   /* Called when a process opens our device */
   static int device_open(struct inode *inode, struct file *file)
   {
       ...
       try_module_get(THIS_MODULE);
   
   }
   
   /* Called when a process closes our device */
   static int device_release(struct inode *inode, struct file *file)
   {
       ...
       module_put(THIS_MODULE);
   }
   
   static int __init lkm_example_init(void)
   {
       ...
       major_num = register_chrdev(0, "lkm_example", &file_ops);
       if (major_num < 0)
       {
           printk(KERN_ALERT "Could not register device: % d\n", major_num);
           return major_num;
       }
       else
       {
           printk(KERN_INFO "lkm_example module loaded with device major number % d\n", major_num);
           return 0;
       }
   }
   
   static void __exit lkm_example_exit(void)
   {
       /* Remember — we have to clean up after ourselves. Unregister the character device. */
       unregister_chrdev(major_num, DEVICE_NAME);
       printk(KERN_INFO "Goodbye, World !\n");
   }
   /* Register module functions */
   module_init(lkm_example_init);
   module_exit(lkm_example_exit);

我必須為作業做這個,所以我想我會在這里分享我的解決方案。

基本 WSL2 核心不允許載入模組。你必須編譯和使用你自己的核心版本。

如何在 WSL2 中編譯和使用核心

  1. sudo apt install build-essential flex bison libssl-dev libelf-dev git dwarves
  2. git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
  3. cd WSL2-Linux-Kernel
  4. cp Microsoft/config-wsl .config
  5. make -j $(expr $(nproc) - 1)
  6. 從 Windows 複製\\wsl$\DISTRO\home\USER\WSL2-Linux-Kernel\arch\x86\boot\bzimageC:\Users\WIN10_USER
  7. 創建C:\Users\WIN10_USER\.wslconfig包含以下內容的文件:
[wsl2]
kernel=C:\\Users\\WIN10_USER\\bzimage

注意:雙斜杠 (\) 是有意的。此外,為避免潛在的舊錯誤,請確保不要在任一行上留下任何尾隨空格。

  1. 在 PowerShell 中,執行wsl --shutdown
  2. 重新開啟你的 WSL2 風格

如何編譯模組

注意:您需要從 /home/USER/ 執行這些操作,或者調整 Makefile 以匹配您的位置。

  1. 創建一個Makefile包含:
obj-m:=lkm_example.o

all:
   make -C $(shell pwd)/WSL2-Linux-Kernel M=$(shell pwd) modules

clean:
   make -C $(shell pwd)/WSL2-Linux-Kernel M=$(shell pwd) clean
  1. make

.wslconfig 文件步驟的來源:https ://www.bleepingcomputer.com/news/microsoft/windows-10-wsl2-now-allows-you-to-configure-global-options/

引用自:https://unix.stackexchange.com/questions/594470