October 14, 2010

Building a GNU/Linux system from scratch and running it with UML

Filed under: GNU/Linux, Projects — Tags: , , , , — shijitht @ 12:23 am

Other than installing the system from the precompiled binaries, we could build it from scratch. The scratch means, building every element that makes our system, entirely from source code !!!. This is a !!! now, but in older days this was a necessary installation routine for linux lovers. Since we are new to this process proper documentation is needed to build the system. A fantastic Linux From Scratch(LFS) project is there to help us. Go to http://www.linuxfromscratch.org/. With proper description of each step, this project is the best to start for a beginner.

After system build, we can use it on a physical drive as per the documentation. Compile a proper kernel and write it on a drive to boot from it. But this article covers using uml. UML means User Mode Linux. Run linux on top of current linux kernel instead of bare hardware. We can test the new system, above a uml kernel.  While running a uml kernel, we can specify virtual resources such as root file system, swap, hardware etc.

Why build from source ?

You will have a question that, why build from source when a lot distros are available, which could be installed easily with a few mouse clicks ?. The aim of installing from scratch is to make a proper understanding of our system software internals. You can see the use of each package, its contents, size and the commands and scripts to build it. With intelligent package managers, we are unaware of the horrible dependency relations between packages. When you finish compiling the system, you can also get an awareness about the effort people put in making it.


Uml kernel runs on top of system kernel in user space. Being a user process, privileged direct hardware access cant be made in uml kernel. So these are converted to system’s native calls. These calls are usually in arch folder of kernel. This make the creation of UML kernel easier because only the arch section differs. Only that folder needs rewrite. Another simple technique is used to execute processes inside uml system. An executing process is traced using ptrace. On a system call the process is stopped and it’s called address is replaced by the address of system call in real kernel. Then the stopped process is continued.

Building UML kernel

Follow these steps to create a uml kernel binary.
Download a stable kernel source from kernel.org.
Untar and cd to that folder.
Give these commands in the command line.
# make defconfig ARCH=um
will produce a .config file with default configuration for uml.
# make menuconfig
if desired
# make menuconfig ARCH=um
to produce a custom kernel
# make mrproper
# make mrproper ARCH=um
to get rid of all traces of whatever building you did, and start over.
# make ARCH=um
starts build
On completion, you can see a uml binary called “linux” of size ~25M.
Strip off debugging symbols to cut size.
To test this kernel start it with ubda=< FILE SYSTEM > option.

Creating file system

We can use a virtual file system to check the above kernel.
Use dd command to create a file of 6 GB.
# dd if=/dev/zero of=fs bs=1G count=6
will copy 1G from /dev/zero 6 times measuring a total of 6G.
Now create a file system of type ext3 using mkfs.ext3.
# mkfs.ext3 fs
give yes when prompted and it will produce a virtual file system of type ext3.
Use loopback to mount it
# mount -o loop fs /mnt/lfs
will mount fs -> /mnt/lfs
Loop back device /dev/loop0 is used for mounting this file. Through this device we can use the file as we are accessing a block device.
Next step is to make all programs inside fs which will help us use the system.

Creating files(programs)

Our system needs a lot of programs and tools for proper functioning. This include the init process, the first process which loads at boot. Then bash to interact with user and various tools to do tasks like compilation(gcc). The proper documentation for building is given at linuxfromscratch.org. So repeating them again will be a waste of time. Go to LFS site and follow the step by step instructions to build a working system. Do the version check as per the documentation to make sure you meet all the prerequisites. Also some errors might happen if texinfo packages is missing. You can come back, when you finish setting up system boot scripts.

Booting in uml

Make some changes to what you have done.
Edit /etc/fstab
When booting with uml we specify ubda as the root file system device.
So add it to fstab instead of what is there as root device.
/dev/ubda    /    ext3    defaults    1    1
Edit /dev/inittab
Comment all agetty lines and add this line instead
1:2345:respawn:/sbin/agetty tty0 9600
Now you are ready to boot with uml.

Power ON

Unmount the file system
# umount /mnt/lfs
Use the uml kernel produced(“linux”)  to start the system
# ./linux ubda=< PATH TO fs >
This will take you to a new virtual system build with your hands.


Building a Gnu/linux system from scratch is an experience which will take you to each and every corner of your system. Familiarizing with many commands and scripting techniques will increase knowledge. The role of each package is clearly understood while building from source. Now we know, what each package has and depends on. So later a much lighter system can be built with a custom configuration as per demands. Very small(~4M) systems can be built, which could be used in embedded systems. If we use uml, no restart is needed to test or boot a system. Also an exposure to virtualization can be gained with uml. LFS project has a documentation that any beginner can follow. Building a linux system from scratch is something that every linux enthusiast must do.

Blog at WordPress.com.