Linux核心增加系統調用

來源:互聯網
上載者:User

其實像這樣的文章網上一搜一大堆,又千篇一律,中國的網路世界就是這樣一個特點,今天我也沒有逃過這樣的“特點”,轉載確實讓我省了很多的文字輸入,但是千篇一律的錯誤也被轉載是我不能容忍的,實驗之後,將錯誤之處一一更正,希望錯誤不再被繼續轉...

1.linux 系統調用的基本原理

   linux的系統調用形式與POSIX相容,也是一套C語言函數名的集合。然而,linux系統調用的內部實現方式卻與DOC的INT 21H相似,它是經過INT 0X80H非強制中斷進入後,再根據系統調用號分門別類地服務。

從系統分析的角度,linux的系統調用涉及4個方面的問題。
(1)與系統調用有關的資料結構和函數
   函數名以“sys_”開頭,後跟該系統調用的名字。例如,系統調用fork()的響應函數是sys_fork()(見kernel/fork.c),exit()的響應函數是sys_exit()(見kernel/fork.c)。

  
檔案include/asm/unisted.h為每個系統調用規定了唯一的編號。假設用name表示系統調用的名稱,那麼系統調用號與系統調用響應函數
的關係是:以系統調用號_NR_name作為下標,可找出系統調用表sys_call_table(見arch/i386/kernel
/entry.S)中對應表項的內容,它正好 是該系統調用的響應函數sys_name的入口地址。系統調
用表sys_call_table記錄了各sys_name函數在表中的位 置,共190項。有了這張表,就很容易根據特定系統調用
在表中的位移量,找到對應的系統調用響應函數的入口地址。系統調用表共256項,餘下的項是可供使用者自己添加的系統調用空間。

(2)進程的系統調用命令轉換為INT 0x80中斷的過程
      
宏定義_syscallN()見include/asm/unisted.h)用於系統調用的格式轉換和參數的傳遞。N取0~5之間的整數。
參數個數為N的系統調用由_syscallN()負責格式轉換和參數傳遞。系統調用號放入EAX寄存器,啟動INT 0x80
後,規定傳回值送EAX寄存器。

(3)系統調用功能模組的初始化
   對系統調用的初始化也就是對INT
0x80的初始化。系統啟動時,彙編子程式setup_idt(見arch/i386/kernel/head.S)準備了1張256項的idt表,由
start_kernel()(見
init/main.c),trap_init()(見arch/i386/kernel/traps.c)調用的C語言宏定義
set_system_gate(0x80,&system_call)(見
include/asm/system.h)設定0x80號非強制中斷的服務程式為
system_call(見arch/i386/kernel/entry.S),system.call就是所有系統調用的總入口。

(4)核心如何為各種系統調用服務
       當進程需要進行系統調用時,必須以C語言函數的形式寫一句系統調用命令。該命令如果已在某個標頭檔
中由相應的_syscallN()展開,則使用者程式必須包含該文 件。當進程執行到使用者程式的系統調用命令時,實際上執
行了由宏命令_syscallN()展開的函數。系統調用的參數 由各通用寄存器傳遞,然後執行INT 0x80,以核心態進
入入口地址system_call。

(5)ret_from_sys_call
   以ret_from_sys_call入口的組譯工具段在linux進
程管理中起到了十分重要的作用。所有系統調用結束前以及大部分中斷服務返回前,都會跳轉至此處入口地址。 該段程式不僅僅為系統調用服務,它還處理中斷嵌套、CPU調度、訊號等事務。

2.通過修改核心原始碼添加系統調用

   通過以上分析linux系統調用的過程, 將自己的系統調用加到核心中就是一件容易的事情。下面介紹一個實際的系統調用,
