原始的系統呼叫是通過中斷向量80所代表的的中斷來實現:把系統呼叫號存到乙個暫存器 中,然後發出int 0x80。已經註冊號的中斷處理程式會檢測暫存器的內容,根據不同的系 統呼叫號, 提供具體的服務。中斷的處理過程分三步:a)保持暫存器的內容;b)呼叫中斷 處理程式進行處理;c)重新載入之前暫存器的內容,這個過程的開銷並不小,所以 int 0x80的方式,對系統的開銷有較大的影響。
後來,intel推出了兩個指令sysenter/sy***it(對於64位系統則是syscall/sysret指令) ,提供 「快速系統呼叫」的功能,幾年後,linux開始使用這兩個指令實現系統呼叫,並且 引入了vdso的機制。具體是怎麼使用的,可以參考sysenter based system call mechanism in linux 2.6。
vdso的大概過程:
核心使用sysenter等指令實現系統呼叫,這部分**中主要過程叫做 __kernel_vsyscall(封裝在乙個so中);使用vdso機制時,核心在初始化過程中,會拷貝這個so到乙個物理頁;核心在載入elf執行檔案時,會把這個物理頁對映到使用者空間,並且會將裡面的函式根 據型別設定到elf auxiliary vectors中,__kernel_vsyscall的位址就會設定到 at_sysinfo型別中;使用ldd檢視的話,可以看到elf檔案包含乙個叫做 linux-gate.so.1或者叫linux-vdso.so.1的共享庫。glibc中系統呼叫的核心命令是: enter_kernel call *%gs:sysinfo_offset經過複雜的定義宣告,最終呼叫的是elf auxiliary vectors中at_sysinfo型別的位址 ,也就是呼叫了__kernel_vsyscall
一般情況下,應用程式不直接使用系統呼叫,而是使用一些glibc封裝好的函式,不過核心 也提供了syscall()方法,讓應用程式可以直接發起乙個系統呼叫。
有一些系統呼叫,比如gettimeofday(),可能會被非常頻繁地呼叫,並且這些系統呼叫的 具體過程都類似,讀取乙個有核心維護的變數的值(比如時間),然後把該值返回到使用者 空間。對於這些系統呼叫,核心提供了一種「捷徑」,使這些系統呼叫事實上不進入核心空 間,而是在使用者空間執行。大概的原理就是在vdso的虛擬動態共享庫檔案中維護了乙個變 量,該變數是由核心更新的,vdso中只是簡單地讀取這個變數並返回給呼叫方,而無需再 進行sysenter等指令。
系統呼叫原理
系統呼叫 系統呼叫是應用程式和作業系統核心的介面,無論程式是直接進行系統呼叫還是通過執行庫,最終還是會到達系統呼叫層面上。之所以要系統呼叫,是因為現在作業系統都將可能產生衝突的系統資源給保護起來,組織應用程式直接訪問。這些系統資源包括檔案 網路 io 各種裝置等。所有的這些操作都必須經由作業系統所規...
系統呼叫原理
以fork 為例 int main fork fork 是乙個對系統呼叫fork的封裝,可用下列巨集來定義 syscall0 pit t,fork syscall0是乙個巨集函式,i386版本定義如下 define syscall0 type,name type name void long res...
系統呼叫的實現原理
計算機系統的各種硬體資源是有限的,在現代多工作業系統上同時執行的多個程序都需要訪問這些資源,為了更好的管理這些資源程序是不允許直接操作的,所有對這些資源的訪問都必須有作業系統控制。也就是說作業系統是使用這些資源的唯一入口,而這個入口就是作業系統提供的系統呼叫 system call 系統呼叫是屬於作...