黃胤凱 ? 原創作品轉載請注明出處 ? 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000
一、視頻學習
1.系統調用的三層皮:xyz ? ?system_call ? ?sys_xyz
對應的是API,中斷向量對應的中斷服務程序,系統調用服務程序。
?
API:應用編程接口 ? ? ? ? ? ?
它與系統調用的關系:API可能直接提供用戶態的服務,不是一個API都有與之相對應的系統調用。
?
2.中斷處理,用戶態及內核態
通過cs:eip的值判斷代碼段是在用戶態還是內核態
中斷處理是一種由用戶態進入內核態的方式(系統調用也可以理解為是一種中斷)
中斷發生后,首先要保存現場,將數值壓棧,保存到相應的寄存器中,然后響應中斷,將數值彈棧,恢復現場。
?
?
二、使用庫函數API和C代碼中嵌入匯編代碼兩種方式使用同一個系統調用
-
實驗報告
-
選擇一個系統調用(13號系統調用time除外),系統調用列表參見http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl 參考視頻中的方式使用庫函數API和C代碼中嵌入匯編代碼兩種方式使用同一個系統調用
-
博客內容的具體要求如下:
-
題目自擬,內容圍繞系統調用的工作機制進行,博客中需要使用實驗截圖
-
博客內容中需要仔細分析匯編代碼調用系統調用的工作過程,特別是參數的傳遞的方式等。
- 總結部分需要闡明自己對“系統調用的工作機制”的理解。
-
?
- 本次實驗選擇了2號調用fork調用來做實驗:fork函數執行完畢后,如果創建新進程成功,則出現兩個進程,一個是子進程,一個是父進程。在子進程中,fork函數返回0,在父進程中,fork返回新創建子進程的進程ID
用實驗樓的虛擬機打開shell
Cd Code Vi forktest.c Gcc forktest.c -o forktest.o -m32 ./forktest.o
fork.c代碼如下
#include <unistd.h> #include <stdio.h> int main () {pid_t fpid;int count = 0;fpid = fork();if (fpid < 0)printf("error in fork!");else if (fpid == 0) {printf("i am the child process, my process id is %d\n",getpid());count++;}else {printf("i am the parent process, my process id is %d\n",getpid());count++;}printf("count: %d\n",count);return 0; }
?
運行結果見截圖
- 嵌入式匯編代碼的執行,fork-asm.c源代碼如下(參數的傳遞方式見注釋):
?
#include <unistd.h> #include <stdio.h> int main () {pid_t fpid;int count = 0;
asm volatile ("mov $0, %%ebx\n\t" "mov $0x2, %%eax\n\t" // 將fork的系統調用號0x2賦值給eax"int $0x80\n\t" // 通過0x80中斷向量,執行系統調用"mov %%eax, %0\n\t" // 系統返回的pid號默認儲存在eax中: "=m" (fpid) // 輸出操作數0為內存中的fpid。);
if (fpid < 0) printf("error in fork!"); else if (fpid == 0) { printf("i am the child process, my process id is %d\n",getpid()); count++; } else { printf("i am the parent process, my process id is %d\n",getpid()); count++; } printf("count: %d\n",count); return 0; }
運行結果見截圖
?