Linux核心分析之四 系統呼叫的工作機制

2021-07-10 15:09:39 字數 1727 閱讀 6054

《linux核心分析》mooc課程

學過計算機作業系統的都知道,cpu工作時有兩種狀態,一種是使用者態,一種是核心態,使用者態意味著**訪問的範圍會受到限制,在32位x86的機器上,4g的記憶體裡,在使用者態的時候,只能訪問0x00000000-0xbfffffff的位址空間。而核心態則不受限制,可以訪問任意記憶體位址。當程式在使用者態執行時,如果需要進入核心態執行,則會產生乙個中斷,然後系統進行中斷處理,先是儲存當前執行現場,將使用者態棧頂指標,狀態字,cs:eip值壓棧:

然後進行中斷處理程式,等處理程式執行結束後,則需要恢復現場:

當我們進行程式設計時,可以利用系統封裝好的api來間接進行呼叫系統呼叫。乙個api裡面可能對應乙個系統呼叫,也可能乙個也沒有,封裝例程會將系統呼叫封裝好,乙個例程往往對應乙個系統呼叫,當使用者程式在執行api(xyz())呼叫時,將會進入封裝例程(xyz())中,由封裝例程裡的中斷彙編**呼叫系統呼叫處理程式(system_call),然後系統呼叫處理程式呼叫系統呼叫服務程式(sys_xyz()):

這可以簡化為系統呼叫三層皮:api,中斷向量所指向的系統呼叫處理程式system_call,中斷服務程式sys_xyz()。

進行系統呼叫時,如跟函式呼叫一般,也需要進行引數傳遞。系統呼叫至少有乙個引數,就是系統呼叫號,通常會把它 傳入eax暫存器,其他引數則傳入其他暫存器,最多為6個引數,如果引數超過6個,則把最後乙個暫存器該為指向一塊剩餘引數記憶體的指標。

下面通過兩個程式來演示系統呼叫的工作機制:

程式一是直接呼叫sysinfo系統呼叫,返回系統資訊,程式二則通過彙編**呼叫系統呼叫,展示引數傳遞過程。

# include # include int

main(int argc, char *argv)

這是編譯執行後程式一的執行結果:

程式二:

# include # include int

main(int argc, char *argv)

編譯執行程式二的執行結果:

由程式二里彙編**:

asm volatile(

"mov %1, %%ebx\n\t"

"mov $0x74, %%eax\n\t"

"int $0x80\n\t"

"mov %%eax, %0\n\t"

: "=m" (error)

: "b" (info)

);

首先是把sysinfo系統呼叫的結構體指標引數傳入ebx暫存器,接著把系統呼叫號0x74傳入eax暫存器,接著進中斷int $0x80,最後把系統呼叫返回結果給error變數。可以看出,沒有程式一的sysinfo(info),程式二一樣成功呼叫系統呼叫sysinfo。

Linux核心分析四 系統呼叫

linux核心分析四 系統呼叫 本文是 linux核心分析 課程的第四次作業,作者劉洋為您奉上。本次課程分別通過c語言和組合語言實現同乙個系統呼叫,來理解linux系統呼叫。作業系統為在使用者態執行的程序與硬體設別之間進行互動提供了一組介面,這種分層的設計能夠帶來很多優點。首先,把使用者從底層硬體開...

linux核心之系統呼叫

應用程式與系統呼叫 使用者應用程式訪問並使用核心所提供的各種服務的途徑,就是系統呼叫,系統呼叫介面層作為核心和使用者應用程式之間的中間層,扮演了乙個橋梁,系統呼叫把應用程式的請求傳達給核心,核心處理完後,把結果返回給應用程式。應用程式通過作業系統提供的應用程式設計介面api而不是直接通過系統呼叫來程...

Linux核心之系統呼叫

linux核心之系統呼叫 1.應用程式通過api而不是直接呼叫系統呼叫來程式設計 2.getpid 系統呼叫示例 asmlinkage long sys getpid void asmlinkage 編譯器僅從棧中提取引數 系統呼叫的命名規則 sys syscallname 3.每個系統呼叫都對應乙...