linux/arch/i386/kernel/syscall_table.S的最後面加上要新增的system call名稱
如果syscall_table.S的最後面長得像這樣
.
.
.long sys_tee /* 315 */
.long sys_vmsplice
.long sys_move_pages
那麼要加入sys_project就要把它改成這樣, 這裡的".long"是必須的, 它並不是代表回傳的型態, 而是Linux Assembly的一個語法
.
.
.long sys_tee /* 315 */
.long sys_vmsplice
.long sys_move_pages
.long sys_project /* 318 */
而所加的定義在檔案中的順序, 其實也就是這個system call的system call number,
此例中是318
linux/include/asm/unistd.h裡面加上自己的define
unistd.h裡面會有一段跟syscall_table.S很像的define, 不過在這裡system call是以"__NR_"開頭, 而其後跟著的數值則是system call number, 如果在它定義的最後一個system call附近像這樣
.
.
#define __NR_vmsplice 316
#define __NR_move_pages 317
#ifdef __KERNEL__
#define NR_syscalls 318
.
.
因為 NR_syscalls 的值必須等於最大的system call加 1, 所以在根據syscall_table.S中的順序修改unistd.h之後, 不要忘了修改NR_syscalls的值
.
.
#define __NR_vmsplice 316
#define __NR_move_pages 317
#define __NR_project 318
#ifdef __KERNEL__
#define NR_syscalls 319
.
.
linux/include/linux/syscalls.h裡面加上函式的定義
函式定義前面必須加上asmlinkage以確保編譯時連結的正確性, 所以加完後的狀況大概像這樣
.
.
asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
size_t len);
asmlinkage long sys_project( int i );
#endif
將system call的實作檔放入source code tree中
原則上, 實作檔應該根據 syscall 的類型放在相對應的資料夾中, 然後再將實作檔編譯後的.o檔檔名加入該資料夾下的Makefile的obj-y之中,
假設實作檔的source code為project.c, 放在linux/kernel/, 那linux/kernel/Makefile改完後大概長這樣
.
.
obj-y = project.o sched.o fork.o exec_domain.o panic.o printk.o profile.o \
.
.
而在撰寫實作檔的時候, 請記得將"#include <linux/linkage.h>"加進去, 否則編譯將會發生問題, 以下是一個實作檔的範例
project.c
#ifndef __LINUX_PROJECT
#define __LINUX_PROJECT
#include <linux/linkage.h>
#include <linux/kernel.h>
asmlinkage long sys_project( int i ){
printk( "Success!! -- %d\n", i );
return 0;
}
#endif
- 在/usr/include/asm/unistd.h中加入定義讓User能呼叫
其實在上一步驟整個system call已經算是加好了, 但此時User只能以system call number呼叫(此例中是318),
為了讓User能以system call的名字呼叫, 所以要修改/usr/include/asm/unistd.h,改完結果像這樣
.
.
#define __NR_vmsplice 316
#define __NR_move_pages 317
#define __NR_project 318
#endif /* _ASM_I386_UNISTD_H_ */
- 重新編譯Kernel---->大功告成!!!
二、如何呼叫System call