1. 程式人生 > >linux 系統調用分析

linux 系統調用分析

linux內核 系統 eight study cal 課程 詳細 http api

本文為我學習孟寧老師的linux內核課程的總結,同時也作為課程學習的作業。

唐建,《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000

1、系統調用概述

  通常用戶空間是無法直接訪問內核空間的,但是有時候確實需要這樣做,於是就產生的系統調用,系統調用是操作系統對用戶空間提供的訪問內核空間的API。

  系統調用分為:系統調用API、封裝例程、系統調用處理程序、系統調用服務程序,其中系統調用處理程序和服務程序在內核空間。

API 1 系統調用例程1 處理程序1

API2 系統調用例程2 system_call 處理程序2

API3 系統調用例程3 處理程序3

…… …… ……

四者對應關系如上,多個API可能對應一個系統調用,一個API也可能對應對個系統調用,一個系統調用對應一個封裝例程。

2、系統調用流程

用戶態調用系統調用API時,調用到系統調用封裝例程,例程通過命令觸發一個軟終端(系統調用專用,中斷號:0x80),系統進入內核態,並走到

  system_call,可以認為這個就是此軟終端的中斷服務程序入口,然後通過傳遞過來的系統調用號來決定調用相應的系統調用服務程序。

3、詳細流程,及舉例

下面我通過跟蹤和模擬系統調用來展示整個流程。

  (1)/下圖是一個簡單的程序,裏面使用了open、read 這兩個最常用的系統調用。右邊是輸出結果。

技術分享圖片技術分享圖片

(2)、下面我們將API改成匯編,直接通過匯編來調用系統調用,進而分析系統調用的過程。

首先查看系統調用號到文件/arch/x86/syscalls/syscall_32.tbl 或者syscall_64.tbl 文件。如下圖,第四列就是對應的內核中的處理函數。

技術分享圖片

  技術分享圖片

上述代碼與前面的c代碼對比。第一部分是 open系統調用,第二部分是read 系統調用。

__asm__ __volatile__ (
"mov %1, %%ebx\n\t" ——將open需要的參數準備好,文件路徑
"mov %2, %%ecx\n\t" ——準備參數,文件打開權限
"mov $5,%%eax\n\t" ——系統調用號,open的系統調用號為5
"int $0x80\n\t" ——觸發中斷0X80
"mov %%eax, %0\n\t" ——系統調用返回了,將返回參數取出來。
:"=m"(fd)
:"p"(path), "c"(O_RDONLY)
);

__asm__ __volatile__ (
"mov %2, %%ecx\n\t" ——準備入參
"mov $3, %%eax\n\t" ——系統調用號
"int $0x80\n\t" ——觸發中斷
"mov %%eax, %0\n\t" ——取出返回值
:"=m"(n)
:"b"(fd),"p"(buf),"d"(20)
);

4、總結

(1)、 每個系統調用都對應一個系統調用號,而系統調用號就對應內核中的相應處理函數。

(2)、所有系統調用都是通過中斷0x80來觸發的。

(3)、使用系統調用時,通過eax 寄存器將系統調用號傳遞到內核,系統調用的入參通過ebx、ecx……依次傳遞到內核

(4)、和函數一樣,系統調用的返回值保存在eax中,所有要從eax中取出

linux 系統調用分析