Generally Linux programmers always curious about system calls and the way it is implemented. As a Linux programmer, I just wanted to learn system call implementation by actually using it in my application. This will completes the cycle.
The environment is i386 QEMU with 3.8 kernel.
Here is the problem statement.
"Just add a system call which takes two integer as input and returns addition of those two".
"Just add a system call which takes two integer as input and returns addition of those two".
Step 1: Download the Linux kernel from kernel.org (3.8 version) and extract it.
Step 2: Adding system call by modifying kernel
Step 2.1: In
linux-3.8/arch/x86/syscalls/syscall_32.tbl
file add an entry.#
# 32-bit system call numbers and entry vectors
#
# The format is:
# <number> <abi> <name> <entry point> <compat entry point>
#
# The abi is always "i386" for this file.
#
0 i386 restart_syscall sys_restart_syscall
1 i386 exit sys_exit
2 i386 fork sys_fork stub32_fork
3 i386 read sys_read
.............
.............
348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
349 i386 kcmp sys_kcmp
350 i386 finit_module sys_finit_module
351 i386 jeyAdd sys_jeyAdd
jeyAdd
is the newly added system call. This file contains system call numbers and corresponding entry vectors for i386(Of course, file name itself explains!!)
Step 2.2: In
linux-3.8/include/linux/syscalls.h
add declaration of sys_jeyAdd()
likeasmlinkage long sys_jeyAdd(int a, int b);
Step 2.3: Add a new C file say
JeyCalc.c
with the following content/* This file is added for testing system calls flow. */
#include <linux/syscalls.h>
SYSCALL_DEFINE2(jeyAdd, int, arg1, int, arg2)
{
return (arg1 + arg2);
}
Step 2.4: In kernel Makefile(
linux-3.8/kernel/Makefile
), include the newly added file JeyCalc.c
#
# Makefile for the linux kernel.
#
obj-y = ...
...
async.o range.o groups.o lglock.o smpboot.o JeyCalc.o
Step 2.5: Compile the kernel for bzImage.
Step 3: Now lets write an application for using our newly created system call.
constraints
- Our C library doesn't know about new system call
- My file system don't have C libraries(Forgot to compile busybox with C libs).
Solutions
syscall() function in unistd.h
can be used with syscall number to invoke it. In our case, 351.
Here is the sample application
#include <stdio.h>
#include <unistd.h>
int main()
{
int a = 0;
printf("\n Test Application for My Syscalls \n");
a = syscall(351, 10, 20);
printf("\n Result: %d\n", a);
return 0;
}
If this application is compiled with -static
then there is no need for C libs. It works fine.
Step 4: Mount the file system and copy the statically linked application to it.
Step 5: Load the QEMU with modified kernel's bzImage and file system.
Step 6: Go to Application's directory and run it. Yeah!!! You made it.
References
No comments:
Post a Comment