Tag Archive : kernel

/ kernel

Add New System Call to Linux 3.2

November 24, 2015 | Article | 1 Comment

What is syscall? Syscall is abbreviation from system call, a service provided by kernel to user program who request for it. It may include hardware related services such as hard disk access, creating and executing new process, also communicationg with integral kernel services (like scheduling). System calls is essential interface between a process and the operating system.

At several past article, we have discussed how to compile a new kernel (based on version 3.6.1). This time, we will try to add some kernel syscall. Our own syscall precisely. And yes, this is part of my course homework. Let’s get start to our subject.

For this time why do we use Linux 3.2.29 version? Well it’s part of the homework though. But next time maybe I will write another article of writing syscall for Linux 3.6.1. Please note that the overall kernel structure in linux prior to 3.2 is different to the newer one so adding syscall in 3.6.1 would has different technique than technique discussed here. But by the way, the step for adding system call is similar to previous article (step by step compile kernel 3.6.1)

Now download the kernel we need at http://kernel.org/ website. In this case we need 3.2.29.

wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.29.tar.xz

The reason I used linux-3.2.29.tar.xz instead of linux-3.2.29.tar.gz or linux-3.2.29.tar.bz2 is simply because of size.

Make sure you move the source to /usr/src/ directory. Do that using root access.

Now extract the source code.

tar -Jxf linux-3.2.29.tar.xz
cd linux-3.2.29

We can take the old configuration as our basis for creating configuration file.

cp /boot/config-2.6.35.22-generic .config

In this case I use kernel 2.6.35.22-generic. It can be different in your system so match the version number with your current kernel version.

It’s a wise way to see what we can do by invoking make. A little help could give us hint.

make help

Now, to configure the config file, invoke

make menuconfig

After deciding what configuration you choose, It’s time for compilation. We will using generic way of compilation. It is the standard way provided by kernel and not platform oriented.

Now it’s time to get to our main subject. We will modify some files and do it sequentially and in the last we will test our new syscalls.

I’m going to create 3 syscalls: generate odd random-number, generate even random-number, and a dummy syscall which add input integer with 10.

Now create a new folder in kernel root directory, in this case /usr/src/linux-3.2.29, named randomsys/.

Open and edit file /usr/src/linux-3.2.29/arch/x86/kernel/syscall_table.S. At end of file add 3 entries:

  • .long sys_oddrandom
  • .long sys_evenrandom
  • .long sys_mycall

See number above? The entries is registered with unique numbers as seen above. Our 3 syscalls have id 349, 350, and 351. It’s easy to figure it out :). You can add more or less than this example, just remember what number your syscalls are.

Open and edit file /usr/src/linux-3.2.29/arch/x86/include/asm/unistd_32.h. Locate line with text:

#ifdef __KERNEL__
#define NR_syscalls 349

You see some number on NR_syscalls, right? In this case is 349. Now look upward and then you will see some entries with __NR_ suffix. We will add some entries like those too. Add these entries after the latest entry:

  • #define __NR_oddrandom 349
  • #define __NR_evenrandom 350
  • #define __NR_mycall 351

Now you would be figure out what those numbers are. Yep, that are our unique number we add on syscall_table.S file. Then change number on NR_syscalls with 352.

Next we will open and edit /usr/src/linux-3.2.29/include/linux/syscalls.h. Add following entries before #endif:

  • asmlinkage unsigned int sys_oddrandom();
  • asmlinkage unsigned int sys_evenrandom();
  • asmlinkage int sys_mycall(int i);

Now open and edit /usr/src/linux-3.2.29/Makefile. Locate entries with:

core-y        += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

Add randomsys/ to end of that line. Here randomsys/ is our newly created folder. If you did correctly your entry would be:

core-y        += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ randomsys/

Now create 3 files in directory /usr/src/linux-3.2.29/randomsys/. Those are sys_oddrandom.c; sys_evenrandom.c; sys_mycall.c.

Now open and edit /usr/src/linux-3.2.29/randomsys/sys_oddrandom.c

#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/random.h>

asmlinkage unsigned int sys_oddrandom() {
   unsigned int v = 0;
   while( (v=get_random_int()) % 2 != 1 );
   return v;
}

