久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Linux內(nèi)核設(shè)計(jì)與實(shí)現(xiàn)(6)

 clover_xian 2014-03-07

現(xiàn)代操作系統(tǒng)中,內(nèi)核提供了用戶進(jìn)程和內(nèi)核進(jìn)程交互的一組接口,,讓app可以受限的訪問硬件資源,,提供進(jìn)程間通信機(jī)制,實(shí)際上主要是為了保證系統(tǒng)穩(wěn)定可靠,,避免應(yīng)用程序do whatever they want.

1.與內(nèi)核通信

系統(tǒng)調(diào)用在用戶空間進(jìn)程和硬件設(shè)備之間添加了一個中間層,,主要作用:

①為用戶空間提供了一種硬件的抽象接口;

②保證了系統(tǒng)的穩(wěn)定和安全,,可以給予權(quán)限,,用戶對訪問進(jìn)行裁決;

③每個進(jìn)程都運(yùn)行在虛擬系統(tǒng)中,;

Linux中,,系統(tǒng)調(diào)用是用戶空間訪問內(nèi)核的唯一手段,;除異常和陷入外,是內(nèi)核唯一的合法入口,;實(shí)際上像設(shè)備文件和/proc之類的方式,也是通過系統(tǒng)調(diào)用進(jìn)行訪問的,。

 

2  API,、POSIX和C庫

應(yīng)用程序通過在用戶空間實(shí)現(xiàn)的應(yīng)用編程接口(API),而不是直接通過系統(tǒng)調(diào)用來編程,。

因?yàn)?span lang="EN-US">API實(shí)際上不需要和系統(tǒng)調(diào)用對應(yīng),,一個API可以實(shí)現(xiàn)成一個系統(tǒng)調(diào)用,也可以通過調(diào)用多個系統(tǒng)調(diào)用來實(shí)現(xiàn),,也可以完全不用,。POSIXAPI,、C庫及系統(tǒng)調(diào)用關(guān)系如下

程序員只跟API打交道,,內(nèi)核只跟系統(tǒng)調(diào)用打交道;即內(nèi)核提供機(jī)制,,API提供策略,。

C庫實(shí)現(xiàn)了大部分的POSIX標(biāo)準(zhǔn)API.

 

3.系統(tǒng)調(diào)用

系統(tǒng)調(diào)用一般用返回0來表示成功,返回負(fù)數(shù)表明錯誤,錯誤碼寫入errno全局變量,peeror()庫函數(shù)可以把錯誤碼轉(zhuǎn)變成錯誤字符串.

舉一例,獲取進(jìn)程ID號的系統(tǒng)調(diào)用getpid()

點(diǎn)擊(此處)折疊或打開

  1. asmlinkage long sys_getpid(void)
  2. {
  3.     return current->tgid;
  4. }

asmlinkage限定詞是編譯器指令,告知編譯器僅從堆棧中提取函數(shù)的參數(shù),;

②內(nèi)核返回long,,用戶空間返回int,是為了保證32/64位系統(tǒng)兼容,;

get_pid在內(nèi)核被定義為sys_getpid(),,內(nèi)核對系統(tǒng)調(diào)用都是如此定義的;

(1)系統(tǒng)調(diào)用號

Linux中,,每個系統(tǒng)調(diào)用號被賦予一個唯一的系統(tǒng)調(diào)用號,,進(jìn)程不會提及系統(tǒng)調(diào)用名稱,而是用系統(tǒng)調(diào)用號來關(guān)聯(lián)具體的系統(tǒng)調(diào)用,。

一個系統(tǒng)調(diào)用號一旦被分配,不能隨意變更,;用sys_ni_syscall()來補(bǔ)缺已經(jīng)刪除的調(diào)用號,;

系統(tǒng)調(diào)用號保持在unsigned long sys_call_table[NR_syscalls];

(2)系統(tǒng)調(diào)用的性能

Linux上下文切換時間很短,,進(jìn)出內(nèi)核都被優(yōu)化的簡潔高效;系統(tǒng)調(diào)用處理程序和每個系統(tǒng)調(diào)用本身都非常簡潔,,所以Linux系統(tǒng)調(diào)用比許多其他操作系統(tǒng)都執(zhí)行的快,。

(3)系統(tǒng)調(diào)用處理程序

通過軟中斷引發(fā)一個異常,促使系統(tǒng)切換到內(nèi)核態(tài),,執(zhí)行異常處理程序代碼,;這個異常處理程序就是系統(tǒng)調(diào)用處理程序system_call(),。

①找到指定的系統(tǒng)調(diào)用

X86上是通過eax把系統(tǒng)調(diào)用號傳給內(nèi)核,system_call()通過查找sys_call_table[]找到對應(yīng)的系統(tǒng)調(diào)用

②參數(shù)傳遞

Ebx,ecx,edx,esiedi依次存放前五個參數(shù),,若需要六個以上參數(shù),用單獨(dú)寄存器指向這些參數(shù)在用戶空間地址的指針,。通過eax存放返回值。

 

4.系統(tǒng)調(diào)用的實(shí)現(xiàn)

(1)決定用途,,每個系統(tǒng)調(diào)用功能應(yīng)該單一明確,不提倡多用途系統(tǒng)調(diào)用,。系統(tǒng)調(diào)用參數(shù),返回值和錯誤碼都要明確,,不要對機(jī)器字節(jié)長度和字節(jié)序做假設(shè),。

