linux體系結構
核心空間與使用者空間是程式執行的兩種不同狀態,通過系統呼叫和硬體中斷能夠完成從使用者空間到核心空間的轉移。如下圖所示:
linux 體系結構圖
從上圖得知,linux由使用者空間和核心空間
一般情況下,使用者程序是不能訪問核心的。它既不能訪問核心所在的記憶體空間,也不能呼叫核心中的函式。linux核心中設定了一組用於實現各種系統功能的子程式,使用者可以通過呼叫他們訪問linux核心的資料和函式,這些系統呼叫介面(sci)稱為系統呼叫。
系統呼叫和普通函式的區別:
系統呼叫和普通的函式呼叫非常相似,區別僅僅在於,系統呼叫由作業系統核心實現,執行於核心態;而普通的函式呼叫由函式庫或使用者自己提供,執行於使用者態。
系統呼叫數:
在2.6.32 版核心中,共有系統呼叫365個,可在arch/arm/include/asm/unistd.h中找到它們。
/*this file contains the system call numbers
*/#define __nr_restart_syscall (__nr_syscall_base+ 0)
#define __nr_exit (__nr_syscall_base+ 1)
#define __nr_fork (__nr_syscall_base+ 2)
......
#define __nr_preadv(__nr_syscall_base+361)
#define __nr_pwritev(__nr_syscall_base+362)
#define __nr_rt_tgsigqueueinfo(__nr_syscall_base+363)
#define __nr_perf_event_open(__nr_syscall_base+364)
系統呼叫的功能:
主要分為3大類:
(1)程序控制類
fork 建立乙個子程序
clone 按照指定條件建立子程序
execve 執行可執行檔案
...(2)檔案控制操作
fcntl 檔案控制
open 開啟檔案
read 讀檔案
...(3)系統控制
ioctl i/o總控制函式
reboot重新啟動
—sysctl讀寫系統引數
...使用系統呼叫函式舉例:
下面通過time函式系統呼叫實現從格林尼治時間2023年1月1日0:00開始到現在的秒數。
#include
main()
系統呼叫工作原理:
一般情況下,使用者程序是不能訪問核心的。它既不能訪問核心所在的記憶體空間,也不能呼叫核心中的函式。系
統呼叫是乙個例外。其原理是(1)程序先用適當的值填充暫存器,(2)然後呼叫乙個特殊的指令,(3)這個指令會讓使用者程式跳轉到乙個事先定義好的核心中的乙個位置。(4)
程序可以跳轉到的固定的核心位置。這個過程檢查系統呼叫號,這個號碼告訴核心程序請求哪種服務。然後,它檢視系統呼叫表(sys_call_table)找到所呼叫的核心函式入口位址。接著,就呼叫函式,等返回後,做一些系統檢查,最後返回到程序。
工作原理概述:
(1)適當的值
所有適當的值我們都可以在include/asm/unistd.h中找到,在這個檔案中為每乙個系統呼叫規定了唯一的編號,叫做系統呼叫號。
#define __nr_utimensat(__nr_syscall_base+348)
#define __nr_signalfd(__nr_syscall_base+349)
#define __nr_timerfd_create(__nr_syscall_base+350)
#define __nr_eventfd(__nr_syscall_base+351)
#define __nr_fallocate(__nr_syscall_base+352)
這裡面每乙個巨集就是乙個系統呼叫號
(2)特殊的指令
在intel cpu中,這個指令由中斷0x80實現
在arm中,這個指令是swi(softwhere interrupt:軟中斷指令),現在重新命名為svc
(3)固定的位置
每個cpu固定的位置是不一樣的,在arm體系中這個固定的核心位置是entry(vector_swi)(在arch\sh\kernel\entry-common.s),也就是pc指標會跳轉到這個位置
(4)相應的函式
核心根據應用程式傳遞來的系統呼叫號,從系統呼叫表sys_call_table找到相應的核心函式
call(sys_restart_syscall)
call(sys_exit)
例項:工作原理(應用):下面是乙個從使用者open呼叫到找到核心中具體的系統呼叫函式入口位址的大體流程
#define __syscall(name) "swi\t" __nr_##name "\n\t「
int open( const char * pathname, int flags)
轉化為int open( const char * pathname, int flags)
//核心入口
/* arch/arm/kernel/entry-common.s */
entry(vector_swi)
…… …… …… ……
adr tbl, sys_call_table @ load syscall table pointer
…… …… …… ……
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
…… …… …… ……
entry(sys_call_table)
#include "calls.s"
………………………………………………………………
call(sys_dup3)
call(sys_pipe2)
/* 360 */call(sys_inotify_init1)
linux 系統呼叫
使用者應用可以通過兩種方式使用系統呼叫。第一種方式是通過c庫函式,包括系統呼叫在c庫中的封裝函式和其他普通函式。圖5.2 使用系統呼叫的兩種方式 第二種方式是使用 syscall巨集。2.6.18版本之前的核心,在include asm i386 unistd.h檔案中定義有7個 syscall巨集...
Linux系統呼叫
一 實驗目的和要求 1.學習linux核心的配置和編譯 2.深入理解linux系統呼叫 3.理解arm和x86的cpu模式 系統模式 使用者模式 的不同 4.掌握核心模組的編寫方法。二 實驗器材 1.linux實驗板卡一塊 2.5v 1a電源乙個 3.microusb線一根 4.macos一台 5....
Linux系統呼叫
linux系統呼叫 系統呼叫 system call 是使用者空間訪問核心的唯一手段,除異常和陷入外,他們是核心唯一的合法入口。通常情況下應用程式是通過應用程式設計介面api來訪問函式,而不是直接使用系統呼叫來程式設計。作業系統通常是通過中斷從使用者態切換到核心態。中斷就是乙個硬體或軟體請求,要求c...