Now open and edit /usr/src/linux-3.2.29/randomsys/sys_evenrandom.c

#include <linux/linkage.h>
#include <linux/kernel.h>
#include <linux/random.h>

asmlinkage unsigned int sys_evenrandom() {
   unsigned int v = 0;
   while( (v=get_random_int()) % 2 != 0 );
   return v;
}

Now open and edit /usr/src/linux-3.2.29/randomsys/sys_mycall.c

#include <linux/linkage.h>
#include <linux/kernel.h>

asmlinkage int sys_mycall(int i) {
   return i+10;
}

Now create and edit file /usr/src/linux-3.2.29/randomsys/Makefile

obj-y    := sys_oddrandom.o
obj-y    += sys_evenrandom.o
obj-y    += sys_mycall.o

Next, compile our kernel and its modules. Invoke this command:

make

The process could be 1 to 4 hours depending on your system performance. For old machine like mine, it could be around 4 hours to do so. In this step the compiled kernel is stored in binary form as arc/x86/boot/bzImage file. Based on kernel headers it will compile the kernel modules (device driver, filesystem, network, etc) and generate .ko files which are kernel objects. These modules also called Loadable Kernel Modules (LKM).

Next, we will install kernel modules. to do so we can invoke

make modules_install

This step will copy all kernel modules (*.ko) to /lib/modules/<version>/kernel/ folder.

Next we will install the kernel itself. We did that by invoking

make install

This step copy the arch/x86/boot/bzImage to /boot folder and copy the .config to /boot/config-<latest version> and generate System.map file.

Next we need to create initramfs file. Next time I would write article about initramfs, but for this time just do so.

update-initramfs -c -k <version>

Here <version> can be 3.2.29 for this case.

Next we have to update the boot loader. I’m using GRUB so we have to invoke:

update-grub

This command automatically probe the kernels in /boot folder and add the entries in configuration file, grub.cfg

Restart the system and look at your bootloader entry. choose the new kernel in bootloader. Now open terminal and invoke

uname -r

Congratulations, you have build new kernel with our own syscalls now! Let’s test now.

Create 2 file: testmycall.h and testmycall.c. You can place it anywhere you want.

Now, open and edit testmycall.h

#include <linux/unistd.h>

#define __NR_oddrandom 349
#define __NR_evenrandom 350
#define __NR_mycall 351

unsigned int oddrandom() {
   return syscall(__NR_oddrandom);
}
unsigned int evenrandom() {
   return syscall(__NR_evenrandom);
}
unsigned int mycall(int i) {
   return syscall(__NR_mycall,i);
}

You must have known what those numbers are, aren’t you? 🙂

Now open and edit testmycall.c

#include <linux/unistd.h>
#include <sys/syscall.h>
#include "testmycall.h"

int main() {
   unsigned int v1=0,v2=0;
   int keluar=0;

   v1 = oddrandom();
   v2 = evenrandom();
   keluar = mycall(10);

   printf("v1         = %u\n",v1);
   printf("v2         = %u\n",v2);
   printf("keluar     = %d\n",keluar);

   return 0;
}

Compile and see the result by yourself 🙂

What is Initial Ramdisk?

November 24, 2015 | Article | 2 Comments

Initial ramdisk is a scheme for loading a temporary filesystem into memory in the boot process of the Linux kernel. You could say it is a pseudo filesystem reflect / mirror to system. There are two scheme, initrd and initramfs. They are refer to slightly different methods and commonly used to make preparations before the real root filesystem can be mounted.

Many Linux distributions ship a single generic kernel image. They do that as they expect a wide variation of user’s hardware that might be met and thus the kernel need to be as flexible as possible. Therefore, developers need to avoid to hardcoded handling for so many special cases into the kernel body but still have to handle thus cases. The initial boot stage with a temporary root filesystem is used. This root filesystem can contain user-space halpers which do the hardware detection, module loading, and device discovery necessary to get the real root filesystem mounted.

As said before, initial ramdisk is an image of initial root filesystem (along with the kernel image), it must be stored somewhere accessible by the Linux bootloader or the boot firmware.

