Thursday, October 20, 2016

Running a simple C program with Linux kernel

HelloWorld program as the init process
In this post, I'm writing down the steps I followed to compile Linux kernel and run it with a simple C program I wrote. First of all, we need to get some packages. I tried this on a 64-bit Ubuntu 16.04 machine.

sudo apt-get update
sudo apt-get install build-essentials libncurses5-dev libncursesw5-dev
sudo apt-get install gcc-multilib
sudo apt-get install qemu

After installing the required packages, let's create a directory for our working environment and then continue the rest there.

mkdir mylinux
cd mylinux
vim init.c

Inside the newly created C source file, insert the following code which will print the text "Hello World!" once compiled and run.

#include <stdio.h>
 
void main() {
  printf("Hello World!\n");
  while(1);
}

Now, run the following commands to compile the program and create a ram disk which will be used by the Linux kernel later. The selection of the file name init.c is special here because that is the name of the first process created by Linux kernel after booting up.

gcc -static init.c -o init
echo init|cpio -o --format=newc > initramfs


It's time to get the source code of the Linux kernel. Download it into the directory we created previously and build it by following the commands shown below.

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.8.1.tar.xz
tar xvJf linux-4.8.1.tar.xz
cd linux-4.8.1/
make defconfig
make


The above operation will take a significant time since the Linux kernel is a huge source code base which need to be compiled one by one and brought together to build the executable monolithic image. After the build process completed, you should be able to find the compiled kernel image in the following location.

linux-4.8.1/arch/x86_64/boot/bzImage

Now, let's run our program with the Linux kernel image on QEMU emulator using the following command.

qemu-system-x86_64 -kernel linux-4.8.1/arch/x86_64/boot/bzImage -initrd initramfs -append "console=tty1"

You should be able to see that the Linux kernel boots up and then it runs our init program at the end. Our program prints the "Hello World!" message and then hangs inside the infinite loop.

No comments:

Post a Comment