contributed by < StevenChen8759
>
linux2020
calc.ko
在啟動時會向 Kernel 註冊裝置,可在 /dev
資料夾下找到裝置 calc
,透過檔案裝置讀寫的方式實作運算式輸入與結果輸出,可在 main.c
中找到相關操作函式的實作。calc.ko
整合了 expression.[ch]
,基於 Marco Defined Vector 提供運算式剖析與運算式計算功能,在 main.c
中的 calc()
函式可找到相對應的函式呼叫。nop()
函式上採用了 Livepatching
的技巧,在 main.c
中會預設呼叫 user_func_fib()
函式,在 Livepatching 模組插入核心後,將會改成呼叫 livepatch_nop()
函式,如此即可在不卸載 calc.ko
核心模組的情況下,達成抽換 callback 的功能。main.c
中仿照 nop()
相關函式的宣告,在 main.c
中實作使用者函式 fib()
的呼叫介面。user_funcs
中,包含了使用者定義函式的名稱與 callback 等資訊,在函式 calc()
中會一併將此參數輸入 expression.[ch]
的函式 expr_create()
中,並回傳包含使用者定義函式 fib()
的運算式剖析器。在剖析器產生後,呼叫 expr_eval()
函式,以求得輸入函式的結果。livepatch-calc.c
中,我們同樣仿照 nop()
的 livepatching 的相關函式,宣告 fib()
的 livepatching 介面。expression.[ch]
中,數值的表示方式採用了 MathEX 自定義的浮點數型別,在此採用 int
型別儲存,LSB 4 bit 存放 exponent,剩下 28 bit 則存放 mantissa,因此在 Livepatching 端的 fib()
函式會將已轉換的數值還原成整數,再導入 fibdrv
中,基於 Fast Doubling
方法的費氏數列計算函式 fibn()
計算出費氏數後,再轉換成自定義的浮點數型別並回傳之。expression.[ch]
中的函式GET_NUM
、GET_FRAC
以及 FP2INT
在 livepatching-calc.ko
編譯時並未連接 expression.o
,因此會跳出 Symbol NOT Found
的警告,並在嘗試 insmod
時失敗,在此暫時以我們自行在 Livepatching 中定義的函式取代之 (應有更佳的做法),參考以下的實作:MathEx
中會造成計算錯誤部分的改善fib()
函式輸入空值進行 vec_pop()
造成記憶體存取錯誤,原因是未檢查 vector 內的元素數量而使程式存取到非法的記憶體位址。我們將 livepatch-calc.c
中 livepatch_fib()
函式內實現的元素數量檢查部分移除,並在程式測試時輸入空的參數 fib()
函式內,即可重現此錯誤:malloc()
時的記憶體檢查方式,在進行 vec_pop()
時,皆須檢查對應 Vector 的 len
值是否為0,如此即可避免錯誤的記憶體存取kcalc
作業說明,Linux Kernel 的 CFS (Completely Fair Scheduler) 使用了定點數的技巧。linux/include/linux/sched.h
,可發現 Linux Kernel 中的定點數使用了 10 bits 作為小數,並使用剩餘位元表示整數。linux/kernel/sched/fair.c
中也使用了定點數的技巧,參考以下的說明: