《Linux内核分析》 第四节 扒开系统调用的三层皮(上)
黃胤凱 ? 原創(chuàng)作品轉(zhuǎn)載請注明出處 ? 《Linux內(nèi)核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000
一、視頻學(xué)習(xí)
1.系統(tǒng)調(diào)用的三層皮:xyz ? ?system_call ? ?sys_xyz
對應(yīng)的是API,中斷向量對應(yīng)的中斷服務(wù)程序,系統(tǒng)調(diào)用服務(wù)程序。
?
API:應(yīng)用編程接口 ? ? ? ? ? ?
它與系統(tǒng)調(diào)用的關(guān)系:API可能直接提供用戶態(tài)的服務(wù),不是一個API都有與之相對應(yīng)的系統(tǒng)調(diào)用。
?
2.中斷處理,用戶態(tài)及內(nèi)核態(tài)
通過cs:eip的值判斷代碼段是在用戶態(tài)還是內(nèi)核態(tài)
中斷處理是一種由用戶態(tài)進(jìn)入內(nèi)核態(tài)的方式(系統(tǒng)調(diào)用也可以理解為是一種中斷)
中斷發(fā)生后,首先要保存現(xiàn)場,將數(shù)值壓棧,保存到相應(yīng)的寄存器中,然后響應(yīng)中斷,將數(shù)值彈棧,恢復(fù)現(xiàn)場。
?
?
二、使用庫函數(shù)API和C代碼中嵌入?yún)R編代碼兩種方式使用同一個系統(tǒng)調(diào)用
-
實驗報告
-
選擇一個系統(tǒng)調(diào)用(13號系統(tǒng)調(diào)用time除外),系統(tǒng)調(diào)用列表參見http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl 參考視頻中的方式使用庫函數(shù)API和C代碼中嵌入?yún)R編代碼兩種方式使用同一個系統(tǒng)調(diào)用
-
博客內(nèi)容的具體要求如下:
-
題目自擬,內(nèi)容圍繞系統(tǒng)調(diào)用的工作機(jī)制進(jìn)行,博客中需要使用實驗截圖
-
博客內(nèi)容中需要仔細(xì)分析匯編代碼調(diào)用系統(tǒng)調(diào)用的工作過程,特別是參數(shù)的傳遞的方式等。
- 總結(jié)部分需要闡明自己對“系統(tǒng)調(diào)用的工作機(jī)制”的理解。
?
- 本次實驗選擇了2號調(diào)用fork調(diào)用來做實驗:fork函數(shù)執(zhí)行完畢后,如果創(chuàng)建新進(jìn)程成功,則出現(xiàn)兩個進(jìn)程,一個是子進(jìn)程,一個是父進(jìn)程。在子進(jìn)程中,fork函數(shù)返回0,在父進(jìn)程中,fork返回新創(chuàng)建子進(jìn)程的進(jìn)程ID
用實驗樓的虛擬機(jī)打開shell
Cd Code Vi forktest.c Gcc forktest.c -o forktest.o -m32 ./forktest.ofork.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; }?
運(yùn)行結(jié)果見截圖
- 嵌入式匯編代碼的執(zhí)行,fork-asm.c源代碼如下(參數(shù)的傳遞方式見注釋):
?
#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的系統(tǒng)調(diào)用號0x2賦值給eax"int $0x80\n\t" // 通過0x80中斷向量,執(zhí)行系統(tǒng)調(diào)用"mov %%eax, %0\n\t" // 系統(tǒng)返回的pid號默認(rèn)儲存在eax中: "=m" (fpid) // 輸出操作數(shù)0為內(nèi)存中的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; }
運(yùn)行結(jié)果見截圖
?
轉(zhuǎn)載于:https://www.cnblogs.com/20132109HKK/p/5295680.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的《Linux内核分析》 第四节 扒开系统调用的三层皮(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MariaDB 条件语句WHERE
- 下一篇: Linux自动化安装cobbler