11
votes

I'm trying to add a simple helloworld System Call to kernel 3.13.0-37-generic on 64 bit system.

I'll try to show what I did so far step by step :

1- I've downloaded kernel source by :

sudo apt-get source linux-image-3.13.0-37-generic

After that, kernel source files extracted to /usr/src/

2- Define a new system call sys_hello() :

I've created a directory with hello name in the kernel source directory in /usr/src/linux-3.13/

And I created a hello.c file in hello directory with below content :

#include <linux/kernel.h>

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

Then I created a Makefile in the hello directory with following content :

obj-y := hello.o

3- Add the hello directory to the kernel’s Makefile

I changed following line in /usr/src/linux-3.13/Makefile:

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

to :

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

4- Add the new system call sys_hello() into the system call table (syscall_64.tbl file)

Because I'm using 64 bit system, I need to alter the syscall_64.tbl file in :

/usr/src/linux-3.13/arch/x86/syscalls/syscall_64.tbl

Added the following line in the end of the file :

-Last line number was 313

314     common    hello    sys_hello

5- Add the new system call sys_hello() in the system call header file

vim /usr/src/linux-3.13/include/linux/syscalls.h

I've added the following line to the end of the file just before the #endif statement at the very bottom :

asmlinkage long sys_hello(void);

6- Compiling this kernel on my system

To configure the kernel I tried the following command :

sudo make menuconfig

After above command a pop up window came up and I made sure that ext4 was selected and then save.

Then :

# cd /usr/src/linux-3.13/
# make

It tooks 2~3 hours.

After that :

# make modules_install install

After that, I rebooted my system.

7- Test the system call (Problem Is Here)

After reboot, I created a file with name hello.c in home folder with following content :

#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
         long int amma = syscall(314); // 314 is the number of sys_hello line in `syscall_64.tbl`
         printf(“System call sys_hello returned %ld\n”, amma);
         return 0;
}

Then :

# gcc hello.c
# ./a.out

The output is :

System call sys_hello returned -1

Problem exactly is -1. It must return 0 not -1.

Seems like sys_hello doesn't added to Kernel System Call.

What am I doing wrong?

1
Look in the kernel log or check uname to make sure you are running your new build. Maybe check the system.map to see if your addition was included in the kernel.Chris Stratton
I can't figure it out by uname cause before/after kernel is same (Both are kernel 3.13.0-37-generic).Hamed Kamrava
There is no log in dmesg that related to sys_hello system call !Hamed Kamrava
Doesn't your kernel output include when it was built? I wasn't suggesting you look there for evidence of your function, but rather for evidence that you are in fact running your new build. Then separately make some checks to see if your new build picked up your code at all.Chris Stratton
Learn about make-kpkg to build a kernel, and pass -j 4 to make-kpkg or to make when building it.Basile Starynkevitch

1 Answers

8
votes

The problem was from step 6 to last step (Compile Kernel).

After step 5, we have to do following steps :

6- Compiling this kernel on my system

To configure the kernel I tried the following command :

# make menuconfig

After above command a pop up window came up and I made sure that ext4 was selected and then save.

Then to create DEB file from new kernel we have to :

# make -j 5 KDEB_PKGVERSION=1.arbitrary-name deb-pkg

It will create some deb files in /usr/src/.

After that we need to install them :

# dpkg -i linux*.deb

It will install new kernel on your system.

Now, reboot your system. After system rebooted you can find out whether new kernel is installed or not :

$ uname -r

And if you want to know your new System Call added to kernel or not just type :

$ cat /proc/kallsyms | grep <system call name>

In my case :

$ cat /proc/kallsyms | grep hello

Following output indicates that your System Call successfully added to the Kernel :

0000000000000000 T sys_hello