Adding a Custom System Call to Ubuntu Linux in [C]

来源:互联网 发布:21天学通java知乎 编辑:程序博客网 时间:2024/04/25 14:00

Adding a Custom System Call to Ubuntu Linux in [C]

REQUIRES:

Compiling a [C] program in Linux

Today we are going to add a custom “Hello World” system call to Ubuntu 9.04 Linux using the kernel version: 2.6.28-11.

First things first, we need to figure out how to get the source andbuild a custom kernel. Instructions for how to do this can be found inmy previous post:

Compiling a UBUNTU Jaunty Jackalope Kernel

Ok, now that we know how to compile a shiny new custom kernel, we need to create our system call:

/* adding helloworld system call */
#include <linux/linkage.h>

asmlinkage int sys_helloworld() {
printk(KERN_EMERG "Hello World!/n");
return 0;
}

Now, I opted to add this to /usr/src/linux/kernel/sys.c.However, you can always create your own file and add it to the kernel’smakefile. If you decide to go down this route you are also going toneed to #include <linux/kernel.h> to the code above; the file kernel/sys.c already includes that package.

Lets explain what’s going on here a little shall we?

asmlinkage: thats there to indicate the code is written in ‘C’ as oppose to C++

printk: is used to print out kernel log messages. These messages are stored in /var/log/syslog.

KERN_EMERG: is used for logging emergency messages;these usually happen before a crash. The Kernel has 8 different typesof log levels, a few others are- KERN_DEBUG, KERN_ALERT, KERN_ERR

Alright, now that we have our system call we need to let the kernel know its there and can be used.

To do this we will have to modify a few files.

Modify /usr/src/linux/arch/x86/include/asm/unistd_32.h and add, or unisted_64.h

#define __NR_helloworld         333

to the list of system call numbers. This is the system calls unique identification number.

Modify /usr/src/linux/arch/x86/include/asm/syscalls.h and add:

/* X86_32 only */
/* kernel/sys.c */
asmlinkage int sys_helloworld();

under the “/* X86_32 only */” comment. This registers the system call.

Modify /usr/src/linux/arch/x86/kernel/syscall_table_32.h and add:

.long sys_helloworld           /* 333 */

to the bottom of the list. This also registers the system call.

Alright, now build your new modified kernel..this is going to take a while…

OK, SO 2 hours later…Install the new kernel and reboot.

Now we have to build a little c-program to use that shiny new system call right? *How Exciting!*

#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>

#define __NR_helloworld        333    /* or     whatever you set it in unistd.h */

int helloworld() {
return (int) syscall(__NR_helloworld);
};

main () {
printf("The return code from the helloworld system call is %d/n", helloworld());
}

Compile it and lets see what happens!

Output [Command Line]:

lee@isis:~$ ./a.out
The return code from the helloworld system call is 0

Output [/var/log/syslog]:

May 14 23:19:02 isis kernel: [48397.527522] Hello World!

Exactly what we expected. Our program returned ‘0′ from the system call execution AND we have the output in the logs. YAY!

[NOTE]: Now, you may have issues with flushing thebuffer at this step so you may have to trigger an event on the systemlike reset your wifi connection to actually see the print out in thelog. However, having the newline at the end of the message is supposedto guarantee the flush.

Congratulations you just made your very own system call in your veryown custom kernel. Mom would be so proud, if only she knew what akernel or a system call was!

Enjoy! =)

原创粉丝点击