Linux 內核開發-筆記

操作系統課程作業要求,針對linux 2.6的內核(kernel)進行開發,詳細的要求和材料可以參照課程連接:

CS3 OPERATING SYSTEMS, PRACTICAL EXERCISE


PHASE 1 PHASE 2 主要爲如何在DICE機上使用VB和linux內核排程器(scheduler)的背景知識閱讀, PHASE 3 是正式的開發,課程評分也只參考這一環節,而這一環節也分爲三個小部分,簡單概括:1.簡單的編譯與載入、卸載內核模塊;2.解決SMP的Lost Wake-up問題;3.編寫一個副排程器以緩解CPU和I/O的速度衝突。


Part1:

首先將現成的.c文件編譯成.ko文件。

獲得ko文件後,比較常用的指令:

-insmod worker.ko 加載某一模塊

-lsmod 顯示當前運作的模塊

-rmmod worker 某一模塊


課程提供的worker.c編譯加載後會運行一個內核例程(kernel routine),每10秒輸出一條命令。在卸載時會調用clean_up函數,並在內核例程結束後,clean_up才結束。簡單修改worker.c,如加一點有個性化的輸入,形成worker1.c模塊,即可提交,30分到手。


Part2:

這次提供的是stuckworker.c,與worker.c不同的是,clean_up函數中,先指示例程結束,然後等了12秒,clean_up才進入sleep的狀態,此時已錯過了例程的wake_up,簡單概括就是一個lost wake-up Problem,在UP中不會出現,但在SMP中有可能出現並造成嚴重的問題。也不難,課程提供的一個提示是使用wait_even函數,避免了沒人喚醒的問題。


Part3:

這一部分挑戰最大,主要解決CPU運行速度和I/O運行速度不一致的問題。在讀取外設的時候大量的系統資源會被佔用,要求開發一個內核,使得在有鍵盤活動時,讀取外設的進程暫停60秒。其中濾出這些佔用資源過多的原則是:


1.進程內核運行時間是否大於1秒;

2.進程內核運行時間是否超過總運行時間10%;


struct task_struct *p;

for_each_process(p){

if(cputime_to_secs(p->stime)>limit_time_in_kernel/*此處爲1秒*/){//進程內核運行時間
ktime_get_ts(&c_t);//獲取當前時間
s_t=(c_t.tv_sec)-(p->start_time.tv_sec);//獲取運行時間
if(cputime_to_secs(p->stime)*limit_for_occupy_time/*此處爲10*/>s_t){...}//判斷進程內核運行時間是否超過總運行時間10%

}



若滿足以上兩個原則,則暫停進程60秒。尋找這個進程可能不難,但是如何停止,然後恢復卻不那麼容易,有很多種看似可行的辦法。Julian多次發羣郵提醒,別想複雜,不用從底層去做,不用通過設置位去完成,從userspace就可以完成。一般而言,在terminal暫停一個進程的指令是kill,那麼kill在內核裏對應調用的函數爲:send_sig(SIGSTOP,,);,相應的恢復運行函數爲send_sig(SIGCONT,,);,但在這裏內核出了一點小差錯,原因尚不明瞭,可以用kill_pid(task_pid(p, SIGCONT, 1);代替。僅僅這兩句代碼的正確選擇,耗費掉了整個作業的大概80%以上時間。完成正常的停止與恢復後,其他一些附加的小功能也就水到渠成了。


很值得一提的是,OS Lecturer Julian還自己開發了一個麻將遊戲!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章