Implementing a new system call in Kernel version 2.6.32

A system call is used by application or user programs to request service from the operating systems. Since the user programs does not have direct access to the kernel whereas the OS has the direct access. OS can access the hardware through system calls only.

The following files has to be modified for implementing a system call

  1. /usr/src/linux-2.6.32.5/arch/x86/kernel/syscall_table_32.S
  2. /usr/src/linux-2.6.32.5/arch/x86/include/asm/unistd_32.h
  3. /usr/src/linux-2.6.32.5/include/linux/syscalls.h
  4. /usr/src/linux-2.6.32.5/Makefile

New set of files to be created

  1. Create a new directory newcall/ inside the path “/usr/src/linux-2.6.32.5/
  2. Create new files Makefile, newcall.c and put them in the /usr/src/linux-2.6.32.5/newcall/ folder
  3. Create new user files (in any folder of Linux) to test the system call
    testnewcall.c, testnewcall.h (created in /home/pradeepkumar)

syscall_table_32.S

Find the file /usr/src/linux-2.6.32.5/arch/x86/kernel/syscall_table_32.S and add the following line at the end
".long sys_newcall"  (add without double quotes, but the preceding . should)

unistd_32.h
open the file /usr/src/linux-2.6.32.5/arch/x86/include/asm/unistd_32.h
(all the system calls will be defined in this file using #define macro)

This file contains the system call number that is passed to the kernel through the register (EAX) when a system call is invoked.

Add "#define __NR_mycall <Last_System_Call_Num + 1>" at the end of the list.
If the last system call defined here is:
"#define __NR_vmsplice   336", then add:
"#define __NR_newcall   337" at the end of the list. (337 is the new system call number)

two

Increment the "NR_syscalls" by 1. So, if NR_syscalls is defined as:
"#define NR_syscalls 337", then change it to:
"#define NR_syscalls 338"  (Since we added a new kernel, so the total number of system calls should be incremented)

one

syscalls.h
open the file /usr/src/linux-2.6.32.5/include/linux/syscalls.h
Add the following line at the end of the file:
"asmlinkage long sys_newcall(int i);"  (without double quotes)

Makefile
Full path of the file - /usr/src/linux-2.6.32.5/Makefile
Create a new directory newcall/ under the folder /usr/src/linux-2.6.32.5
and include that path to /usr/src/linux-2.6.32.5/Makefile

open the /usr/src/linux-2.6.32.5/Makefile
and find the "core-y += " and append newcall/ to the path (please see the image below)

three

newcall.c
Create a new file called newcall.c with full path: /usr/src/linux-2.6.32.5/newcall/newcall.c
/*---Start of newcall.c----*/
#include <linux/linkage.h>
asmlinkage long sys_newcall(int i)
{
return i*10; //the value passed from the user program will be multiplied by 10
}
/*---End of newcall.c------*/

Makefile
Create a new file called Makefile with full path: /usr/src/linux-2.6.32.5/newcall/Makefile
and paste the following line
obj-y := newcall.o

Create userspace files to test the system call
create two files testnewcall.c and testnewcall.h and the full path of the files are
/home/pradeepkumar/testnewcall.c
/home/pradeepkumar/testnewcall.h

testnewcall.c

#include <stdio.h>
#include "testnewcall.h"
int main(void)
{
printf("%d\n", newcall(15)); // since 15 is passed, the output should be 15*10=150
return 0;
}

testnewcall.h

#include<linux/unistd.h>
#define __NR_newcall 337

long newcall(int i)
{
return syscall(__NR_newcall,i);
}

Note: "_syscall1(long, mycall, int, i)" this can be added instead of

long newcall(int i)
{
return syscall(__NR_newcall,i);
}

Macro _syscall1()

_syscall1(long, newcall, int, i)
the importance of the above syscall is

  • The name of the system call is newcall.
  • It takes one argument.
  • The argument is an int named number.
  • It returns an long.

Testing the new system call
Step 1: Recompile and install the new kernel so that our system call becomes available to the operating system. go to the kernel folder and give command make

Step 2: Reboot the system

Step 3: Compile and execute the user space C file (testnewcall.c) that we created above. (gcc testnewcall.c and then execute ./a.out)

RESULT: You should see the output as 150. This has been tested on kernel 2.6.32.5.

Source: http://tldp.org/HOWTO/html_single/Implement-Sys-Call-Linux-2.6-i386/ (The above link uses kernel version 2.6.17 and it uses different set of files)

My post uses a recent kernel 2.6.32.5 and it modifies different set of files.

Any doubts, please query through the comments….

Installing Windows 7 from USB

Are you a person recently purchased a netbook which is not having a DVD ROM, No problem, you can install any OS using a pendrive or USB’s.
Here is the steps.
Requirements
1. A 4GB pen drive (since the size of Windows 7 is 2.34GB)
2. Windows 7 installation files or a iso image of Windows 7 OS
3. Administrative privileges in the OS
Step 1 : Take the backup of all the data in your usb drive plug into the Machine.
Step 2: Go to device manager (Control panel –> device manager –> select disk –> select your usb drive ) and then right click –> properties –> go to policies –> Select Better performance). This step is needed for faster installation of windows 7 (You can wonder, windows 7 installed within 15 minutes with just 1GB RAM) See the following picture
one

