日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

第五章 系統調用

發布時間:2025/5/22 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第五章 系統調用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 系統調用的作用

  • 爲用戶空間提供了一種硬件的抽象接口。如Linux的“萬物皆文件”的思想,APP讀取文件不用關心磁盤或者文件系統的類型

  • 保證系統的穩定和安全。因爲內核是作爲Hardware跟APP之間的中間人,可以避免APP不正確地使用Hardware,竊取其他進程的資源,或其他危害系統的事情。

  • 實現多任務和虛擬內存的需要

2. 在Linux中,系統調用是除了異常和陷入之外,用戶空間訪問kernel的唯一手段。

3. 系統調用在出現錯誤的時候C庫會把錯誤碼寫入errno全局變量。通過調用perror()庫函數,可以把變量翻譯成用戶可以理解的錯誤字符串。

4. 在include/linux/syscalls.h中列出了一些列定義系統調用時用到的宏,如:

  • #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__)
  • #define SYSCALL_DEFINEx(x, sname, ...) \
  • SYSCALL_METADATA(sname, x, __VA_ARGS__) \
  • __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
  • 如open系統調用的定義 (fs/open.c中):

  • SYSCALL_DEFINE3(open,constchar __user *, filename,int, flags,umode_t, mode)
  • {
  • if(force_o_largefile())
  • flags |= O_LARGEFILE;
  • return do_sys_open(AT_FDCWD, filename, flags, mode);
  • }
  • 5. 在定義系統調用是會使用asmlinkage限定詞,目的是告訴編譯器僅從棧中提取該函數的參數。

    6. 每一個系統調用都被賦予一個系統調用號,獨一無二。用戶空間的進程執行系統調用時會將系統調用號傳遞給kernel,kernel據此判斷需要執行那個系統調用。

    在arm架構的kernel代碼,系統調用表如下,其中在表中的號就是系統調用號。

    ?

  • arch/arm/kernel/entry-common.S中:
  • .type sys_call_table,#object
  • ENTRY(sys_call_table)
  • #include "calls.S"
  • arch/arm/kernel/call.S中:
  • /*0*/ CALL(sys_restart_syscall)
  • CALL(sys_exit)
  • CALL(sys_fork)
  • CALL(sys_read)
  • CALL(sys_write)
  • /*5*/ CALL(sys_open)
  • CALL(sys_close)
  • CALL(sys_ni_syscall)/* was sys_waitpid */
  • CALL(sys_creat)
  • ......
  • 在arm64架構的kernel代碼中如下:

  • arch/arm64/kernel/sys.c中:
  • #undef __SYSCALL
  • #define __SYSCALL(nr, sym) [nr] = sym,
  • /*
  • *The sys_call_table array must be 4K aligned to be accessible from
  • * kernel/entry.S.
  • */
  • void *sys_call_table[__NR_syscalls] __aligned(4096)={
  • [0... __NR_syscalls -1]= sys_ni_syscall,
  • #include <asm/unistd.h>
  • };
  • arch/arm64/include/asm/unistd32.h中:
  • #define __NR_restart_syscall 0
  • __SYSCALL(__NR_restart_syscall, sys_restart_syscall)
  • #define __NR_exit 1
  • __SYSCALL(__NR_exit, sys_exit)
  • #define __NR_fork 2
  • __SYSCALL(__NR_fork, sys_fork)
  • #define __NR_read 3
  • __SYSCALL(__NR_read, sys_read)
  • #define __NR_write 4
  • __SYSCALL(__NR_write, sys_write)
  • #define __NR_open 5
  • __SYSCALL(__NR_open, compat_sys_open)
  • #define __NR_close 6
  • __SYSCALL(__NR_close, sys_close)
  • /*7 was sys_waitpid */
  • __SYSCALL(7, sys_ni_syscall)
  • #define __NR_creat 8
  • __SYSCALL(__NR_creat, sys_creat)
  • ......
  • 7. Linux內核通過軟中斷引發一個異常來促使系統切換到內核態去執行異常處理程序,在該異常處理程序中會或獲得用戶傳給的系統調用號和其他參數,根據系統調用號決定執行那個系統調用處理程序。對於arm架構是通過svc軟中斷指令實現的。

    8. copy_to_user()和copy_from_user()

    在內核空間接受一個用戶空間的指針的時候,需要做如下檢查:

    • 指針指向的內存區域屬於用戶空間

    • 指針指向額內存區域在進程的地址空間裏

    • 如果是讀,該內存應被標記爲可讀;?如果是寫,該內存應被標記爲可寫;?如果是可執行,該內存應被標記爲可執行;

    上述的兩個方法在完成了必須的檢查和內核空間和用戶空間之間數據拷貝?。需要注意的是返回值的含義:

    • 如果執行失敗,返回沒能完成拷貝的數據的字節數

    • 成功的話,返回0

    • 如果在檢查用戶空間指針合法性時出錯,返回 -EFAULT

    此外,當包含用戶數據的頁被換出到硬盤上而不是在物理內存上時,這個兩函數都會引起阻塞,此時進程會休眠,知道缺頁處理程序將頁從硬盤重新換回到物理內存。

    9. 內核執行系統調用的時候處於進程上下文,current指針指向當前任務,即引發系統調用的那個進程

    10. 在進程上下文,內核可以睡眠並且可以被搶佔。

    11. 必須保證系統調用是可衝入的。

    12. 下面是執行系統調用的連鎖反應:陷入內核,傳遞系統調用號和參數,執行正確的系統調用函數,並把返回值帶回到用戶空間

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?



    來自為知筆記(Wiz)



    總結

    以上是生活随笔為你收集整理的第五章 系統調用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。