# 2024q1 Homework6 (integration) contributed by < [han1018](https://github.com/Han1018) > ## 自我檢查清單 - [x] 實體電腦安裝 GNU/Linux - [x] 閱讀〈[Linux 核心模組運作原理](https://hackmd.io/@sysprog/linux-kernel-module)〉並對照 Linux 核心原始程式碼 (v6.1+),解釋 `insmod` 後,Linux 核心模組的符號 (symbol) 如何被 Linux 核心找到 (使用 List API)、`MODULE_LICENSE` 巨集指定的授權條款又對核心有什麼影響 (GPL 與否對於可用的符號列表有關),以及藉由 [strace](https://man7.org/linux/man-pages/man1/strace.1.html) 追蹤 Linux 核心的掛載,涉及哪些系統呼叫和子系統? - Linux 核心模組的符號 (symbol) 如何被 Linux 核心找到 ? 當使用 gcc 編譯後,根據巨集定義,系統將會在初始化模組時調用 `init_module`,並將我們指定的 `module_init` 函式插入其中。為了讓系統在調用 `init_module` 時直接調用我們自定義的函式,我們可以使用一些技巧。`init_module` 是一個系統呼叫,它將 ELF image 載入至核心空間。在系統上,當系統呼叫 `finit_module` 後會呼叫 `load_module`,load_module 會為載入的模組配置記憶體並進行初始化。這個模組的初始化函式即為核心模組的 `init_function`,也就是我們自定義的函式。 - MODULE_LICENSE 巨集指定的授權條款又對核心有什麼影響? 參照 [include/linux/module.h](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/module.h) 說明,授權 licence 為免費使用的有 `GPL`、`GPL v2`、`GPL and additional rights`、`Dual BSD/GPL`、`Dual MIT/GPL`、`GPL`、`Dual MPL/GPL`。非免費使用的有 `Proprietary`。 需要對 module 定義一個 licence 否則系統會出現以下警告: `loading out-of-tree module taints kernel. module license 'unspecified' taints kernel.` - strace 追蹤 Linux 核心的掛載,涉及哪些系統呼叫和子系統? 使用 strace 追從 `insmod fibdrv.ko` 後發現其依序使用以下系統呼叫: - `execv` : 指定要執行的新程式 - `brk(null)` : 藉由指定空間結束的地址,調整程式資料空間 (data segement) 的大小。 :::info 設定 `null` 不確定表示其意思 ::: - `arch_prctl` : 設定行程/執行緒的狀態 - `mmap/munmap` 放置/取消 program 至記憶體。需要給定起始位置、空間大小等 - `access` : 確認行程可以存取指定的檔案,除了確認使否存在此檔案外也確認有讀取權限 - `openat` : 打開檔案並且回傳 `file descriptor` - `newfstatat` : 取得檔案狀態 - `close` : 關閉 `file descriptor`,使其無法存取指向的檔案 - `read` : 讀取 fd 的 bytes 至 `buffer` - `pread` 依據給定 `offset` 存取 fd 位移後的 bytes 至 `buffer` - `set_tid_address` : 設定行程執行緒 id 的地址。 - `mprotect` : 設定指定地址區間的記憶體保護屬性,讀/寫/執行/禁止訪問等。 - `prlimit64` : 取得資源限制,CPU 時間、記憶體等 - `fcntl` : 操作 `file descriptor`,有複製、設定 fd, 設定/取得 `lock` 等。 - `lseek` : 修改檔案 offset - `exit_group` : 結束行程裡所有的執行緒 - [x] 閱讀《[The Linux Kernel Module Programming Guide](https://sysprog21.github.io/lkmpg/)》(LKMPG) 並解釋 [simrupt](https://github.com/sysprog21/simrupt) 程式碼裡頭的 mutex lock 的使用方式,並探討能否改寫為 [lock-free](https://hackmd.io/@sysprog/concurrency-lockfree); 分為兩種鎖,一個是生產消費者鎖,一個是 read 鎖。consumer 和 producer 在 simrupt_work_func 裡使用,每一次只允許一個 worker 進入 mutex lock 讀或寫 buffer,遇到第二個 worker 進入讀/寫區域時,後存取的會進入睡眠狀態。read_lock 是負責將 Critical section 裡 kfifo buffer 的內容傳至 userspace。 這邊用的 lock 是 mutex_lock_interruptible 如果等待時有按下 ctrl + c 會返回 -ERESTARTSYS。