Linux 2.4.18的linux/linkage.h文件定義了若干相關的宏
用ENTRY(name)就能定義函數了。后來發現Flux OSKit中本來就提供了類似功能的宏,定義在inc/asm.h中。使用的時候需要再寫一個c語言的wrapper function(至少2.4.18里面是這么做的)asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
Time : 2008-08-22 15:56OS Lab 4 debugging notes [1]系統調用 fork()
用Simics跟蹤一條條匯編分析頁表映射、寄存器值還真是體力活啊。。
1. 實現Copy On Write時,如果某一個用戶態頁面有多個進程共享,其中一個進程修改該頁面時需要創建一個新的頁面。一開始偶忘了把原來頁面的內容復制到新的頁面了 =_= 另外由于新的頁面要代替老的頁面,或者說它們的物理地址不同,但虛擬地址相同,我的方法是在內核態開辟一個大小為一個頁面的空間作為中轉。
2. do_fork函數中,子進程復制父進程的頁表的同時會把父進程頁表項置為不可寫,注意最后要flush tlb。因為一開始沒有flush tlb,導致最后用戶態fork返回以后讀取的信息來自于tlb,直接改寫了共享頁面中fork的返回地址,導致切換到子進程時fork的返回地址丟失。這個bug讓我郁悶了兩三個小時。。
3. 使用兩次fork時,第二次fork返回的pid會被改掉。查了下發現為用戶空間分配物理頁面的代碼里居然在分配好以后沒有把對應的struct置為已使用,結果導致第二個子進程COW創建新頁面時得到了原來的父進程頁面,改寫了父進程頁面內容。
1. 清空頁表的用戶空間映射的函數一開始寫得yts,bug到處都是,比如free的時候沒使用指向內存塊首地址的指針,記錄內存地址的變量沒有累加。
2. exec傳遞給內核態的兩個參數必須先在內核態保存一個副本,否則清空用戶態頁表后就無法得到這兩個參數信息了。
3. 分配給用戶態的頁面必須先清零,一方面考慮到安全性,另一方面不清零會隱藏一些潛在的bug。一開始我沒有在內核執行exec的時候完整的復制所有的參數,而是直接指向了原進程的內存空間,由于清空頁表后再次申請新頁表時得到了原來的頁面,結果正好原來那個保存參數的頁面和新進程的該頁面重合了 =_= 于是浪費了不少時間在這個bug上
Time : 2008-08-31 1:18OS Lab5 debugging notes還算順利,不過這個lab蠻無聊的,等有空了把syscall改成類似linux的做法,單一中斷號+寄存器選擇syscall。
1. 最花時間的一個bug是ls返回值沒有改成應用程序數,結果一開始一直以為是brk系統調用沒寫好,最后才發現問題出在這么小的地方。
2. brk的邏輯還不是很清楚,盡管通過了簡單的測試,但是debug輸出的信息顯示brk增長的很快,經常是一個頁一個頁漲的,看來還得查下brk的具體行為。
3. 寫了個比MAGIC_BREAK好用一點的宏,因為用戶態的程序都是按二進制讀入的,Simics無法得到函數信息(函數名、當前行數等),利用C99的宏寫了個新的INFO_BREAK
Powered by: BlogJava Copyright © ZelluX