1. 程式人生 > >Linux | 系統呼叫System Calls

Linux | 系統呼叫System Calls

1 Linux作業系統體系結構

這裡寫圖片描述

可以把這張圖想象成一個三維的:

最下面的底盤是硬體平臺(Hardware Platform),上面有兩大層:核心區(Kernel Space) 和 使用者區(User space)

其中核心區還有分層

2 系統呼叫的“社會”關係

作業系統為使用者態程序硬體及核心資源進行 互動提供的一組介面

系統呼叫可被看成是一個核心使用者空間程式 互動的介面

可以說承上啟下

【作用】

  • 極大的提高了系統的安全性
  • 使使用者程式具有可移植性

系統呼叫和應用程式程式設計介面(API)

Linux的應用程式設計介面(API)遵循 POSIX標準(一種作業系統介面標準)

C Library to System Call

這裡寫圖片描述

系統呼叫與系統命令

系統命令相對API,更高一層,每個系統命令都是一個可執行程式。

系統命令的實現呼叫了系統呼叫

系統呼叫與核心函式

核心函式在形式上與普通函式一樣,但它是在核心實現的,需要滿足一些核心程式設計的要求

系統呼叫是使用者程序進入核心的介面層,由核心函式實現的

進入核心後,不同的系統呼叫會找到各自對應的核心函式,這些核心函式被稱為系統呼叫的“服務例程”(後面會經常用到這個概念)

3 系統呼叫時的核心棧

這裡寫圖片描述

在之前日誌曾討論過為什麼切換核心態會耗費時間,其中提到程式會有兩個棧,棧切換有費時。

為了把系統呼叫號與相應 的服務例程關聯起來,核心利用了一個系統呼叫表。

這個表存放在 sys_call_table陣列中,有 NR_syscalls個表項

當用戶態程序呼叫一個系統呼叫時,CPU切換到 核心態並開始執行一個核心函式

核心實現了很多不同的系統呼叫,程序必須傳遞 一個名為系統呼叫號的引數來指明需要呼叫的系 統呼叫,eax暫存器就用作這個目的

引數傳遞
系統呼叫也需要輸入輸出引數

  • 實際的值
  • 使用者態程序地址空間變數的地址

system_call是linux中所有系統呼叫的入口點,每個系統呼叫至少有一個引數,即eax傳遞的系統呼叫號

system_call

程式碼
/arch/x86/kernel/entry_32.S ENTRY(system_call)

  • system_call是用匯編語言寫的
  • 傳遞系統呼叫號和引數(eax , ebx, ecx, edx, esi, edi 存放參數)
  • 如果檢驗有效,則執行相應的系統呼叫處理程式 call *sys_call_table(, %eax , 4)

Linux-4.4.39定義了七個從SYSCALL_DEFINE0到 SYSCALL_DEFINE6的一組巨集,用於定義系統呼叫服務例程
<include/linux/syscalls.h>
X是系統呼叫引數的個數

#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) #define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) #define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) 

驗證引數
在核心打算滿足使用者的請求之前,必須仔細的檢查所有的系統呼叫引數
只要一個引數指定的是地址,那麼核心必須 檢查它是否在這個程序的地址空間之內,有兩種驗證方法:

  • 驗證這個線性地址是否屬於這個程序的地址空間
  • 如果是讀,該記憶體應被標記為可讀。如果是寫, 該記憶體應被標記為可寫。

傳遞返回值
所有的系統呼叫返回一個整數值。

  • 正數0表示系統呼叫成功結束
  • 負數表示一個出錯條件
    此時這個負值將要存放在errno變數中返回給應用程 序。核心沒有設定或使用errno變數,封裝例程在系 統呼叫返回取得返回值之後設定這個變數

服務例程的返回值是將會被寫入eax暫存器

4 系統呼叫過程

使用者態下呼叫C庫的庫函式,比如func():

  1. func()先做好引數傳遞工作,然後利用int 0x80指令產生一次異常
  2. CPU通過0x80號在IDT中找到對應的服務例程 system_call(),並呼叫之
  3. system_call()根據系統呼叫號索引系統呼叫表,找到系統呼叫程式入口,比如sys_func()
  4. sys_func()執行完後,經過ret_from_sys_call()例程返 回用戶程式

Linux只允許系統呼叫介面使用128這一個軟中斷向量。
這也意味著所有的系統呼叫介面必須共享這一中斷通道, 並在同一個中斷服務例程中呼叫不同的核心服務例程。
系統呼叫介面是通過呼叫軟中斷指令“int $0x80”使程序 從使用者態進入到核心態。

應用程式、封裝例程、系統呼叫中斷處理程式及系統呼叫服務例程之間的 關係
這裡寫圖片描述

相關推薦

Linux | 系統呼叫System Calls

1 Linux作業系統體系結構 可以把這張圖想象成一個三維的: 最下面的底盤是硬體平臺(Hardware Platform),上面有兩大層:核心區(Kernel Space) 和 使用者區(User space) 其中核心區還有分層 2 系統呼叫

arm linux 系統呼叫過程

在Linux下系統呼叫是用軟中斷實現的,下面以一個簡單的open例子簡要分析一下應用層的open是如何呼叫到核心中的sys_open的。 t8.c 1: #include <stdio.h> 2: #include <sys/types.h> 3:

一次性講明白Linux系統呼叫(1)

什麼是系統呼叫 Linux核心中設定了很多可以實現各種系統功能的子程式,這些子程式就叫系統呼叫。而系統呼叫和普通函式呼叫的區別主要是在系統呼叫是系統提供的,函式一般是函式庫或者自己提供的。 為什麼要用系統呼叫 其實很多我們平時用的C語言標準函式,在Linux

