Hi friends!! I am going to use this article to explain how to add a “hello world system call” to your kernel as I recently accomplished this task. My OS is Linux Ubuntu 14.04 and the kernel version I have implemented this in is, 4.1.33 and I have used a 64 bit system. The following steps will be more or less the same with little changes here and there for other versions of kernel.

In computing, a system call is the programmatic way in which a computer program requests a service from the kernel of the operating system it is executed on. This may include hardware-related services (for example, accessing a hard disk drive), creation and execution of new processes, and communication with integral kernel services such as process scheduling . System calls provide an essential interface between a process and the operating system.
Grab the kernel source:
Open the terminal and use the following command to get the kernel source file.
$ sudo apt-get source linux-image-$(uname -r)
You will find a new folder name linux-<kernel version number>.

Copy the kernel source to /usr/src.
$ sudo cp -r linux-4.1.33 /usr/src .
{{ Use “sudo -s” command to avoid repeating sudo every time.}}
Installing the required packages:
$ sudo apt-get update
$ sudo apt-get build-dep linux-image-$(uname -r)
$ sudo apt-get install kernel-package # for make-kpkg clean
$ sudo apt-get install libncurses-dev # for make menuconfig
Next the system call:
Step 1:
$ cd linux-4.1.33
Create a directory hello in the kernel source directory:-
$ mkdir hello
Change into this directory
$ cd hello
Step 2:
Create a “hello.c” file in this folder and add the definition of the system call to it as given below.
$ vim hello.c
Then include the code :::::::::::
#include <linux/kernel.h>
asmlinkage long sys_hello(void)
{
printk(“Hello world\n”);
return 0;
}
The asmlinkage tag is one other thing that we should observe about this simple function. This is a #define for some gcc magic that tells the compiler that the function should not expect to find any of its arguments in registers (a common optimization), but only on the CPU’s stack.

Step 3: Create the Makefile
$ vim Makefile
Add the following line to Makefile
obj-y := hello.o

Step 4 : Add the hello directory to the main kernel Makefile
Change back into the linux-4.1.33 folder and open Makefile.
gedit Makefile
Go to line number 900(may vary) which says :-
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
and add hello/ to the end of the line like so
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ hello/
This tells our compiler that the source code of sys_hello() lies in the hello directory.

Step 5: Add sys_hello() into the syscall table
Since we are using a 64 bit system we need to edit the file “syscall_64.tbl” .
$ cd arch/x86/entry/syscalls/syscall_64.tbl
Add the following after the last sys_call.
323 64 hello sys_hello
Where 323 is one plus the last sys_call in “syscalls_64.tbl”. This has to be used to make the syscall in the user program.

Step 6 : Add the sys_hello() in the syscalls.h header file
$ cd include/linux
$ vim syscalls.h
Add the following to the end of the file just before the #endif statement.
asmlinkage long sys_hello(void);
This defines the prototype of the function for our system call. ”asmlinkage” is a key word used to indicate that all parameters of the function would be available on the stack.

Create the config file……….
$ cd ../..
$ make menuconfig
In the window that comes you can customize the feature of the kernel you are going to build.(we will keep it to the default values). Select the save option using tab and enter keys.
Building the Kernel (Time for a tea break…..!!)
To increase the speed of compilation use the below command
$ export CONCURRENCY_LEVEL=3 # 1+number of cores on your processor
$ make # compile the kernel
…check the number of cores on your processor…
$ lscpu
Installing the kernel…
To install this kernel execute the following command
$ sudo make modules_install install
The above command will install the Linux Kernel 4.1.33 into your system.It will create some files under /boot/ directory and will automatically make an entry in your grub.cfg.
Test the system call.
Create a “hello_syscall.c” program in your home folder and type in the following code :-
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main() {
long int sys = syscall(323); // 323 is the sys_hello number we had used to add the sys_call
printf(“System call sys_hello returned %ld\n”, sys); // 0 means, everything went well
return 0;
}
Now compile this program using the following command.
$ gcc hello_syscall.c
If it didn’t compile and you got an error, try fixing it and then compile again.
Now run the program using the following command
$ ./a.out
You will see the following line getting printed in the terminal if all the steps were followed correctly.
System call sys_hello returned 0
If you got -1 instead of 0, that means your sys_hello() did not execute correctly, check all the code changes you made and try to build the kernel again. Make sure you have booted using the kernel you have made changes to. To check the current running kernel type the following command.
$ uname -r
If everything worked correctly check the log message of the kernel by using the dmesg command.
$ dmesg
This will display “Hello World!” at the end of the kernel’s message and you have successfully implement a sys_call.

Boot to the Right Kernel:
You can change which kernel grub boots to during the computers start-up.
As the computer starts up.
Hold down SHIFT to display the menu during boot. In certain cases, pressing the ESC key may also display the menu.

You should now see the the grub menu. Use the arrow keys to navigate to the advanced options and choose the kernel you want to boot.
