1. 程式人生 > >用核心模組的方式為系統新增一個系統呼叫

用核心模組的方式為系統新增一個系統呼叫

今天,利用核心模組的方式向系統添加了一個核心模組。在make後,我開始sudo insmod hello.ko

完成之後。老是出現killed,在lsmod後,發現hello這個模組已經載入上去,但是測試函式呼叫的時候
,發現根本無法呼叫這個系統呼叫。在經過一番分析,查閱資料後,發現是Makefile檔案中少了一行
程式碼,新增上了這行程式碼後,執行成功。那麼,我就和大家分享一下這次的試驗。
那麼,我們先來了解一下,核心有單體核心和微核心之分。單體核心單體核心整個核心程式都是以
內執行。微核心本身只提供最基本的作業系統的功能,比如程序排程與訊息傳遞等,其他的功能由其
獨立的模組提供,每個獨立的功能模組都可以是一個程序。當我們需要使用某個功能的時候,我們只
需要在執行的作業系統裡安裝這個模組,並且執行對應服務,當這個功能不再需要的時候,我們可以
停止這個服務,這樣這個功能模組將不佔據系統記憶體和處理器的資源,而不會破壞當前的系統正常運
行。
接下來我們接下來就是我的利用核心模組新增系統呼叫的試驗過程了。首先是要編寫生成模組的代
系統呼叫函式是輸入自己的生日,如何出生日期為偶數返回完整的的年月日,否則為0。(下列系統調
用函式程式碼已省略)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <asm/uaccess.h>
#include <linux/sched.h>

#define my_syscall_num 223
//如下的這個值要到你機子上查。cat /proc/kallsyms | grep sys_call_table
#define sys_call_table_adress 0xc1511160
unsigned int clear_and_return_cr0(void); void setback_cr0(unsigned int val); asmlinkage long sys_mycall(void); int orig_cr0; unsigned long *sys_call_table = 0; static int (*anything_saved)(void); unsigned int clear_and_return_cr0(void) { unsigned int cr0 = 0; unsigned int ret; asm("movl %%cr0, %%eax"
:"=a"(cr0)); ret = cr0; cr0 &= 0xfffeffff; asm("movl %%eax, %%cr0"::"a"(cr0)); return ret; } void setback_cr0(unsigned int val) //讀取val的值到eax暫存器,再將eax暫存器的值放入cr0中 { asm volatile("movl %%eax, %%cr0"::"a"(val)); } static int __init init_addsyscall(void) { printk("hello, kernel\n"); sys_call_table = (unsigned long *)sys_call_table_adress;//獲取系統呼叫服務首地址 anything_saved = (int(*)(void)) (sys_call_table[my_syscall_num]);//儲存原始系統呼叫的地址 orig_cr0 = clear_and_return_cr0();//設定cr0可更改 sys_call_table[my_syscall_num] = (unsigned long)&sys_mycall;//更改原始的系統呼叫服務地址 setback_cr0(orig_cr0);//設定為原始的只讀cr0 return 0; } //新增自己的系統呼叫函式 asmlinkage long sys_mycall(void) { //... //... //... } static void __exit exit_addsyscall(void) { //設定cr0中對sys_call_table的更改許可權。 orig_cr0 = clear_and_return_cr0();//設定cr0可更改 //恢復原有的中斷向量表中的函式指標的值。 sys_call_table[my_syscall_num] = (unsigned long)anything_saved; //恢復原有的cr0的值 setback_cr0(orig_cr0); printk("call exit \n"); } module_init(init_addsyscall); module_exit(exit_addsyscall); MODULE_LICENSE("GPL"); 然後接著編譯Makefile檔案 ![Makefi檔案](http://img.blog.csdn.net/20161203230607903) 之後執行了sudo insmod hello.ko,結果他給我顯示瞭如圖 ![這裡寫圖片描述](http://img.blog.csdn.net/20161203231748323)

但是我查看了一下lsmod,發現載入的模組卻正在執行中
這裡寫圖片描述
但是系統呼叫是是失敗的,沒有達到預期的返回值。於是在追求原因,發現在Makefile檔案下新增
這裡寫圖片描述
之後發現模組執行成功,且沒有出現killed情況,最終返回了預期的返回值