# Linux 核心專題: 重作 kxo > 執行人: vicLin8712 ### Reviewed by `Hande1004` > 文中的 " 並且僅可 `r`ead。" 這裡應該是打錯字,請留意。 ### Reviewed by `h0w726` >fget 用於讀取 fp 的20個字元,注意到 C11 標準內提到 fget 僅會讀取到換行符號(或檔案結束)為止,並於最後保留 \0,也就是僅會讀取最多19個 bytes。 可以引用 C 語言規格書內容作為解釋。 ### Reviewed by `fcu-D0812998` >對 atomic_long_t 目的與功能不清楚 可以附上你針對 atomic_long_t 查找的資料,並在更詳細解釋你不懂的地方嗎? ## 任務簡述 重作 [kxo](https://hackmd.io/@sysprog/linux2025-kxo),務必完成所有指定任務,過程中可觀摩同學的成果並予以重現。要額外探討以下: (都該有原始程式碼分析和實驗解讀) * Linux workqueue 的目標/要解決什麼問題 * atomic operations in Linux kernel device driver * CMWQ 的設計目標,如何運用在 kxo * Linux tasklet 的作用是什麼?為何會被棄置?替代方案又是什麼?對 kxo 有何啟發? ## 重做 kxo 專案 ### Kxo `xo-user.c` 檔案分析 此檔案示範如何在 userspace 端與 kernel space 進行通訊,此檔案為 user space 端的程式碼。 ```C #define XO_STATUS_FILE "/sys/module/kxo/initstate" static bool status_check(void) { FILE *fp = fopen(XO_STATUS_FILE, "r"); if (!fp) { printf("kxo status : not loaded\n"); return false; } char read_buf[20]; fgets(read_buf, 20, fp); read_buf[strcspn(read_buf, "\n")] = 0; if (strcmp("live", read_buf)) { printf("kxo status : %s\n", read_buf); fclose(fp); return false; } fclose(fp); return true; } ``` `status_check` 用於檢測對應模組是否掛載。 `FILE` 結構體屬於 `<stdio.h>` ,此宣告意即將 `fp` 指向 `XO_STATUS_FILE`,並且僅可 `r`ead。 注意到其指向 `/sys/module/kxo/initstate`,為何不是 `dev` 等檔案系統? `/sys` 檔案系統主要用於暴露檔案資訊給存取者,而 `/dev` 用於存取硬體資訊,故而放置在 `/sys` 內部。另一個問題是裝置狀態儲存位置需要額外在核心模組寫入嗎? 查看`main.c:492 ret = device_create_file(kxo_dev, &dev_attr_kxo_state);` 發現其利用`linux devices` 所提供的 `device_create_file`,建立一個於 `sys` 的檔案用於儲存 `kxo_dev` 的狀態,當然前面需要先建立 `kxo_dev` 的物件(後續會討論到)。 `fget` 用於讀取 `fp` 的20個字元,注意到 C11 標準內提到 `fget` 僅會讀取到換行符號(或檔案結束)為止,並於最後保留 `\0`,也就是僅會讀取最多19個 bytes。問題是究竟 `fget` 所獲得的 bytes 會有何種形式?回顧到 `fp` 的創建,需回去查看核心模組的原始碼,後續再追蹤,在此先認為他會回傳某些用於判斷模組正常與否的資料。 `strcspn` 用於取出兩者字串一樣的位置,在此例也就是 `read_buf` 出現 `\n` 的位置,將其設置為 0 避免掉換行。 ```c static struct termios orig_termios; static void raw_mode_disable(void) { tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios); } static void raw_mode_enable(void) { tcgetattr(STDIN_FILENO, &orig_termios); atexit(raw_mode_disable); struct termios raw = orig_termios; raw.c_iflag &= ~IXON; raw.c_lflag &= ~(ECHO | ICANON); tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw); } ``` `termios` 查詢此結構體的使用,可參考 [termios(3) — Linux manual page](https://www.man7.org/linux/man-pages/man3/termios.3.html) ,此標頭檔提供用於控制終端機,terminal,所需的基本操作。 終端機在此專案中用以呈現下棋步驟,其中步驟由核心模組的演算法所決定。先查看 `raw_mode_enable` ,`tcgetattr` 取得 `STDIN_FILENO` 所對應的檔案描述符 (STDIN_FILENO 實際上 = 0),並將其賦予後者 `orig_termios`。 ### LINUX 核心的併行處理 閱讀材料: Linux 核心設計: 中斷處理和現代架構考量 ## Linux workqueue 的目標/要解決什麼問題 檢視 `workqueue.h` 程式碼 ```c struct delayed_work { struct work_struct work; struct timer_list timer; /* target workqueue and CPU ->timer uses to queue ->work */ struct workqueue_struct *wq; int cpu; }; ``` 發現結構體 `work_struct`、`timer_list`,以及`workqueue_struct`。查閱其對應的標頭檔以釐清內部元素,首先是宣告`work_struct` 結構體之標頭檔。對應程式碼如下 ```c struct work_struct { atomic_long_t data; struct list_head entry; work_func_t func; #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif }; ``` 對 `atomic_long_t` 目的與功能不清楚。 ## Atomic Operation in Linux Kernel Device Driver ### 目的