歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 讀薄《Linux 內核設計與實現》(3) - 系統調用

讀薄《Linux 內核設計與實現》(3) - 系統調用

日期:2017/3/1 11:45:45   编辑:關於Linux

本文主要講了以下問題:系統調用的概念、系統調用的實現原理與過程以及如何在 Linux 中增加一個系統調用。

0x00 系統調用的概念

系統調用是為了和用戶空間上的進程進行交互,內核提供的一組界面。

應用程序通過這組界面訪問硬件和其他操作系統資源

完成對硬件和資源的訪問控制

硬件設備的抽象(提供設備的獨立性)

0x01 系統調用簡介

I 常用系統調用

fork(), exec(), open(), read(), write(), close(),……

目前 Linux 系統調用 300 多個

II 應用程序及系統調用的層次關系

應用程序通過在用戶空間實現的 API 而不是直接通過系統調用來編程

例:調用 printf() 函數時,應用程序、C 庫和內核的關系:
應用程序調用 printf() -> C 庫中的 printf() -> C 庫中的 write() -> 內核中的 write() 系統調用

0x02 Linux 系統調用實現原理

I 相關概念

int 80H:軟中斷,通知內核的機制是靠軟中斷實現的,第128號中斷處理程序

IVT(Interrupt Vector Table):中斷向量表,包括所有中斷程序入口地址,它固定存放於內存中(實模式下應用)

IDT(Interrupt Descriptor Table):中斷描述符表,不固定內存位置,通過 IDTR 寄存器定位該表(保護模式下應用,int 80H 占據其中一項)

syscall table:系統調用表

系統調用號: 在 Linux 中,每個系統調用被賦予一個系統調用號,表示它在表中的編號

II 系統調用的加載

操作系統在加載時做的有關系統調用的加載:

int 80H 處理程序地址的加載:start_kernel()中的 trap_init()和 set_system_gate()

各系統調用處理程序的加載(entry.s)

III 系統調用過程(以 x86 為例)

首先,通過軟中斷陷入到 int 80h 中斷中,促使系統切換到內核態去執行異常處理程序(系統調用處理程序);之後,系統通過讀取 eax 寄存器的值來獲取系統調用號;之後,系統通過讀取寄存器來獲取傳遞的參數(ebx, ecx, edx, esi, edi)按照順序存放前五個參數,如果參數為6個或以上,則將其中一個寄存器的值指向內存空間;最後,執行相應系統調用代碼,完成系統調用

IV 系統調用的參數驗證

系統調用必須仔細檢查他們所有參數是否合法有效,如果用戶將不合法的參數傳遞給內核,那麼系統的安全和穩定將面臨極大考驗。

權限驗證:系統調用的調用者可以使用 capable() 函數來檢查是否有權能對制定的資源進行操作

指針合法性驗證:在接受一個用戶空間的指針之前,內核需要驗證:

指針指向的內存區域屬於用戶空間 指針指向的內存區域在進程的地址空間裡 如果是讀,該內存應被標記為可讀;如果是寫,該內存應被標記為可寫;如果是可執行,進程決不能繞過內存訪問限制

0x03 如何增加一個系統調用

增加系統調用函數(/kernel/sys.c)

把系統調用函數入口添加到 sys_call_table(entry.s)

添加系統調用號

0x04 系統調用的意義

它為用戶提供了一種硬件的抽象接口

在保證系統穩定和安全的前提下提供服務,避免應用程序恣意橫行

Copyright © Linux教程網 All Rights Reserved