先前遇到一個很懂system kernel的人, 突然想要看一下我之前在OSDI的筆記
赫然發現medium上竟然沒有, 好險之前有存在hackmd過
圖檔以全部失效, 也沒有留了
已經是5年前的筆記了, 參考價值應該非常低
在此註記
由於lab5太多東西,所以我分成兩次繼續寫
切記!!!! 可以參考,但是照抄真的很沒有意義,學不到東西也無法讓你帶著走,看著code回答不出來更尷尬
接下來我們要實作system call,相信大家都懂,就是透過轉換到kernel mode後,再去執行一些東西,再切回user mode,但在OS怎樣去實作的呢?這次LAB我猜想是USER先把system call number以及一些參數存進暫存器,再切換成kernel mode去做這些事,詳情參閱lib/syscall.c
首先我們先去改kernel/trap_entry.S,配置好中斷向量T_SYSCALL這個會對應到的function,然後去kernel/syscall.c去註冊這個function,以及寫好他之後對到的handler,這邊的動作在前面幾個lab都有做到,這邊我就不再多描述了
其實我很好奇,怎麼有這麼多個syscall.c lib裡一個, kernel裡也一個
查了一下資料原來是,lib裡的是kernel mode可以直接用的,至於user必須先透過中斷向量發出,告訴OS他要執行system call,這邊也是為何我們要去設置trap相關的code 之後會跳到kernel/syscall.c裡,(在中斷發生後,以切換成kernel mode 詳情請看trap_entry.S)之後會再跳去執行lib/syscall.c裡面的system call,如果很混亂建議拿張紙筆描繪一下,很快就能理解了
至於system call裡面的各項要怎樣填寫,根據提示應該不會太困難,這邊也先省略了
之後我們根據相關的需要的system call 去修改mem.c的 sys_get_num_free_page與sys_get_num_userd_page
只需要算一下free的page就好了
再來是timer handler的操作,根據提示我們需要去刷新正在睡覺的task以及正在執行的task,兩者的tick值都要降低,若sleep的task已經歸零,那我們就把他放回準備中的狀態,若執行中的task歸零,那我們就要scheduler看看有沒有要換人
由於這作業量真的蠻大的,筆者已經忘了還有哪邊會用到,如果有的話再去察看問題,以上大致應該完成了八成左右,最後最後要提到的就是排班(scheduling)
我們先看一下提示
很好,相信大家在恐龍本都體會過round-robin的精隨了,應該都很會算吧,小孩子都會的東西(??)但在要實作出來的今天,這真的讓我訝異到了,要考慮的東西,遠比想像中要多很多………
筆者在這邊,就沒有跟著提示走了,我總覺得有更簡單的方法,我們先透過一個無窮迴圈,裡面的內容 next指的是下一個task,若這task為目前的task(cur_task),在檢查一下他是否還在RUNNING,是的話就直接跳掉,這用意到底是什麼呢?
我慢慢說,我們通常會跑到這個時候,就代表這個時候要執行的task為目前的task(cur_task),但是,我們不知道是誰,驅動了這個sched,有兩種狀況,被迫的,執行到別的syscall,一種是,自己的tick已經歸零了,當然後者我們必須從給他tick,但前者不用,這也是為何為RUNNING我們就直接跳出繼續做就好的原因
完成後,利用forktest測試你的程式沒有問題,會像這樣
沒有跑出錯誤,就大功告成了!!
這邊觀念上有錯誤,或是有其他地方用錯字之類都可以回復給我,感謝大家收看