# 2025q1 Homework3 (kxo) contributed by < `Hlunlun` > ? {%hackmd NrmQUGbRQWemgwPfhzXj6g %} ## 開發中遇到的問題 1. 沒辦法把 module 放到 linux kernel 中 ```bash lun@lun-OMEN:~/linux2025/hw3/kxo$ sudo insmod kxo.ko [sudo] password for lun: insmod: ERROR: could not insert module kxo.ko: Key was rejected by service ``` - 分析:一開始以為是 `make` 後警告訊息的原因,然後就在更改 linux-headers 和 linux-image 的版本,結果完全不是,是因為有啟動 UEFI Secure Boot,這個安全標準會造成 kernel 模組需要簽名的安全金鑰才可以放到 kernel 中執行 (以下參考 [The Linux Kernel Module Programming Guide 第 1.7 章](https://sysprog21.github.io/lkmpg/#what-is-a-kernel-module)) >SecureBoot. Numerous modern computers arrive pre-configured with UEFI SecureBoot enabled—an essential security standard ensuring booting exclusively through trusted software endorsed by the original equipment manufacturer. Certain Linux distributions even ship with the default Linux kernel configured to support SecureBoot. In these cases, the kernel module necessitates a signed security key. - 解決:我是直接進去 Machine Owner Key (MOK) 的界面把 Secure Boot 禁用了,這樣最快 1. 以下指令是管理 UEFI Secure Boot 的命令,可以請求禁用 UEFI Secure Boot 的模組簽名驗證功能,它會叫你設置一組密碼,等等進入 MOK 會用到 ```bash sudo mokutil --disable-validation ``` 2. 然後重啟電腦 ```bash sudo reboot ``` 3. 會進入一個藍色的畫面,這就是 MOK,選擇 "Change Secure Boot state" 4. 然後選擇禁用 Secure Boot 驗證 5. 然後會要求你輸入剛才設置的密碼:是用問你密碼第幾個字元是什麼的方式教你輸入 ## 閱讀作業說明 ### Linux 核心的浮點數運算 1. kernel 中沒有浮點數的運算,所以要手動紀錄並在之後恢復,這在 kernel space 和 user space 轉換之間要注意 ### Monte Carlo Tree Search 理解 ## 閱讀教材 ### [你所不知道的 C 語言:數值系統篇](https://hackmd.io/@sysprog/c-prog/%2Fs%2FBkRKhQGae#%E4%BD%A0%E6%89%80%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84-C-%E8%AA%9E%E8%A8%80%EF%BC%9A%E6%95%B8%E5%80%BC%E7%B3%BB%E7%B5%B1%E7%AF%87) 1. balanced ternary - 不用像二進位數考慮 unsigned 和 signed - 小數點的運算會更簡單 - IOTA:過度效率 over engineering? 2. 數值表達 - 空集合是否屬於空集合? - 單精度浮點運算: 為什麼最後一個不是 `NaN` ? ```c #include<stdio.h> int main(){ printf("%f\n", 1e20*1e20*1e20); printf("%f\n", 1e20*(1e20*1e-20)); printf("%f\n", 1e20*(1e20-1e20)); printf("%f\n", 1e20*1e20-1e20*1e20); } //9999999999999949387135297074018866963645011013410073083904.000000 //100000000000000000000.000000 //0.000000 //0.000000 ``` - 為什麼要考慮浮點數符不符合結合律? - 浮點數不具結合性 $\to$ 所以要思考電腦有多少位元可以承載這些數值:如波音 787 造成 overflow 的案例 $\to$ 若是沒有考慮到這層會造成在不同電腦上有不同的答案 3. Integer Overflow - `int` 是否唯有號數取決於編譯器與硬體 - 潛在被攻擊的可能 4. 計算機編碼 - ARM 中的 `char` 是 unsigned,`char` 就是一種 integer - 補數的出現 $\to$ 不用考慮正負號和絕對值,只要找到補數就可將加法便減法,但會有循環進位的問題 - 1960 發生了很多事,發展了一補數(ones')、Linus 出生,ARPAnet(網路前身)也在那時使用了一補數編碼 - 二補數(two's):是封閉阿爾貝群 - side channel attack: 利用加解密的時間差(就是 [Dude, is my code constant time?](https://eprint.iacr.org/2016/1123.pdf) 提及的 timing leakage? ) - 5. ### [你所不知道的 C 語言: bitwise 操作](https://hackmd.io/@sysprog/c-prog/%2F%40sysprog%2Fc-bitwise#%E4%BD%A0%E6%89%80%E4%B8%8D%E7%9F%A5%E9%81%93%E7%9A%84-C-%E8%AA%9E%E8%A8%80-bitwise-%E6%93%8D%E4%BD%9C) 1. bloader: 只有相當小的資源,所以希望不要占用到太多記憶體的資源 **XOR swap** 就是一個很好的方式,可以不用用到額外的記憶體空間就可以交換兩個數 ```c 假設: x=5, y=3 x ^= y 1001 x ^0011 y ----- 1010 -> x y ^= x 0011 y ^1010 x ----- 1001 -> y x ^= y 1010 x ^1001 y ----- 0011 -> x 最後: x=3, y=5 ``` 2. 位移運算 - 左移超過變數長度時 ```c int i= 0xFFFFFFFF; i = i<<32; ``` - 右移一個負數時,可能是算術位移或是邏輯位移? >? 3. `sizeof` 是 operator,回傳 `unsigned` 的數值 4. 做中學,不用背 - Set bit: 將 `x` 的第 n 個位元設為 1,和第 n 個位元為 1 的值做 logical or - Clear bit: 將 `x` 的第 n 個位元設為 0,和第 n 個位元為 0 其他位元為 1 的值做 logcial and - Toggle bit: 將 `x` 的第 n 個位元若為 0 就改為 1 、若為 1 就改為 0,和第 n 個位元為 1 的值做 exclusize or - Test bit: 看 `x` 的第 n 個位元有沒有值,和第 n 個位元為 1 的值做 logcial and,結果是否大於 0 就是第 n 個位元有沒有值 - The right/left most byte: - Sign bit: 跟最高位元是 1 的值做 logical and 5. NEON -