linux系统调用理解之摘录(1)
寫在前面:出于對系統(tǒng)調(diào)用這一塊知識的疑惑,先從網(wǎng)上摘錄處一些經(jīng)典的講解。
操作系統(tǒng)負(fù)責(zé)資源管理,當(dāng)應(yīng)用層需要使用系統(tǒng)資源時(shí),就會向內(nèi)核發(fā)起系統(tǒng)調(diào)用。如:讀取文件時(shí)發(fā)起syscall_read系統(tǒng)調(diào)用;建立socket時(shí),發(fā)起syscall_socket系統(tǒng)調(diào)用等等;
(1)能夠觸發(fā)內(nèi)核響應(yīng)的三種操作:
內(nèi)核在完成引導(dǎo)后,就一直處于等待各種請求的狀態(tài),以便做出響應(yīng)從而實(shí)現(xiàn)對硬件資源的管理。
1.系統(tǒng)調(diào)用:基于軟件中斷機(jī)制(簡稱為“軟中斷”)實(shí)現(xiàn),應(yīng)用層對內(nèi)核層發(fā)起的請求;
2.異常:如缺頁異常,使虛擬地址分配到物理空間;
3.中斷:一般為硬件狀態(tài)改變引起內(nèi)核響應(yīng),如usb設(shè)備插入等;
本文主要介紹系統(tǒng)調(diào)用,它是由軟中斷實(shí)現(xiàn)的。
1.首先,用戶程序?yàn)橄到y(tǒng)調(diào)用設(shè)置參數(shù)。其中一個(gè)參數(shù)是系統(tǒng)調(diào)用編號;
2.參數(shù)設(shè)置完成后,程序執(zhí)行“系統(tǒng)調(diào)用”指令(這是一個(gè)特殊的機(jī)器指令);在x86平臺上的軟中斷是由int指令產(chǎn)生的。(不明白?);
3.系統(tǒng)調(diào)用指令會產(chǎn)生一個(gè)異常:產(chǎn)生一個(gè)事件,這個(gè)事件首先會導(dǎo)致處理器進(jìn)行狀態(tài)切換:用戶態(tài)——>系統(tǒng)態(tài)(或稱為內(nèi)核態(tài)),然后跳轉(zhuǎn)到一個(gè)新的地址執(zhí)行異常處理程序,這個(gè)程序就是“系統(tǒng)調(diào)用處理程序”。
(2)內(nèi)核空間中的實(shí)現(xiàn)
在linux中,每個(gè)系統(tǒng)調(diào)用都有一個(gè)對應(yīng)的系統(tǒng)調(diào)用號。
當(dāng)用戶程序的進(jìn)程執(zhí)行一個(gè)系統(tǒng)調(diào)用時(shí),這個(gè)系統(tǒng)調(diào)用號就是用來指明到底要執(zhí)行哪一個(gè)系統(tǒng)調(diào)用。
(2.2)所有系統(tǒng)調(diào)用陷入內(nèi)核的方式都是一樣的,所以僅僅是陷入內(nèi)核空間是不夠的。
因此必須將系統(tǒng)調(diào)用號一并傳給內(nèi)核。
在x86上,系統(tǒng)調(diào)用號是通過eax寄存器傳遞給內(nèi)核的。在陷入內(nèi)核之前,用戶空間就將系統(tǒng)調(diào)用號一并傳給eax中了。這樣系統(tǒng)調(diào)用處理程序一旦運(yùn)行,就可以從eax中得到數(shù)據(jù)。arm中也是類似操作。
(2.3)
除了系統(tǒng)調(diào)用號,一般系統(tǒng)調(diào)用還需要傳遞一些輸入?yún)?shù)。系統(tǒng)調(diào)用時(shí),也需要把這些參數(shù)傳遞給內(nèi)核。
最簡單的方式:如傳遞系統(tǒng)調(diào)用號一樣,將這些參數(shù)先存在寄存器中;x86上,ebx,ecx,edx,esi,edi按順序存放前五個(gè)外部輸入?yún)?shù)。
如果需要傳遞的參數(shù)多于六個(gè)時(shí),可以使用一個(gè)單獨(dú)的寄存器來指向存放所有這些參數(shù)在用戶空間地址的指針。
(2.4)
內(nèi)核記錄了系統(tǒng)調(diào)用表中的所有已注冊的系統(tǒng)調(diào)用,保存在sys_call_table中。
它與體系結(jié)構(gòu)有關(guān),一般在entry.s中定義。
它是一張由指向?qū)崿F(xiàn)各種系統(tǒng)調(diào)用的內(nèi)核函數(shù)的函數(shù)指針組成的表。
用戶空間的實(shí)現(xiàn):
linux下三種關(guān)系發(fā)生系統(tǒng)調(diào)用的方法:
1.通過glibc提供的庫函數(shù)
glibc是Linux下使用的開源的標(biāo)準(zhǔn)C庫,它是GNU發(fā)布的libc庫。glibc為程序員提供豐富的API,出了例如字符串處理,數(shù)學(xué)運(yùn)算等用戶服務(wù)外,最重要的是封裝了操作系統(tǒng)提供的系統(tǒng)服務(wù),即系統(tǒng)調(diào)用的封裝。
好處:封裝好的系統(tǒng)調(diào)用以API形成存在,容易理解,用戶不需要知道更多的內(nèi)部細(xì)節(jié),比如chmod系統(tǒng)調(diào)用,我們只需要知道它的作用,不需要知道它的內(nèi)部實(shí)現(xiàn)原理。
同時(shí),使用API形式的系統(tǒng)調(diào)用,具有更好的可移植性,glibc方便移植;即使采用的不是glibc的c函數(shù)庫,也只需要進(jìn)行少量的修改;
2.使用syscall直接調(diào)用
glibc中沒有進(jìn)行封裝的系統(tǒng)調(diào)用,比如用戶私自增加的一個(gè)系統(tǒng)調(diào)用,這時(shí)候就需要利用glibc提供過的syscall函數(shù)直接調(diào)用(值得深入研究)
3.通過int指令陷入
實(shí)際上,用戶程序通過軟中斷指令 int 0x80 來陷入內(nèi)核態(tài)(在Intel Pentium II中又引入了sysenter指令),參數(shù)的傳遞是通過寄存器,eax 傳遞的是系統(tǒng)調(diào)用號,ebx、ecx、edx、esi和edi 來依次傳遞最多五個(gè)參數(shù);
當(dāng)系統(tǒng)調(diào)用返回時(shí),返回值會存在eax中。
?
?
?
?
?
?
?
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的linux系统调用理解之摘录(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FTP服务器端口说明
- 下一篇: linux系统调用理解之摘录(2)