精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux中的系統調用是怎樣實現

jf_78858299 ? 來源:碼農的荒島求生 ? 作者:碼農的荒島求生 ? 2023-02-15 11:40 ? 次閱讀

那么在今天的文章中我們從理論來到現實,看看Linux中的系統調用是怎樣實現的。

首先我們先來簡單復習下之前講解過的知識。

系統調用和普通的函數調用沒有本質區別,普通的函數調用一般調用的是我們自己編寫的函數或者其它庫函數,而系統調用調用的則是內核中的函數,更學術一點的說法是這樣的,所謂系統調用是指用戶態程序請求操作系統提供的服務。

一提到服務,大家最先想到的一定是服務器,假設客戶端是瀏覽器,瀏覽器發送http請求,服務器接收到請求后進行解析然后調用相應的hander, 從本質上講就是客戶端觸發了服務器端的某個函數的運行 ,這時我們說客戶端請求了服務器端上的服務。

而系統調用與此類似,只不過用戶態程序并不是通過http觸發了操作系統中某個函數的運行,而是通過機器指令來觸發的,因為用戶態的App和操作系統運行在同一臺計算機系統上,而客戶端和服務器端運行在不同的計算機系統中(絕大部分情況下),因此客戶端只能通過網絡協議http來與服務器進行通信

圖片

更通俗的說法就是所謂系統調用是指用戶態的某個函數調用內核中的某個函數。

接下來我們用一段簡單的hello world程序看下系統調用,這段程序需要運行在x86_64下:

.datamsg:    .ascii "Hello, world!\\n"    len = . - msg.text    .global _start_start:    movq  $1, %rax    movq  $1, %rdi    movq  $msg, %rsi    movq  $len, %rdxsyscall    movq  $60, %rax    xorq  %rdi, %rdisyscall

使用以下命令編譯:

$ gcc -c test.S$ ld -o test test.o

然后執行:

./testHello, world!

這段匯編代碼成功的打印出了hello world,這段代碼是什么意思呢?

注意看.data這一段,這里說的是程序定義了哪些數據,.text段是說程序中包含了哪些執行,我們之前提到進程的內存布局時總是說數據段以及代碼段,這里的數據段指的就是匯編中的.data段、代碼段指的就是匯編中的.text段,現在你應該明白了吧。

圖片

在.text段我們看到了一條略顯奇怪的指令,syscall,這條指令是什么意思呢?

我們來翻看一下intel的開發手冊:

SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.)

這段話告訴我們intel處理器在執行syscall指令時會在內核態調用操作系統的某個函數,即syscall-call handler,這個過程就是所謂的系統調用,我們知道CPU執行某個函數時必須知道某個函數在內存中的地址,那么CPU是怎么知道某個syscall-call handler的內存地址呢?

原來syscall-call handler所在的內存地址存儲在寄存器MSR中,那么又是誰將這個地址存儲在了寄存器MSR中呢?很顯然是操作系統,接下來以Linux為例來講解。

Linux內核初始化時將syscall-call handler也就是Linux內核中entry_SYSCALL_64函數的地址寫入寄存器MSR中:

wrmsrl(MSR_LSTAR, entry_SYSCALL_64);

其中syscall-call handler也就是entry_SYSCALL_64定義在了Linux源碼中的arch/x86/entry/entry_64.S,上述初始化寄存器MSR的代碼定義在了arch/x86/kernel/cpu/common.c。

現在我們知道了,當CPU執行syscall時會無腦跳轉到寄存器MSR中保存的函數地址,也就是entry_SYSCALL_64函數,那么很顯然的,所有系統調用的入口都是entry_SYSCALL_64函數,那么操作系統該怎么區分到底是調用的read系統調用還是write等系統調用?

原來,操作系統中給每種系統調用分配了一個序號,就像Linux中這樣:

0  common  read      sys_read
1  common  write      sys_write
2  common  open      sys_open
3  common  close      sys_close
4  common  stat      sys_newstat
5  common  fstat      sys_newfstat
6  common  lstat      sys_newlstat
7  common  poll      sys_poll
8  common  lseek      sys_lseek
9  common  mmap      sys_mmap
...

可以看到,0號系統調用表示的是內核中的read函數,1號系統調用表示的內核中的write函數,在進行系統調用時會將表示系統調用類別的序號寫入通用寄存器中。

從上面這個表格中可以看到write系統調用的序號是1,因此在hello world程序中我們將1寫入寄存器rax中:

movq  $1, %rax

這條指令就表示我們將要調用第1號系統調用,也就是sys_write,hello world程序中后續三條機器指令的函數是:

# 寫入文件描述符1
movq  $1, %rdi


# 保存指向字符串的指針
movq  $msg, %rsi


# 寫入數據的大小
movq  $len, %rdx

實際上這四條機器指令都是為執行syscall進行的鋪墊,也就是執行syscall所需要的參數,可以看到我們進行系統調用傳遞參數時都是通過寄存器來完成的。

這樣當CPU執行syscall執行時就會跳轉到Linux內核中的write函數,同時在執行該函數時也能知道write函數所需要的參數是什么。

