我是Linux Kernel新手,但是現在涉及到了修改調用的活,
趕鴨子上架了。通過看書和實踐,到也做出了簡單的東西,感謝
james_zhang和young_yang,寫出我的經歷,也算是一個入門過
程了。
首先我看了一本書《Linux 操作系統內核分析》(9711課本)。
沒有太詳細的閱讀,直接找到了系統調用的一章,和自己的代碼
一對比,發現不一樣!看來2.4.x和2.2.x還是有變化的。
然後請教了james_zhang和young_yang,堅定了信心,大體的
原理不會變,結構不會變。
連上了Google。搜索“編寫系統調用”,夠裸吧!
找到了幾個網頁,打開一看,大體也差不多:
// 以下引用:
需要以下幾個基本步驟:
1、編寫系統調用函數
編輯sys.c文件:
# cd /usr/src/linux/kernel
# vi sys.c
在文件的最後增加一個系統調用函數:
asmlinkage int sys_print_info(int testflag)
{
printk(" Its my syscall function!n");
return 0;
}
該函數有一個int型入口參數testflag,並返回整數0。
2、修改與系統調用號相關的文件
編輯入口表文件:
# cd /usr/src/linux/arch/i386/kernel
# vi entry.S
把函數的入口地址加到sys_call_table表中:
arch/i386/kernel/entry.S中的最後幾行源代碼修改前為:
......
.long SYMBOL_NAME(sys_sendfile)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
rept NR_syscalls-190
.long SYMBOL_NAME(sys_ni_syscall)
.endr
修改後為:
......
.long SYMBOL_NAME(sys_sendfile)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
.long SYMBOL_NAME(sys_print_info) /* added by I */
.rept NR_syscalls-191
.endr
修改相應的頭文件:
# cd /usr/src/linux/include/asm
# vi unistd.h
把增加的sys_call_table表項所對應的向量,在include/asm/unistd.h
中進行必要申明,以供用戶進程和其他系統進程查詢或調用。
#define __NR_putpmsg 189
#define __NR_vfork 190
#define __NR_print_info 191 /* added by I */
// 引用結束
這一段有點差別,經過分析發現只要在arch/i386/kernel/entry.S單獨加上
.long SYMBOL_NAME(sys_print_info) /* added by I */
就行了。
然後就是做過無數次的make了,重起,編個程序一試,不行
# vi test.c
#include
#include
extern int errno;
_syscall1(int,print_info,int,testflag)
main()
{
int i;
i= print_info(0);
if(i==0)
printf("i=%d , syscall sUCcess!n",i);
}
分析一下,發現還需要改/usr/include/linux/unistd.h,加上同樣的東西
就行了。
然後試驗,一切OK,我的Hello World系統調用就這樣寫出來了!
相信我能做很多人就能像我一樣的。其實一些東西只要肯動手都不想想像的
那麼難。