Add system calls to the kernel

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!

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325049289&siteId=291194637