Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding new System Call to Linux Kernel 3.13 on 64 bit system

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?

like image 964
Hamed Kamrava Avatar asked Nov 03 '14 18:11

Hamed Kamrava


People also ask

How do you implement system calls?

A typical way to implement this is to use a software interrupt or trap. Interrupts transfer control to the operating system kernel, so software simply needs to set up some register with the system call number needed, and execute the software interrupt.

Do system calls run in kernel mode?

Since system calls are executed in kernel mode, they have access to kernel space and if pointers are not properly checked user applications might get read or write access to kernel space.

Do all system calls require kernel mode?

The original definition of a system call is/was a system support (OS) function that is called by a trap of some kind rather than a "normal" function call. So by that definition, every system call requires a switch to kernel mode, as if it didn't it wouldn't be a system call (just a normal system library call).


1 Answers

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
like image 186
Hamed Kamrava Avatar answered Sep 23 '22 01:09

Hamed Kamrava