add system call to kernel 4.x

Add a new entry in syscall table

OS: Ubuntu 16.04 64 bit

Add a entry in arch/x86/entry/syscalls/syscall_64.tbl:

1
2
3
4
5
322     64      execveat                stub_execveat
323 common userfaultfd sys_userfaultfd
324 common membarrier sys_membarrier
325 common mlock2 sys_mlock2
326 common hello sys_hello <---- 加在这一行

Declare the system call

Add a declaration to our system call in include/linux/syscalls.h:

1
2
3
4
5
asmlinkage long sys_membarrier(int cmd, int flags);

asmlinkage long sys_mlock2(unsigned long start, size_t len, int flags);

asmlinkage long sys_hello(void); <---- 加这一行

Implement our system call

1
2
3
mkdir hello
touch hello/hello.c
touch hello/Makefile

Content in hello/hello.c:

1
2
3
4
5
6
7
#include <linux/kernel.h>

asmlinkage long sys_hello(void)
{
printk("Hello world\n");
return 0;
}

Content in hello/Makefile:

1
obj-y := hello.o

Modifiy Makefile in linux-4.x/

Change

1
core-y          += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/

to

1
core-y          += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ hello/

Compile kernel

  1. make menuconfig
  2. make -j$(nproc)
  3. sudo make modules_install
  4. sudo make install
  5. sudo reboot

Write program to use the system call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>

#define __NR_hello 326

long hello_syscall(void)
{
return syscall(__NR_hello);
}

int main(int argc, char *argv[])
{
long int a = hello_syscall();
printf("System call returned %ld\n", a);
return 0;
}

If everything is OK, we can see “Hello world” in dmesg