Earlier we learned to add our own code to the kernel, this time we add a system call of our own to the kernel, like a function like open/close!
When our application calls the open close function: the open close function calls the syscall function through the libc.so library, and then the syscall function calls the kernel system call through SWI;
After we write a system call, we also need to implement such a process so that the application layer can call the system call normally.
vim calls.S register system call number 378 for its own function
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 declares its own system call function line 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)
Create a mysyscall folder in the arch/arm/kernel directory: and in the folder: touch mysyscall.c mysyscall.h Makefile three files, write the following code, then compile the kernel, and flash the machine, so that your own syscall compiled into the kernel.
mysyscall.c
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: Indicates that this code will be called by assembly in the future. 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.h
1 #ifndef __MYSYSCALL_H_ 2 #define __MYSYSCALL_H_ 3 4 asmlinkage long sys_my_add(int a,int b); 5 6 7 #endif
makefile
1 obj-y += mysyscall.o
vim ../Makefile
74 AFLAGS_iwmmxt.o := -Wa,-mcpu= iwmmxt 75 obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o 76 # Add the next Makefile path in this layer of malefile 77 obj-y += mysyscall/ 78
After that, make -j4 is added to the kernel using the SD card flashing system call;
Then we have to make a library containing mysyscall: find a folder on the PC: touch my_add.c my_add.h Write the following code. And compile it into a dynamic library:
vim my_add.c
1 // These three lines are the header files and macro definitions included in order to call syscall: you can view 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
Make the above my_add.c my_add.h into a dynamic library: generate 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
Then write an application to call our system call: touch test.c
force 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 Use arm-linux-gcc to compile the test.c code, you need to link the dynamic library -L specifies the path -l specifies the library name 78 Generate an executable file: arm-linux-gcc test.c -o test -L./ - ladd 79 Copy the library files and executable files to the shared folder: cp libadd.so test / myroot 81 Copy the newly compiled kernel to the SD card and flash the machine; 82 On the PC side: 1 Start the sharing service 83 2 Minicom link to the development board 84 mount -t nfs -o nolock,rw 192.168 . 1.10 :/myroot / mnt 85 cd / mnt 86 cp libadd.so /lib/ put it under the root lib, no need to specify the path when running 87 ./test run
root@board liuye_dir#./test this is liuye's app [ 1817.020000] this is liuye's syscall! sum = 3 root@board liuye_dir#
The above completes the whole process of a system call. I believe that students have learned how to add a system call to the kernel, and also learned the whole process of calling a system call by an application program. Do you think it's great?!!!!! !!!!! Hahahaha anyway I think it is rewarding!