(2)參數(shù)驗(yàn)證:內(nèi)核必須保證

①指向用戶空間內(nèi)存的指針,,內(nèi)核不能直接訪問;

②指針指向的內(nèi)存在用戶進(jìn)程空間里,,內(nèi)核不能讀其他進(jìn)程空間;

③內(nèi)存不能繞過訪問限制:可讀內(nèi)存標(biāo)記為可讀,,可寫標(biāo)記為可寫,可執(zhí)行標(biāo)記為可執(zhí)行

內(nèi)核用copy_to_user()copy_from_user()來從用戶空間讀寫數(shù)據(jù),,都是把第二個參數(shù)指定位置數(shù)據(jù)傳送到第一個參數(shù)指定位置,長度由第三個參數(shù)決定,。執(zhí)行失敗,,返回未傳送字節(jié),成功返回0,。copy_to_user()copy_from_user()都可能引起休眠。

④檢查權(quán)能,,針對合法權(quán)限,比如if (!capable(CAP_SYS_BOOT))      return –EPERM;

(3)內(nèi)核執(zhí)行系統(tǒng)調(diào)用時處于進(jìn)程上下文,,current指針指向引發(fā)系統(tǒng)調(diào)用的那個進(jìn)程。能夠休眠,,所以系統(tǒng)調(diào)用必須是可重入的,。

(4)往系統(tǒng)添加一個系統(tǒng)調(diào)用的一個簡單實(shí)例

①添加系統(tǒng)調(diào)用名字函數(shù)名字sys_mytest,一般在calls.S或者entry.S

/* 320 */ .long       sys_get_mempolicy

              .long       sys_set_mempolicy

              .long   sys_mytest

②在unistd.h添加系統(tǒng)調(diào)用號,322

#define __NR_get_mempolicy             (__NR_SYSCALL_BASE+320)

#define __NR_set_mempolicy             (__NR_SYSCALL_BASE+321)

#define __NR_mytest                   (__NR_SYSCALL_BASE+322)

③實(shí)現(xiàn)系統(tǒng)調(diào)用函數(shù)

點(diǎn)擊(此處)折疊或打開

  1. asmlinkage long sys_mytest(struct testsys __user *buf)
  2. {
  3. #if 1
  4.     struct testsys pbuf_kernel;
  5.     copy_from_user(&pbuf_kernel,buf,sizeof(pbuf_kernel));
  6.     pbuf_kernel.cmd += 1;
  7.     pbuf_kernel.value += 2;
  8.     copy_to_user(buf,&pbuf_kernel,sizeof(pbuf_kernel));
  9. #endif
  10.     printk("---this is my test about sys_call!\r\n");
  11.     return 0;
  12. }

④在syscalls.h做系統(tǒng)調(diào)用函數(shù)聲明

點(diǎn)擊(此處)折疊或打開

  1. asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
  2.              unsigned long arg4, unsigned long arg5);
  3. asmlinkage long sys_mytest(struct testsys __user *buf);

app測試

點(diǎn)擊(此處)折疊或打開

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #define __NR_mytest 322
  6. struct testsys{
  7.         int cmd;
  8.         int value;
  9. };
  10. int main(void)
  11. {

  12.         struct testsys mysys;
  13.         mysys.cmd = 2;
  14.         mysys.value = 2;

  15.         //syscall(__NR_mytest);
  16.         syscall(322,&mysys);
  17.         printf("mysys.cmd:%d.\nmysys.value:%d\n",mysys.cmd,mysys.value);
  18.         return 0;
  19. }

測試結(jié)果:


5.添加系統(tǒng)調(diào)用

優(yōu)點(diǎn)有

①系統(tǒng)調(diào)用創(chuàng)建容易,且使用方便,;

Linux系統(tǒng)調(diào)用高性能顯而易見

缺點(diǎn)是:

①需要一個系統(tǒng)調(diào)用號,這個需要官方分配

②系統(tǒng)調(diào)用被加入穩(wěn)定內(nèi)核固化后,,接口不能改變,;

③需要將系統(tǒng)調(diào)用分別分配到各種體系結(jié)構(gòu)去(與硬件相關(guān))

④在腳本中不容易調(diào)用系統(tǒng)調(diào)用,也不能從文件系統(tǒng)直接訪問系統(tǒng)調(diào)用

⑤在主內(nèi)核樹之外很難維護(hù)

⑥如果只進(jìn)行簡單信息交換,,系統(tǒng)調(diào)用大材小用了,。所以盡管建立一個系統(tǒng)調(diào)用非常容易,但是不建議這么做,,替代方法:

①實(shí)現(xiàn)一個設(shè)備節(jié)點(diǎn),,并對此實(shí)現(xiàn)read()write(),,ioctl()來進(jìn)行操作

②像信號量這樣的某些接口,可以用文件描述符來表示

③把增加的信息作為一個文件放在sysfs的合適位置

 

Linux盡量使系統(tǒng)調(diào)用簡潔,,事實(shí)上Linux已經(jīng)是一個相對穩(wěn)定并且功能已經(jīng)較為完善的操作系統(tǒng),。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多