前面咱們學習了在內核中添加本身的代碼,此次咱們在內核中添加一個本身的系統調用,就像open/close同樣的函數!linux
當咱們應用程序調用open close函數時: open close函數是通過libc.so 庫調用syscall函數,而後syscall函數再通過SWI調用內核的系統調用的;vim
全部咱們寫了一個系統調用以後,也要實現這樣一個過程,才能讓應用層正常調用系統調用.app
vim calls.S 爲本身的函數註冊系統調用號378函數
385 CALL(sys_syncfs) 386 CALL(sys_sendmmsg) 387 /* 375 */ CALL(sys_setns) 388 CALL(sys_process_vm_readv) 389 CALL(sys_process_vm_writev) 390 /* 378 */ CALL(sys_my_add) 391 #ifndef syscalls_counted 392 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 393 #define syscalls_counted 394 #endif 395 .rept syscalls_padding 396 CALL(sys_ni_syscall) 397 .endr
vim arch/arm/include/asm/unistd.h 聲明本身的系統調用函數 407行學習
403 #define __NR_sendmmsg (__NR_SYSCALL_BASE+374) 404 #define __NR_setns (__NR_SYSCALL_BASE+375) 405 #define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) 406 #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) 407 #define __NR_my_add (__NR_SYSCALL_BASE+378) 408 409 /* 410 * The following SWIs are ARM private. 411 */ 412 #define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000) 413 #define __ARM_NR_breakpoint (__ARM_NR_BASE+1) 414 #define __ARM_NR_cacheflush (__ARM_NR_BASE+2) 415 #define __ARM_NR_usr26 (__ARM_NR_BASE+3)
在 arch/arm/kernel目錄下建立一個mysyscall文件夾: 並在文件夾內:touch mysyscall.c mysyscall.h Makefile三個文件,寫入以下代碼,而後編譯內核,並刷機,這樣就把本身的syscall編譯到內核了.this
mysyscall.cspa
1 #include <linux/init.h> 2 #include <linux/sched.h> 3 #include <linux/module.h> 4 #include "mysyscall.h" 5 /* asmlinkage long sys_arm_fadvise64_64(int fd, int advice, 6 loff_t offset, loff_t len) 7 { 8 return sys_fadvise64_64(fd, offset, len, advice); 9 } */ 10 //asmlinkage:表示未來這段代碼是要由彙編來調用的。 11 asmlinkage long sys_my_add(int a,int b) 12 { 13 printk("this is liuye's syscall!\n"); 14 return a+b; 15 } 16 17 //module_init(sys_my_add); 18 MODULE_LICENSE("GPL");
mysyscall.hcode
1 #ifndef __MYSYSCALL_H_ 2 #define __MYSYSCALL_H_ 3 4 asmlinkage long sys_my_add(int a,int b); 5 6 7 #endif
makefileblog
1 obj-y += mysyscall.o
vim ../Makefile開發
74 AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt 75 obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o 76 # 在這層malefile中添加下一曾Makefile路徑 77 obj-y += mysyscall/ 78
以後 make -j4 利用SD卡刷機 系統調用添加到內核中了;
而後咱們要製做一個包含mysyscall的庫:在PC機上隨便找一個文件夾:touch my_add.c my_add.h 寫入以下代碼.並編譯成動態庫:
vim my_add.c
1 //這三行是爲了調用syscall而包含的頭文件和宏定義:能夠man syscall查看 2 #define _GNU_SOURCE /* See feature_test_macros(7) */ 3 #include <unistd.h> 4 #include <sys/syscall.h> /* For SYS_xxx definitions */ 5 #include <stdio.h> 6 int my_add(int a ,int b) 7 { 8 printf("this is liuye's app\n"); 9 return syscall(378,a,b); 10 11 }
vim my_add.h
1 #ifndef __MY_ADD_H_ 2 #define __MY_ADD_H_ 3 4 extern int my_add(int a, int b); 5 6 #endif
把上面的my_add.c my_add.h製做成動態庫:生成libadd.so
[liuye@LiuYe 01syscall]$>arm-linux-gcc -fPIC -c -o my_add.o my_add.c
[liuye@LiuYe 01syscall]$>arm-linux-gcc my_add.o -shared -o libadd.so
而後寫一個應用程序來調用下咱們系統調用:touch test.c
vim test.c
1 #include <stdio.h> 2 #include "my_add.h" 3 //#include <my_add.h> 4 int main(void) 5 { 6 int sum; 7 sum = my_add(1,2); 8 printf("sum = %d\n",sum); 9 return 0; 10 }
77 使用arm-linux-gcc編譯test.c代碼,須要連接動態庫 -L指定路徑 -l指定庫名 78 生成可執行文件:arm-linux-gcc test.c -o test -L./ -ladd 79 複製庫文件和可執行文件到共享文件夾:cp libadd.so test /myroot 81 把新編譯的內核copy到SD卡,刷機; 82 PC端:1 開啓共享服務 83 2 minicom連接開發板 84 mount -t nfs -o nolock,rw 192.168.1.10:/myroot /mnt 85 cd /mnt 86 cp libadd.so /lib/ 放到根下lib下,在運行的時候不用指定路徑 87 ./test 運行即
root@board liuye_dir#./test this is liuye's app [ 1817.020000] this is liuye's syscall! sum = 3 root@board liuye_dir#
以上就完成了一個系統調用的全過程,相信同窗們即學會了如何在內核中添加一個系統調用,也學會了應用程序調用系統調用的全過程了,是否是以爲很贊?!!!!!!!!!!哈哈哈哈反正我以爲是有收穫的!