Adding New System Call to Linux Kernel 3.13 on 64 Bit System

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

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

Adding a new system call in Linux kernel 3.3

I think in kernel 3.3 its shifted here

http://lxr.free-electrons.com/source/arch/x86/syscalls/

adding a simple system call to linux kernel

Your code is executed in kernel context whilst the buffer with data comes from the userspace. If you need to process some string from the userspace, copy it to the kernel memory using strncpy_from_user() function. If you don't follow the scheme and simply try to access the data directly, this will lead to a memory access violation.

A better solution (based on your code) would look somewhat like this:

asmlinkage long sys_hello(char* name) {
long nb_symbols;
char *name_internal;
long i;

/*
* Estimate the buffer length sufficient
* to accommodate the string
*/
for (i = 1; ; ++i) {
nb_symbols = strnlen_user(name, i);
if (nb_symbols <= 0)
return -EFAULT;

if (nb_symbols < i)
break;
}

/* Allocate the storage */
name_internal = kmalloc(nb_symbols + 1, GFP_KERNEL);
if (name_internal == NULL)
return -ENOMEM;

if (strncpy_from_user(name_internal, name, nb_symbols + 1) !=
nb_symbols) {
kfree(name_internal);
return -EFAULT;
}

printk("The 'name' is '%s'\n", name_internal);
kfree(name_internal);

return 0;
}

However, please note that such a loop (as one in my example) might not be an acceptable solution for buffer length estimation. Ideally, you could drop it and use a static char array of fixed length to use strncpy_from_user() with.

Linux Kernel system call implementation with struct parameter

Place a header containing the new struct in include/uapi/linux.
Avoid namespace pollution by using the appropriate types e.g. __u16 instead of unsigned short/uint16_t, __kernel_time_t instead of time_t ...etc. Check out struct mii_ioctl_data for an example.

By adding a header-y += new_header.h entry to include/uapi/linux/Kbuild, you can then export the header with make headers_install.

By default, it installs the headers in ./usr. If you want it to install them as system headers, use make headers_install INSTALL_HDR_PATH=/usr instead. This results in the contents of the uapi directory being merged into /usr/include. You may then #include <linux/new_header.h> in your userspace program.



Related Topics



Leave a reply



Submit