# 2024q1 Homework6 (integration) contributed by < `otteryc` > ## 實驗環境 ```shell $ uname -r 6.5.0-28-generic $ gcc --version gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 Copyright (C) 2021 Free Software Foundation, Inc $ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Address sizes: 39 bits physical, 48 bits virtual Byte Order: Little Endian CPU(s): 8 On-line CPU(s) list: 0-7 Vendor ID: GenuineIntel Model name: Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz CPU family: 6 Model: 158 Thread(s) per core: 2 Core(s) per socket: 4 Socket(s): 1 Stepping: 9 CPU max MHz: 4500.0000 CPU min MHz: 800.0000 BogoMIPS: 8400.00 ``` 另外,在進行開發時,由於編譯核心模組需要 `linux-header`, clangd 沒有辦法自動找到對應的 include path 以及編譯參數,可以透過 [Bear](https://github.com/rizsotto/Bear) 來解決,並且在 .clangd 檔案中,加入以下敘述,即可抑制 clangd 產生不正確的警告或錯誤。 ```yaml CompileFlags: Add: -Wno-unknown-warning-option Remove: [-m*, -f*] ``` ## 開發紀錄 ### 閱讀 Linux 核心模組教材 #### The Simplest Module 根據 LKMPG ,以下是一個編譯核心模組的 Makefile: ```Makefile obj-m += hello-1.o PWD := $(CURDIR) all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean ``` 在這個例子中, `make` 會切換到對應版本的 header 目錄,並由該目錄下的 Makefile 接手編譯。 另外,在 [Real world Makefile](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/char/Makefile) 中有許多 `obj-y` 以及 `obj-m` 的宣告,根據 [Linux Makfile documentation](https://docs.kernel.org/kbuild/makefiles.html),宣告為 `obj-y` 的模組會被編入 vmlinux ,而 `obj-m` 則會編成 loadable module 。 ```Makefile # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the # directory of external module to build. Setting M= takes precedence. ifeq ("$(origin M)", "command line") KBUILD_EXTMOD := $(M) endif ``` ### ksort: 處理並行排序的核心模組 在上述開發環境進行 `make check` 的時候,會出現以下錯誤: ```c ./include/linux/export.h:29:22: error: passing argument 1 of ‘class_create’ from incompatible pointer type [-Werror=incompatible-pointer-types] 29 | #define THIS_MODULE (&__this_module) | ~^~~~~~~~~~~~~~~ | | | struct module * /home/otteryc/linux2024/ksort/sort_mod.c:96:26: note: in expansion of macro ‘THIS_MODULE’ 96 | class = class_create(THIS_MODULE, DEVICE_NAME); | ^~~~~~~~~~~ ``` 原因是在 Linux 核心在 [commit 1aaba11](https://github.com/torvalds/linux/commit/1aaba11da9aa7d7d6b52a74d45b31cac118295a1) 後, `create_create` API 的傳入參數刪除了 module pointer ,所以編譯時會發生函式宣告與呼叫不一致的錯誤。對此,有依不同核心版本,調整 API 呼叫的必要,已經提出 [Pull Request](https://github.com/sysprog21/ksort/pull/1) 並獲接受。 :::info :question: 在閱讀 sort_mod.c 的過程中,發現在 `sort_read` 函式內,第 65 、 66 行的 early-return 可能有造成 `sort_buffer` 所指向的記憶體空間發生記憶體洩漏的疑慮。但是 User Mode Linux 似乎不能搭配 Valgrind 進行分析,不知道除了重編 Kernel 並選取 KMEMLEAK 工具以外,有沒有不需要重新編譯 Kernel 的方式? ::: ### simrupt: 整合井字遊戲對弈