two
Step 3:   open the command prompt with administrative rights (Accessories –> right click Command prompt – and select run as administrator)
Step 4: type DISKPART  (you will get a prompt as DISKPART)
Step 5: type LIST DISK (it will list all the disks), please remember the disk number of your pen drive (see the following picture)
three
So, mine is disk 1
Step 6: Execute the following commands one by one,
SELECT DISK 1
CLEAN
CREATE PARTITION PRIMARY
SELECT PARTITION 1
ACTIVE
FORMAT FS=NTFS   (since windows 7 permits only NTFS, the USBs also to be formatted as NTFS, and this process will take some time)
ASSIGN
EXIT
Step 7: Now insert the windows 7 DVD drive or if you have iso image, using winrar extract it to a folder
Step 8:  go to the concerned folder in the command prompt (assume installation files of windows 7 as E:/win07)
execute the command in command prompt
E:
CD win07/BOOT
BOOTSECT.EXE /NT60 G: (assigning the bootmanager to the USB. G is the drive letter for my USB)
Step 9: After getting the successful message, copy the contents of your Windows 7 installation files to your USB Drive. Thats it.
Enable Booting from  USB option in your BIOS and lets see the installation will complete within 15 minutes.!!!!

Thanks to http://www.intowindows.com/how-to-install-windows-7vista-from-usb-drive-detailed-100-working-guide/

How to add a new Linux Kernel Module (LKM)

To demonstrate, let us goto a simple “Hello World” as a module and inserted in to the kernel

Step 1
Open any editor like vi or gedit in a shell prompt and the type the following
/* Name of the file is hello.c */
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
printk(KERN_INFO “Hello world.n”);
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO “Goodbye worldn”);
}


The above is a simple C program that displays “Hello world” when the module is inserted and displays “Goodbye world” when the module is removed.
Step 2
The program can be compiled using gcc compiler in the shell prompt itself, but we need to write the commands twice or more. So to compile shortly let us write a makefile to compile the above program
The make file should be named as Makefile (See the First letter M is uppercase and there should not be any space between Make and file)
Copy and paste the following lines in an editor (vi or gedit)
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Step 3
after this, execute the following command
# make
You will get the following output which indicates there is no error
make -C /lib/modules/2.6.27.5-117.fc10.i686/build M=/home/pradeepkumar/lsp modules
make[1]: Entering directory `/usr/src/kernels/2.6.27.5-117.fc10.i686′
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory `/usr/src/kernels/2.6.27.5-117.fc10.i686′
The make command creates new set of files like hello.ko, hello.mod.o, modules.order, etc
Step 4
The .ko indicates it is a kernel object, but ordinary C compiler generates only an object file..
go to the shell prompt (open the terminal) execute the command one by one
# su
The above command waits for the root password, please provide the password
# insmod
inserting the module
# lsmod
listing all the modules running under the kernel, you can see the first module will be listed as hello
# dmesg
you can see thelast line says hello world
# rmmod
removing the module
# dmesg
you can see the last line says goodbye world
Like this we can write many modules and can be inserted to the kernel..

Recompiling Linux Kernel

How to add a new kernel to linux OS and compile it and use it, the following points discusses that.
Step 1: Download a new kernel from kernel.org (recent version is 2.6.33)
Step 2: you may get the file either as a .tar.bz2 file  or .tar.gz file
Step 3: untar the file in the /usr/src directory (for installing you need to be a root user)
if it is a bz2 file, then execute tar jxvf filename.tar.bz2 –C /usr/src
if it is a gz file, then execute tar zxvf filename.tar.gz –C /usr/src
Step 4: go to the folder /usr/src using the command cd /usr/src

Step 5: Execute the following 
    Execute any one of the following command
  • make config (for text mode)
  • make menuconfig
  • make xconfig (for X window)
  • make gconfig (this command is preferred)
Step 6: make  (will take atleast 30 minutes to complete, be patient)
Step 7: make modules
Step 8: make modules_install
Step 9: make install
Once done, reboot the system, your grub loader is updated with one more kernel.
(NB: in the previous flavors of linux, the following are the set of commands
  • make xconfig
  • make dep
  • make
  • make bzImage
  • make modules
  • make modules_install
  • make install    )