Wednesday, March 26, 2014

[OSDI] Adding a New System Call in Linux Kernel

Steps

  1. modify arch/x86/kernel/syscall_table_32.S
  2. modify arch/x86/include/asm/unistd_32.h
  3. modify arch/x86/include/asm/syscalls.h
  4. modify arch/x86/kernel/Makefile
  5. add and implement arch/x86/kernel/hello.c
  6. make && sudo make modules_install && sudo make install && sudo reboot (Compile Kernel)

modify arch/x86/kernel/syscall_table_32.S

this file contains all the syscall names, so add a new line for our new system call at the end of the file
add .long sys_mycall at the end

modify arch/x86/include/asm/unistd_32.h

add #define __NR_mycall 338 before #ifdef __KERNEL__
modify #define NR_syscalls <number of system calls + 1>

modify arch/x86/include/asm/syscalls.h

the interface (declaration) of the system calls
add asm_linkage int mycall(void); after asmlinkage long sys_mmap(...);

modify arch/x86/kernel/Makefile

make sure the new system call will be compiled
add obj-y += mycall.o after obj-y := process...

add and implement arch/x86/kernel/hello.c

#include <linux/kernel.h>
#include <linux/linkage.h>
asmlinkage int sys_mycall(void) {
    printk("Hello, how are you?\n");
    return 0;
}

Test

  • modify /usr/include/asm/unistd_32.h
  • modify /usr/include/bits/syscall.h
  • write a program to test it
  • see the output in dmesg
modify /usr/include/asm/unistd_32.h
add #define __NR_mycall 341 at the end, before #endif
modify /usr/include/bits/syscall.h
add #define SYS_mycall __NR_mycall at the end of the file
write a program to test it

#include <syscall.h>#include <stdio.h>
int main() {
    int r;
    r = syscall(__NR_mycall);
    printf("return value = %d\n", r);
    return 0;
}

see the output in dmesg
simply type "dmesg" to check if the output is there

Reference