Tuesday, March 23, 2010

Anatomy of initrd image

Lets say, you have a Linux Installer CD/Live CD, and you want to know what your system does immediately after booting kernel. initrd image is the place you might want to look at.
Initrd is actually a zipped , cpio archive of the hierarchy of directory structure. It contains init script aka mother of all processes. copy your initrd image into tmp folder. Then issue the following command.

$gunzip initrd.gz
$cpio -id < inird


This will create the entire directory structure. you will find 'init' as executable. If you are using a Linux-installer CD OR Live DVD chances are the initrd image uses busybox.

Happy Exploring.

Monday, March 8, 2010

QuickHowto: Building Real time Linux using RTAI


I have always been interested in Real-Time Kernels and O.S.es. I have started looking for Real time version of Linux almost immediately since I started working on Linux. There are multiple solutions out there to address the problem of making regular Linux-kernel into RTOS. While scanning through them I came acorss RTAI (Real Time Application Interface). This is Free, comes with good docmentation and RTAI addresses the problem neatly. Did I mention that RTAI is actively developed? Check out www.rtai.org

I have decided to build my own free usable realtime linux that could run on regular PC. This is what i did:

1) get the latest kernel image
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.tar.bz2

2) Download latest or one of the rtai package from www.rtai.org. My firefox firefox 3.6 didnt let me open this site.
So I tried in Firefox 2.0 and 2.0 complained about certificate but it let me open the page after i asked the browser to ignore.
I downloaded rtai-3.8.tar.gz

3) Now, untar the Linux kernel and rtai images. you will find directories linux-2.6.23/ and rtai-3.8/

4) Explore the direcotry rtai-3.8/ There are kernel patches for 2.6.20,2.6.22,2.6.23 under
rtai-3.8/base/arch/i386/patches

5)Patch the kernel.
$cd linux-2.6.23/ $patch -p1

Compile the Linux Kernel

6) Now, configure the kernel.
$ make menuconfig
Make sure the loadable kernel module is enabled.

7)compile the kernel with 'make' The linux kernel successfully compiles.

Compile RTAI - Kernel

8) inside rtai-3.8/ directory,
$make menuconfig
Under General -> Change the Linux directory and final installation directories to point to appropriate directories.
Under Machine (x86) -> make sure the number of CPUs in your machine is given correctly.
$ make
this will compile the RTAI referring your patched-kernel source.
$ make install

Testing
Now, you have RTAI as well as Linux kernel. You can either do "make install" the kernel. Or you can use test this realtime kernel with just initrd, which i will do next.
Create your own initrd image. I am going to just follow the steps explained my previous post. Basically, this should result in a system directory structre based on busybox. Create a linux system directory structure. additionally create realtime/ directory under usr/. Then Copy all realtime/ folder contents installed form previous step into it.
So your "root" directory structure should look something like this.

[root@sm initramfs-rtai3.8]# ls -lhrt
total 36K
drwxr-xr-x 2 root root 4.0K 2010-03-08 17:31 sys
drwxr-xr-x 2 root root 4.0K 2010-03-08 17:31 sbin
drwxr-xr-x 2 root root 4.0K 2010-03-08 17:31 proc
drwxr-xr-x 2 root root 4.0K 2010-03-08 17:31 newroot
-rw-r--r-- 1 root root 20 2010-03-08 17:31 initramfs.igz
-rwxr-xr-x 1 root root 1.2K 2010-03-08 17:31 init
drwxr-xr-x 2 root root 4.0K 2010-03-08 17:31 etc
drwxr-xr-x 2 root root 4.0K 2010-03-08 17:31 bin
drwxr-xr-x 3 root root 4.0K 2010-03-08 17:31 usr

Then from inside your directory strcuture issue folllowing command

[root@sm initramfs-rtai3.8]# find . | cpio -H newc -o > ../initramfs.-rtai3.8.cpio
This creats your own initrd image. So, you have initrd , kernel are ready. Recollect that we have copied all "realtime" directory into initrd. Once these two are ready you can test it with qemu.

# qemu -kernel /mnt/lfs1/linux-2.6.23/arch/i386/boot/bzImage -initrd initramfs.-rtai3.8.cpio -append "root=/dev/ram" /dev/cdrom

This opens a new PC-emulator window and loads kernel and initrd image, runs the kernel.


Reference:
* This is a very good and latest tutorial on howto compile kernel. http://www.cyberciti.biz/tips/compiling-linux-kernel-26.html
* A good Howto on howto create initramfs image is here. http://jootamam.net/howto-initramfs-image.htm It works for me.