Prior to linux version 2.6.12, Linux use initrd scheme. The image may be a filesystem image (optionally compressed) which is made available in a special block device (/dev/ram) that is then mounted as the initial root filesystem. Once the initial root filesystem is up, the kernel executes /linuxrc as its first process. When it exits, the kernel assumes that the real root file system has been mounted and executes “/sbin/init” to begin normal user-space boot process.

In initramfs (Linux 2.6.13 onward) scheme, the image may be a cpio archive (optionally compressed). The archive is unpacked by the kernel into a special instance of a tmpfs that becomes the initial root filesystem. With this scheme, there is no requirement of intermediate filesystem or block drivers to be compiled into kernel.

Compiling Linux Kernel, Step by Step

November 24, 2015 | Article | 4 Comments

— This is old article I wrote on my old Nest —

Recently I was doing some linux kernel compilation for a course homework. I did it manually. Someone said it’s so complicated so I will share my guide for linux kernel compilation. Here I use the most recent kernel version as October 9th, 2012. The version is 3.6.1. All operations are performed on Ubuntu distribution.

Check for your current linux kernel version. You can do it by typing this on your terminal.

uname -r

or

cat /proc/version

Now download the latest kernel at http://kernel.org/ website. In this tutorial we would use kernel version 3.6.1.

wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.6.1.tar.xz

The reason I used linux-3.6.1.tar.xz instead of linux-3.6.1.tar.gz or linux-3.6.1.tar.bz2 is simply because of download size.We will following a convention or common practice of kernel building so we will use /usr/src directory. Make sure you move the source to /usr/src/ directory. Do that using root access.

Now extract the source code.

tar -Jxf linux-3.6.1.tar.xz
cd linux-3.6.1

In linux-3.6.1 folder there would be some files and folders. Some of them used as special purpose as:

arch – describe all architecture support by kernel
crypto – contain cryptographic implementation like AES, DES
drivers – all drivers modules (ID, SCSI, Ethernet device, Wireless)
fs – all filesystem implementation (ext4, FAT, NTFS)
net – all network protocol implementation (IPv4, IPv6, tcp, 802.11)

Now let’s configure our kernel source. The kernel compilation need a configuration file that contain lots of variable to help to understand what modules we need to compile. Specific kernel variable can be found at kernel.org

We can take the old configuration as our basis for creating configuration file.

cp /boot/config-2.6.35.22-generic .config

Note that I use kernel 2.6.35.22-generic so I copy the configuration file. It can be different in your system so match the version number with your current kernel version.

It’s a wise way to see what we can do by invoking make. A little help could give us hint.

make help

Now, to configure the config file, invoke

make menuconfig

After deciding what configuration you choose, It’s time for compilation. We will using generic way of compilation. It is the standard way provided by kernel and not platform oriented.

To compile the kernel and its modules we can invoke:

make

The process could be 1 to 4 hours depending on your system performance. For old machine like mine, it could be around 4 hours to do so. In this step the compiled kernel is stored in binary form as arc/x86/boot/bzImage file. Based on kernel headers it will compile the kernel modules (device driver, filesystem, network, etc) and generate .ko files which are kernel objects. These modules also called Loadable Kernel Modules (LKM).

Next, we will install kernel modules. to do so we can invoke.

make modules_install

This step will copy all kernel modules (*.ko) to /lib/modules/<version>/kernel/ folder.

Next we will install the kernel itself. We did that by invoking.

make install

This step copy the arch/x86/boot/bzImage to /boot folder and copy the .config to /boot/config-<latest version> and generate System.map file.

Next we need to create initramfs file. What is iniramfs? You can find out here.

update-initramfs -c -k <version>

Here <version> can be 3.6.1 for this case.

Next we have to update the boot loader. I’m using GRUB so we have to invoke:

update-grub

This command automatically probe the kernels in /boot folder and add the entries in configuration file, grub.cfg

Restart the system and look at your bootloader entry. choose the new kernel in bootloader. Now open terminal and invoke.

uname -r

The kernel version should be 3.6.1 now.

Social media & sharing icons powered by UltimatelySocial