This article discuss about how to create a customized Linux OS using bare minimum components. The target audience are Linux kernel enthusiast and developers. It demonstrates a simplified approach for building Linux system.
Let’s get started by downloading latest Linux kernel source code from www.kernel.org . The latest source code package can be found at http://www.kernel.org/pub/linux/kernel/v2.6/
For building the kernel we require a Linux host system with compiler tools installed on it. If you have chosen “Software Development Packages” at the install time then you already have necessary build tools on host machine.
For this demonstration I have used linux-2.6.35.tar.bz2 and Fedora Core 11. We will be using Fedora Core as our host system (base system) for building custom Linux OS.
Building Kernel
The first step in kernel compilation is, configuration. Extract the kernel package and execute the following command:
make menuconfig
Since we are building a minimalist kernel, only required features should be selected in configuration. The configuration is saved in .config file in current directory. The configuration file consist of list of features we need in kernel. The feature can be part of kernel image (selected as <*>) or as a separate loadable module (selected as <M>). File system modules like ext2 or ext3 should be part of kernel as it is required to mount root file system during boot time. Support for add-on cards like Ethernet, Audio can be compiled as separate loadable modules to minimize kernel boot image.
make bzImage
The above command will compile kernel. The kernel image will be created in folder linux-2.6.35/arch/x86/boot/bzImage
make modules
This command will compile Linux modules. The modules are built in linux-2.6.35\drivers directory. Modules are also called kernel objects hence named as *.ko files.
Preparing File System
For booting the compiled kernel we need to prepare a hard disk drive. Connect the target hard drive to host system and create partition using fdisk command.
fdisk /dev/sdb (where, sdb is the drive on which the kernel is to be installed)
Execute “n add a new partition” to create root partition.
Select “p for primary partition” and partition number as 1 with rest of the parameters kept as defaults. Select “w write table to disk and exit”.
Format the partition using mkfs.ext3 /dev/sdb1
Now mount the /dev/sdb1 and create following directories on root file system:
bin dev etc lib proc sbin sys usr
Copy following binaries in /bin directory. The binaries are copied from host system’s /bin directory to target hard drive.
bash cp df echo ping mkdir ps sh uname cat date dmesg ls mount pwd umount
Copy following binaries in /sbin directory. The binaries are copied from host system’s /sbin directory to target hard drive.
modinfo modprobe ifconfig fdisk lsmod rmmod
Copy following libraries in /lib. The libraries are copied from host system’s /lib directory to target hard drive. These libraries are needed as dependencies for the above binary files:
ld-linux.so.2 libblkid.so.1 libidn.so.11 libresolv.so.2 libtinfo.so.5 libacl.so.1 libc.so.6 libncurses.so.5 librt.so.1 libuuid.so.1 libattr.so.1 libcap.so.2 libproc-3.2.7.so libselinux.so.1 libaudit.so.0 libdl.so.2 libpthread.so.0 libsepol.so.1
The library dependencies for a given binary can be found out by ldd command. All the required libraries must be copied in target hard drive /lib directory for proper working of binaries.
Create /lib/modules/2.6.35/kernel/drivers folder on target drive and copy required modules from drivers folder (These modules are copied compiled kernel folder). It is important to maintain the folder structure while copying kernel modules. For example the location of scsi_transport_sas.ko would be /lib/modules/2.6.35/kernel/drivers/scsi/scsi_transport_sas.ko
Create /lib/modules/modules.dep and copy relevant entries from host system’s modules.dep. This file will be used by modprobe for resolving module dependencies.
Copy device nodes from from host system /dev directory to target /dev directory:
cp –a <host_system>/dev/sda* <target_system>/dev
Create /sbin/init script on target drive with following contents:
-------------------------------------------------------
#!/bin/sh
mount –t proc /proc /proc
/bin/bash
-------------------------------------------------------
Init script will be executed after kernel is booted, as a first application. We are simply invoking bash shell in init.
Now copy kernel image bzImage in root partition /. With the kernel in place we are done with file system setup.
Installing boot loader
We will use GRUB as a boot loader to boot the Linux kernel.
Execute following command to install boot loader on target drive (/dev/sdb)
grub-install /dev/sdb
This command will copy necessary files from host system to target /boot/grub directory and install GRUB in boot sector. Modify /boot/grub/grub.conf to following:
-----------------------------------------------
title Custom Linux OS
root (hd0,0)
kernel /bzImage root=/dev/sda1 rw
-----------------------------------------------
Now we are ready with minimal Linux system. Connect only the hard drive on which custom Linux is installed and boot off it. It will present a bash shell on successful boot!