1. 程式人生 > >2018-2019-1 20189213《Linux核心原理與分析》第六週作業

2018-2019-1 20189213《Linux核心原理與分析》第六週作業

系統呼叫的三層機制(下)

給MenuOS增加time和time_asm命令

首先是刪除menu目錄,並用git clone重新克隆一個新版本的menu:

進入menu,由於已經提供了一個指令碼rootfs,執行make rootfs指令碼就可以自動編譯並自動生成根檔案系統,並同時執行MenuOS系統:

在MenuOS系統中執行已經新增過的time和time-asm命令:

然後我們開啟menu目錄下的test.c檔案,找打定義的time函式和time-asm函式:

在main函式中對這兩個函式進行呼叫:

使用gdb跟蹤系統呼叫核心函式sys_getpid

由於上週做了三個系統呼叫的C語言實現方法,分別是getuid、getpid、rename,這裡我們進行對getpid的跟蹤除錯:
首先是在test.c中加入getpid:



然後儲存test.c,重新make rootfs,發現多了一個getpid的命令:


下面開始進行gdb除錯:
先返回LinuxKernel目錄,將核心載入進來:

首先在start_kernel函式處設定第一個斷點,然後繼續執行,到斷點處停:

由於getpid是20號系統呼叫,對應核心處理函式是sys_pid,於是我們在此處也設定斷點,然後執行結束:

但此時出現了問題,無法執行到sys_getpid斷點處停下。
原因應該是:C庫函式getpid()與核心處理函式sys_getpid存在衝突,導致無法執行到sys_getpid!

system_call的程式碼註釋:


注:
(1)sys_call_table(,%eax,4)的理解:因為分派表中的每個表項佔4個位元組,所以先把系統呼叫號(eax)乘以4,再加上 sys_call_table 分派表的起始地址,即是所呼叫的服務例程。
(2)GET_THREAD_INFO 巨集用於獲得當前程序的thread_info結構的地址,即獲取當前程序的資訊。
(3)syscall_exit_work 執行了一些程序排程、訊息傳遞的工作,如果進行了程序切換,可能要繼續觸發新的中斷,執行新的系統呼叫。

system_call流程示意圖:

總結

寫pid函式時一開始定義函式名為getpid,後來編譯發現出錯,然後改名為pid,編譯成功,估計是函式名getpid與20號系統呼叫getpid()存在衝突;