Sunday, March 7, 2010

In-Memory Linux

Aim is to create my own Linux distribution which runs completely runs in-memory. The Linux should be minimal at the same time functional.

In order to achieve this, you need 2 things: 1. Kernel of your choice 2. Initrd image

Kernel
1) Download the kernel of your choice. using
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.tar.bz2
2) unzip the bz2 image
''tar -jxvf linux-2.6.23.tar.bz2''
3) make sure the following is enabled in kernel configuration
General Setup --->

[* ] Initial RAM filesystem and RAM disk (initramfs/initrd) support

() Initramfs source file(s)
4) just make the kernel. Need not do make install. The bzImage is available in ''linux-2.6.23/arch/i386/boot/bzImage''


Prepare Initrd image

Initrd image is nothing but a small filesystem that contains mini linux system - shell and all supported commands etc. You can put your own programs also into this.
Most lightweight linux systems use busybox as their all-in-one utility program. busybox is a single binary that acts as common programs like ls,pwd,time,date etc. So, download busybox from www.busybox.net and compile it using make menuconfig & make commands. you will find busybox executable in the busybox folder itself. Make sure to configure the busybox to link statically all "applets". Applets are the individual programs.

1) in your work directory, create a directory called initramfs
2) create bin sbin etc proc sys newroot directories under initramfs directory.
''$ mkdir -p initramfs/{bin,sbin,etc,proc,sys,newroot}
$ touch initramfs/etc/mdev.conf ''
3) copy the busybox executable into ''initramfs/bin/''
4) create softlink called sh in bin.
'' $ ln -s busybox initramfs/bin/sh''
5) in initramfs directory create a ''init'' script file. This is the script that is run as pid=1 by Kernel.
~~~~~~~
''#!/bin/sh

#Mount things needed by this script
mount -t proc proc /proc
mount -t sysfs sysfs /sys

#Disable kernel messages from popping onto the screen
echo 0 > /proc/sys/kernel/printk

#Clear the screen
clear

#Create all the symlinks to /bin/busybox
busybox --install -s

#Create device nodes
mknod /dev/null c 1 3
mknod /dev/tty c 5 0
mdev -s

#Function for parsing command line options with "=" in them
# get_opt("init=/sbin/init") will return "/sbin/init"
get_opt() {
echo "$@" | cut -d "=" -f 2
}

#Defaults
init="/sbin/init"
root="/dev/hda1"

#Process command line options
for i in $(cat /proc/cmdline); do
case $i in
root=*)
root=$(get_opt $i)
;;
init=*)
init=$(get_opt $i)
;;
esac
done

#Mount the root device
mount "${root}" /newroot

#Check if $init exists and is executable
if [[[ -x "/newroot/${init}" ]] ; then
#Unmount all other mounts so that the ram used by
#the initramfs can be cleared after switch_root
umount /sys /proc

#Switch to the new root and execute init
exec switch_root /newroot "${init}"
fi

#This will only be run if the exec above failed
echo "Failed to switch_root, dropping to a shell"
exec sh''

~~~~~~~~~
6) create softlinks for mount,echo and clear in initramfs/sbin
''$ln -s initramfs/bin/busybox initramfs/sbin/mount
$ln -s initramfs/bin/busybox initramfs/sbin/echo
$ln -s initramfs/bin/busybox initramfs/sbin/clear''

7) inside initramfs, execute following command to create a cpio archive
''$ cd initramfs
$ find . | cpio -H newc -o > ../initramfs.cpio
$ cd ..
$ cat initramfs.cpio | gzip > initramfs.igz
''
Now, Initrd image is ready.

Testing

I. Using a emulator - QEMU
qemu is a PC emulator. You can download the qemu from internet. Once installed, You can test your images using following command.

''qemu -kernel /boot/bzImage -initrd /boot/initramfs.igz -append "root=/dev/ram" my_iso/rawimage''

II. Booting your PC with newly created images
Copy newly built kernel image and initramfs.igz image into /boot directory
Create new entry in grub/menu.lst
Restart your PC and choose the new kernel to boot with.
The PC should start and provide you a prompt. Now the PC runs completely on RAM. Go ahead explore the system.

In a typical Server/Desktop environment, Initrd contains specific programs that will further load necessary applications even do second stage of booting. In embedded
systems initrd IS the filesystem. Initrd provides simple "container" of your own programs that boot loader iteslf loads as part of bootprocess.

Happy Exploring.