linux 系統呼叫 inotify & epoll

一、inotify 作用: 監控一個目錄下檔案的增加、刪除事件 1.重要的資料結構 // 發生的event結構 struct inotify_event {     __s32       wd;       &nb

linux 系統呼叫open 七日遊(二)

接著昨日的旅程,我們應該開始處理具體的子路徑了: 【fs/namei.c】 sys_open->do_sys_open->do_filp_open->path_openat->link_path_walk 點選(此處)摺疊或開啟 &n

linux系統呼叫open七日遊(一)

友情提示:您需要一個 kernel 3.15.6,下載地址: https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.15.6.tar.xz     我們將以 Linux 系統呼叫 open 為主線,參

Linux 系統呼叫 open 七日遊(七)

【場景三】open(pathname, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)     在這個場景中我們希望建立一個新檔案(O_CREAT),並賦予該檔案使用者可讀(S_IRUSR)和使用者可寫(S_IW

time, ctime, sleep, exit等Linux系統呼叫使用方法

作業系統實驗時候整理的一些知識點。有小錯請見諒哦。 (1)Linux中time命令是用來計算某個程式的執行耗時(real),使用者態cpu耗時(user),系統態cpu耗時(sys)。 (2)time命令最常用的使用方式就是在其後面直接跟上命令和引數:time <command>

Linux 環境程式設計——Linux系統呼叫

系統呼叫概述 系統呼叫,顧名思義,說的是作業系統提供給使用者程式呼叫的一組“特殊”介面。使用者程式可以通過這組“特殊”介面來獲得作業系統核心提供的服務,比如使用者可以通過檔案系統相關的呼叫請求系統開啟檔案、關閉檔案或讀寫檔案,可以通過時鐘相關的系統呼叫獲得系統時間或設定定時器等。 從邏輯上來說

linux系統呼叫SYSCALL_DEFINE

核心程式碼中系統呼叫都是:SYSCALL_DEFINEx 巨集,x表示引數個數。 這個巨集參考部落格: http://blog.csdn.net/hxmhyp/article/details/22699669 # 和 ## 使用參考部落格: http://www.linuxid

Linux系統呼叫--getrlimit()與setrlimit()

功能描述: 獲取或設定資源使用限制。每種資源都有相關的軟硬限制,軟限制是核心強加給相應資源的限制值,硬限制是軟限制的最大值。非授權呼叫程序只可以將其軟限制指定為0~硬限制範圍中的某個值,同時能不可逆轉地降低其硬限制。授權程序可以任意改變其軟硬限制。RLIM_INFINITY的值表示

linux系統呼叫原理及實現

linux系統呼叫 系統呼叫是linux核心為使用者態程式提供的主要功能介面。通過系統呼叫,使用者態程序能夠臨時切換到核心態,使用核心態才能訪問的硬體和資源完成特定功能。系統呼叫由linux核心和核心模組實現,核心在處理系統呼叫時還會檢查系統呼叫請求和引數是否正確,保證對特

Linux系統呼叫索引

本系列計劃把Linux的所有系統呼叫都扒一遍,詳細解釋每個系統呼叫的功能,用法,使用示例,應用場景和注意事項。 系統中支援的系統呼叫列表及編號都定義在 /usr/include/asm/unistd.h檔案下。 以下的列表來源於64位的CentOS 7系統,詳解連結後面會

Linux系統呼叫

一、系統呼叫概述   系統呼叫,顧名思義,說的是作業系統提供給使用者程式呼叫的一組“特殊”介面。使用者程式可以通過這組“特殊”介面來獲得作業系統核心提供的服務,比如使用者可以通過檔案系統相關的呼叫請求系統開啟檔案、關閉檔案或讀寫檔案,可以通過時鐘相關的系統呼叫獲

Linux系統呼叫的最終指南

1.概述 這篇部落格解釋了Linux程式如何呼叫Linux核心中的函式。 它將概述幾種進行系統呼叫的不同方法,如何手工製作自己的程式集來進行系統呼叫(包括示例),系統呼叫的核心入口點,系統呼叫的核心出口點,glibc包裝器,bug等等。 2.什麼是系統呼叫 當您執行一個呼叫了

linux 系統呼叫 inotify & epoll

一、inotify 作用: 監控一個目錄下檔案的增加、刪除事件 1.重要的資料結構 // 發生的event結構 struct inotify_event {     __s32       wd;         /* watch descriptor */     __u

Linux系統呼叫函式strdup

Name strdup, strndup, strdupa, strndupa - duplicate a string 複製一個字串 Synopsis #include <string.h> char *strdup(const char *s);

Linux系統呼叫IO

Linux 系統呼叫IO 開啟檔案: int open(const char* pathname,int flags); int open(const char *pathname,int flags,mode_t mode); 引數一:檔案路徑 引數二:開啟許

linux系統呼叫使用者態到核心態流程

Linux系統呼叫流程分析 一直很好奇系統呼叫的詳細過程,只簡單的瞭解系統呼叫是使用者與核心互動的藉口,看了幾天的內容,不知道從何下手開始寫,今天略有頭緒,做以簡單總結。 1,  什麼是系統呼叫。 系統呼叫:系統呼叫是作業系統為使用者提供的一系列API;系統呼叫將使用者的請

剖析Linux系統呼叫的執行路徑

在[什麼是作業系統](http://www.cnblogs.com/ronny/p/7787105.html)這篇文章中,介紹過作業系統像是一個代理一樣,為我們去管理計算機的眾多硬體,我們需要計算機的一些計算服務、資料管理的服務,都由作業系統提供**介面**來完成。這樣做的好處是讓一般的計算機使用者不用關心硬