好啦,這篇就到這里,最后,我準備開通知識星球啦,我會把所有文章中留下的問題總結在這里,同時也鼓勵大家在這里輸出自己的深度、系統性的思考,沉淀出屬于自己的知識。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11123

    瀏覽量

    207886
  • 函數
    +關注

    關注

    3

    文章

    4234

    瀏覽量

    61961
  • 系統調用
    +關注

    關注

    0

    文章

    27

    瀏覽量

    8309
收藏 人收藏

    評論

    相關推薦

    Linux系統調用實現與應用

    在計算機科學系統調用(System Call)是一種操作系統提供的服務,它允許應用程序通過軟件中斷的方式訪問操作系統內核
    發表于 06-14 11:46 ?451次閱讀

    Linux內核系統調用詳解

    Linux內核設置了一組用于實現各種系統功能的子程序,稱為系統調用。用戶可以通過
    發表于 08-23 10:37 ?715次閱讀
    <b class='flag-5'>Linux</b>內核<b class='flag-5'>中</b><b class='flag-5'>系統</b><b class='flag-5'>調用</b>詳解

    ARM Linux系統調用是如何實現的呢

    和執行程序。Unix系統通過向內核發出系統調用(system call)實現了用戶態進程和硬件設備之間的大部分接口。系統
    發表于 05-06 10:42

    ARM linux系統調用實現原理

    大家都知道linux的應用程序要想訪問內核必須使用系統調用從而實現從usr模式轉到svc模式。下面咱們看看它的實現過程。
    發表于 05-30 11:24 ?2219次閱讀

    基于linux系統實現的vivado調用VCS仿真教程

    VCS-MX的版本,可以混合編譯Verilog和VHDL語言 由于在linux系統個人用戶各種權限被限制,導致很多地方無法正常使用軟件之間的協調工作。 為了以防萬一,在此以個人用戶去實現
    的頭像 發表于 07-05 03:30 ?1.1w次閱讀
    基于<b class='flag-5'>linux</b><b class='flag-5'>系統</b><b class='flag-5'>實現</b>的vivado<b class='flag-5'>調用</b>VCS仿真教程

    透了解系統調用助你成為Linux下編程高手

    Linux內核設置了一組用于實現各種系統功能的子程序,稱為系統調用。用戶可以通過
    的頭像 發表于 05-11 11:27 ?3354次閱讀
    透了解<b class='flag-5'>系統</b><b class='flag-5'>調用</b>助你成為<b class='flag-5'>Linux</b>下編程高手

    你知道Linux系統調用的原理

    系統調用是應用程序與操作系統內核之間的接口,它決定了程序如何與內核打交道的。無論程序是直接進行系統調用,還是通過運行庫,最終還是會到達
    發表于 05-16 16:21 ?1417次閱讀
    你知道<b class='flag-5'>Linux</b><b class='flag-5'>系統</b><b class='flag-5'>調用</b>的原理

    Linux系統調用的技巧

    1.linux系統調用的基本原理  linux系統調用形式與POSIX兼容,也
    發表于 04-02 14:36 ?358次閱讀

    Linux系統調用是什么

    所謂系統調用是指操作系統提供給用戶程序調用的一組“特殊”接口,用戶程序可以通過這組“特殊”接口獲得操作系統內核提供的服務。例如,用戶可以通過
    發表于 06-11 09:33 ?2290次閱讀

    系統調用是如何實現的?

    這張圖畫了挺久的,主要是想讓大家可以從全局角度,看下linux內核系統調用實現。 在講具體的細節之前,我們先根據上圖,從整體上看一下
    的頭像 發表于 02-20 16:46 ?3854次閱讀
    <b class='flag-5'>系統</b><b class='flag-5'>調用是</b>如何<b class='flag-5'>實現</b>的?

    關于Linux內核系統調用是如何實現的與結果

    在執行 entry_SYSCALL_64 函數時,內核代碼會根據約定,先從rax寄存器獲取想要執行的系統調用的編號,然后根據該編號從sys_call_table數組中找到對應的系統
    的頭像 發表于 03-19 10:52 ?1493次閱讀

    如何區分xenomai、linux系統調用/服務

    對于同一個POSIX接口應用程序,可能既需要xenomai內核提供服務(xenomai 系統調用),又需要調用linux內核提供服務(linux
    的頭像 發表于 05-10 10:28 ?1911次閱讀

    Linux內核系統調用概述及實現原理

    本文介紹了系統調用的一些實現細節。首先分析了系統調用的意義,它們與庫函數和應用程序接口(API)有怎樣
    的頭像 發表于 05-14 14:11 ?2099次閱讀
    <b class='flag-5'>Linux</b>內核<b class='flag-5'>系統</b><b class='flag-5'>調用</b>概述及<b class='flag-5'>實現</b>原理

    Linux系統調用的具體實現原理

    文我將基于 ARM 體系結構角度,從 Linux 應用層例子到內核系統調用函數的整個過程來梳理一遍,講清楚linux系統
    的頭像 發表于 09-05 17:16 ?981次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>系統</b><b class='flag-5'>調用</b>的具體<b class='flag-5'>實現</b>原理

    Linux系統調用概述

    控制。也就是說操作系統是使用這些資源的唯一入口,而這個入口就是操作系統提供的系統調用(System Call)。在linux
    的頭像 發表于 11-09 10:27 ?450次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>系統</b><b class='flag-5'>調用</b>概述