系統呼叫的那些事兒

2021-06-04 02:08:36 字數 2752 閱讀 6304

**:

1.系統呼叫

我們知道,linux將整個虛擬位址空間劃分為兩部分:使用者空間和核心空間。並且規定,使用者空間不能直接訪問核心空間,而核心空間則可以訪問使用者空間。通過這樣的級別劃分,可以使得核心空間更加的穩定和安全。但是,當使用者程序必須訪問核心或使用某個核心函式時,就得使用系統呼叫(system call)。在linux中,系統呼叫是使用者空間訪問核心空間的唯一途徑。

系統呼叫是核心提供的一組函式介面,它使得使用者空間上執行的程序可以和核心之間進行互動。比如,使用者程序通過系統呼叫訪問硬體裝置或作業系統的某些資源等。系統呼叫如同核心空間和使用者空間的乙個傳話者。核心如同乙個高高在上的帝王,而使用者空間的程序則屬於級別很小的**。由於使用者程序資質太淺,當它需要得到核心的支援時,它並沒有權利直接上報核心,而只能通過系統呼叫這個傳話人來得到核心的支援。

具體的,使用者程式通過應用程式設計介面來使用系統呼叫,而系統呼叫則是在核心中通過核心函式來實現的。

2.應用程式設計介面

有時候,某些api所提供的功能會涉及到與核心空間進行互動。那麼,這類api內部會封裝系統呼叫。而不涉及與核心進行互動的api則不會封裝系統呼叫。也就是說,api和系統呼叫並沒有嚴格對應關係,乙個api可能恰好只對應乙個系統呼叫,比如read()api和read()系統呼叫;乙個api也可能由多個系統呼叫實現;有時候,乙個api的功能可能並不需要核心提供的服務,那麼此時這個api也就不需要任何的系統呼叫,比如abs()。另外,乙個系統呼叫可能還被多個不同的api內部呼叫。

對於程式設計者來說,系統呼叫和api都是一組函式,並無什麼兩樣;但是事實上,系統呼叫的實現是在核心完成的,api則是在函式庫中實現的。

api是使用者程式直接可以使用的函式介面,但如果每個作業系統都擁有只屬於自己的api,那麼應用程式的移植性將會很差。基於posix(portable operating system inte***ce)標準的api擁有很好的可移植性,它定義了一套posix相容標準,這使得按這個標準實現的api可以在各種版本的unix中使用。現如今,它也可以在除unix之外的作業系統中使用,比如linux,windows nt等。

3.函式庫

乙個.c檔案會經過預處理、編譯、彙編、鏈結四個步驟。在彙編階段,輸出的是.o檔案,即我們常說的目標檔案。目標檔案並不能直接執行,它需要鏈結器的再一次加工。鏈結器將所有的目標檔案集合在一起,加上庫檔案,最後才能得到可執行檔案。

函式庫完成了各種api函式的定義,只不過函式庫是二進位制的形式,我們不能直接去檢視這些api函式如何實現。這些api函式的宣告則散步在不同的標頭檔案中,比如我們常用(也許你並未感知我們頻繁的使用這個函式庫)的標準函式庫libc.so,在其中包含多個我們常用的函式定義,但是這些函式的宣告卻分布在stdio.h和string.h等標頭檔案中。

我們每次在鏈結程式時,都必須告訴鏈結器需要鏈結到那個庫中。只不過通常預設的鏈結讓我們忽視了這一點。

比如,乙個簡單的helloworld程式中,僅使用了stdio.h標頭檔案。我們當然可以這樣輕鬆的編譯:gcc helloworld.c -o helloworld。之所以可以毫無顧忌是因為stdio.h中所宣告的函式都定義在libc.so中,而對於這個函式庫,聯結器是默然鏈結的。

如果我們編譯如下程式:

01#include < stdio.h >

02#include < math.h >

03intmain()

04

按照我們以往的編譯方法顯然是不行的:

1edsionte@edsionte-desktop:~$ gcc test.o -o test

2test.o: in function `main':

3test.c:(.text+0x39): undefined reference to `sqrt'

4collect2: ld returned 1exitstatus

因為在這個程式中使用了math.h標頭檔案,而這個標頭檔案中宣告的函式sqrt()被定義在libm.so函式庫中。那麼,這個時候應該這樣編譯:gcc test.c -o test -lm。最後的-lm選項即告訴鏈結器需要加入libm.so函式庫。

上述一步到位的編譯方法似乎又無形中掩蓋了函式庫的加入時間。如果我們按照編譯程式的四個步驟依次處理相應檔案時,就可以發現只有到了最後的鏈結過程中才會出現上述錯誤資訊。也就是說,函式庫的加入是在鏈結部分。

4.系統命令

每乙個系統命令其實就是乙個可執行的程式,這些可執行程式的實現呼叫了某些系統呼叫。並且,這些可執行程式又分為普通使用者可使用的命令和管理員可使用的命令。根據上述分類,普通使用者可用的命令和管理可用的命令分別被存放於/bin和/sbin目錄下。

5.系統呼叫的服務例程

系統呼叫的實現是在核心中完成的,它通過封裝對應的核心函式(通常是以sys_開頭,再加上相應的系統呼叫名)來實現其代表的功能。核心函式和使用者空間中函式並無兩樣,只不過核心函式是在核心中實現。也就是說,使用者程式通過某個系統呼叫進入核心後,會接著去執行這個系統呼叫對應的核心函式。這個核心函式也稱為系統呼叫的服務例程。

由於核心函式是在核心中實現的,因此它必須符合核心程式設計的規則,比如函式名以sys_開始,函式定義時候需加asmlinkage識別符號等。

sockt套接字之系統呼叫的那些事兒

套接字的特性由三個屬性確定 域 domain 型別和協議。建立套接字 socket系統呼叫建立乙個套接字並返回乙個描述符,該描述符可以用來訪問套接字。套接字位址 每個套接字域都有其自己的位址格式。對於af unix域套接字來說,他的位址由結構sockaddr un來描述,該結構定義在標頭檔案sys ...

作業系統的那些事兒

作業系統 英語 operating system,簡稱os 是管理和控制計算機 硬體與軟體資源的 電腦程式,是直接執行在 裸機 上的最基本的系統軟體,任何其他軟體都必須在作業系統的支援下才能 執行。操 作系統是使用者和計算機的 介面,同時也是計算機硬體和其他軟體的介面。驅動程式 最底層的 直接控制和...

由系統想到的那些事兒

系統剛敲完,現在仍然不敢放鬆警惕,因為系統還沒有驗收,很害怕又像上乙個系統一樣被 驗收出一大堆的問題,心裡發虛,不知道 會怎麼驗收。現在正在進行整體除錯,發現了很多不足,還需要繼續改。現在的進度真慢的夠可以的了,大家在一起開會討論的時候就覺得很羞愧。做這個系統,怎麼說呢,讓我喜憂參半,更確切地說,應...