並把它加到核心中去。要增加的系統調用是:inttestsyscall(),其功能是在控制終端螢幕上顯示hello world,
執行成功後返回0。
1編寫int testsyscall()系統調用
編寫一個系統調用意味著要給核心增加1個函數,將新函數放入檔案kernel/sys.c中。新函數代碼如下:
asmlingkage sys_testsyscall()
{  

console_print("hello world/n");
return 0;
}

2串連新的系統調用
編寫了新的系統調用過程後,下一項任務是使核心的其餘部分知道這一程式的存在,然後重建包含新的系統調用的核心。
為了把新的函數串連到已有的核心中去, 需要編輯2個檔案:

1).inculde/asm/unistd.h在這個檔案中加入
#define_NR_testsyscall 191

2).arch/x86/kernel/syscall_table_32.S 這個檔案用來對指標數組初始化,在這個檔案中增加一行:
.long SYMBOL_NAME(_sys_tsetsycall)
將.rept NR_syscalls-190 改為 NR_SYSCALLS-191,然後重新獎勵和運行新核心。

3).使用新的系統調用
在保證的C語言庫中沒有新的系統調用的程式段,必須自己建立其代碼如下


#inculde<linux/unistd.h>


#define_NR_testsyscall 191



_syscall0(int,testsyscall)
main()
{  
   tsetsyscall();
}
     
在這裡使用了_syscall0()巨集指令,巨集指令本身在程式中將擴充成名為syscall()的函數,它在main()函數內部加以調用。
在testsyscall()函數中, 預先處理程式產生所有必要的機器指令代碼,包括用系統調用參數值載入相應的cpu寄存器, 然後執行int
0x80中斷指令。

3.利用核心模組添加系統調用
  
   模組是核心的一部分,但是並沒有被編譯到核心裡面去。它們被分別編譯並串連成一組目標檔案,
這些檔案能被插入到正在啟動並執行核心,或者從正在啟動並執行核心中移走。核心模組至少必須有2個函數:int_module和cleanup_module。第
一個函數是在把模組插入核心時調用的; 第二個函數則在刪除該模組時調用。
   由於核心模組是核心的一部分,所以能訪問所有核心資源。根據對linux系統調用機制的分析,
如果要增加系統調用,可以編寫自己的函數來實現,然後在sys_call_table表中增加一項,使該項中的指標指向自己編寫的函數,
就可以實現系統調用。下面用該方法實現在控制終端上列印“hello world” 的系統調用testsyscall()。

1)編寫系統調用核心模組
#inculde(linux/kernel.h)
#inculde(linux/module.h)
#inculde(linux/modversions.h)
#inculde(linux/sched.h)
#inculde(asm/uaccess.h)
#define_NR_testsyscall 191
extern viod *sys_call+table[];
asmlinkage int testsyscall()
{

console_print("hello world/n");
return 0;
}
int init_module()
{

sys_call_table[_NR_tsetsyscall]=testsyscall;
printk("system call testsyscall() loaded success/n");
return 0;
}
void cleanup_module()
{


printk("system call testsyscall() unloaded success/n");



}

2)使用新的系統調用

#include <linux/unistd.h>
#define_NR_testsyscall 191
_syscall0(int,testsyscall)
main()
{
    testsyscall();
}

3)編譯核心模組並插入核心
       編譯核心的命令為:gcc -Wall -02 -DMODULE -D_KERNEL_-C syscall.c
   -Wall通知編譯器顯示警告資訊;參數-02 是關於代碼最佳化的設定, 核心模組必須最佳化;
參數-D_LERNEL通知標頭檔向核心模組提供正確的定義; 參數-D_KERNEL_通知標頭檔,
這個程式碼將在核心模式下運行。編譯成功後將產生 syscall.0檔案。最後使用insmod
syscall.o命令將模組插入核心後即可使用增加的系統調用。

    比較以上二種方法,筆者認為採用核心模組的方法較好。因為這種方法可省去編譯新核心並用新核心重新 啟動的麻煩,這一優點對於代碼的調試是非常有價值的, 可以節省大量時間。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.