This was way harder than it should have been. You would imagine if you just have a bootloader, a kernel, and a filesystem you’d be ready to go.
Most of the “minimal linux build tutorials” are really dated.
In fact, I think because Linux From Scratch is around, most people just point to that and think we don’t really need tutorial for building a simple working system.
Well LFS is certainly not ‘minimal’. It’s a monster, at over several hundred megabytes. Not to mention it takes a good deal of time. I want something I can do pretty quickly.
For the longest time, I was stuck with a working chroot environment, but It was not easy getting it to boot.
Then I came across this blog. At first it looked like it was made just for me. The only posts are about putting together a minimal bootable environment and it’s recent — 2012!
Well it was a bummer. It stopped just before booting the environment.
But I actually got it to work. A working, super minimal, Busybox environment. Here’s my story.
In particular, you want to have a Virtualbox hard disk installed with Debian. It can actually be any Linux, but in case you’re wishy washy, Debian is pretty good for playing around with, especially because when you install it, tasksel comes up and asks you what you want, and you can unmark the desktop and base utils. As far as I can tell, I don’t think Ubuntu let’s you opt out of things too easily.
Furthermore, you might want to get Virtualbox Guest Additions — not only is it nice to have the additions, but you will also need the build tools.
Step 1: Add A hard disk
A picture is worth a thousand words:
It if this isn’t clear, add a comment saying so. But it should be.
Once you get there, choose to add “A New Hard disk”. And you’ll get the standard hard disk creation dialogue you get when you create a new virtual machine.
Well this is going to be where we’re going to build our new minimal Linux distro.
Yea you know most other tutorials about this stuff wants you to make a separate partition. Ugh!! It’s actually not that bad, but with modern technology (i.e. Virtualbox) we can avoid it pretty easily.
Step 2: Build a kernel
Since our new disk has nothing in it, you should boot into Debian. I know it’s usually bad advice to do things as root when you don’t need to, but I just found it convenient to stay root throughout this tutorial, so I’m going to (If you’re like me, and you just made this a spare Debian install so you could mess around with things, it really shouldn’t be a problem — I set up my Debian box half expecting something to go terribly wrong). If you’re not logged in as root, you can just su or sudo when appropriate.
to get the kernel source type (you can check which one’s the most recent on kernel.org):
to build the kernel:
tar jxf linux-3.2.7.tar.bz2 cd linux-3.2.7/ make defconfig && make
If you were really out to make a minimal kernel you could follow Nasir’s bit on kernel building, but quite frankly, your kernel will probably not be over a dozen megabytes at most even if you use defconfig. However, if you do it Nasir’s way you might also get shorter compile time. Pick your poison.
Once the compilation finishes (it could take a while, but probably not more than half an hour on a reasonably modern machine), you will find your kernel at arch/x86/boot/bzImage. In fact, It will even tell you at the end of the build.
Step 3: Get Busybox
You can download a statically linked Busybox executable from:
This is probably another place you could hail modern technology. For those of you who don’t know what Busybox is, the Busybox multiplexer is a single program that can be called and used as many different programs.
For instance, try
It gets even better:
ln busybox ls ./ls
Before Busybox you probably had to fetch all the different executables and libraries to get all the essential software to work (you would have to get core-utils and required libraries). Busybox is a single executable that can be used as a shell (ash), ls, ps, mkdir, cd, etc. You can also follow Nasir’s build method, but as far as I can tell, I don’t really see the benefit. The static Busybox executable is small enough for me to begin with, so it’s all good.
Also you should note that we got the static Busybox executable. In case you don’t know what a static executable is, a dynamic (i.e. non-static) executable depends on external libraries, so if we want a dynamic executable to work in a different hard disk, or even a different partition, we often need to copy over the libraries. If you build Busybox from source, by default it is set to build dynamically.
Step 4: Build the root file system
Actually here, I’m just gonna stick to Nasir’s method, so you could probably just follow the instructions there.
For completeness I’ll list the directions here.
We’re gonna build the initrd system. Most of the following should be self explanatory. I might post about mknod later, but it probably isn’t too hard to find the info on Google.
Btw, make sure you’re not still in the kernel source directory. There’s nothing wrong with doing it there, but it isn’t a pleasant thought for me.
mkdir rootfs cd rootfs mkdir dev proc sys tmp mknod dev/console c 5 1 cat >> init << EOF #!/bin/ash mount -t proc none /proc mount -t sysfs none /sys /bin/ash EOF chmod +x init
Now that we have our file system pretty much set up, we want to package it.
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz cd ..
Step 5: Format the Disk
Your disk is probably on /dev/sdb.
and create a single partition taking up the entire disk.
Also mark the partition bootable.
Now the file /dev/sdb1 should exist. You should be able to run:
to format the partition.
Step 6: Get Grub
Almost there!! — After this step, you get to boot into your personally assembled Linux environment!
Now we actually want to put stuff into our other disk, /dev/sdb1. Run
mount /dev/sdb1 /mnt
So that we mount the /dev/sdb1 partition on /mnt. Now we can put stuff in sdb1 by putting stuff in /mnt.
You probably have grub installed. I’m also going to take a reasonable leap of faith and say you have grub2 installed.
grub-install --root-directory=/mnt /dev/sdb
For more info on Grub2 see this post.
Step 7: Boot!!
Lol. There’s actually little more work to be done.
Create a new virtual machine, except this time, instead of creating a new virtual hard drive, choose to use an existing one, and pick the one that you’ve been working on.
You’re going to see the grub boot prompt.
set root=(hd0,msdos1) linux /bzImage initrd /rootfs.cpio.gz boot
And after the messages seem to stop, type enter.
Now type in a command (e.g. ls).
Doesn’t Busybox ls look nicer than with barebone Debian?
Now you’re in a personally assembled Linux environment!!
There’s a lot that could improve. For one, I could get grub.cfg set up so that you don’t have to type in boot info everytime you boot. Another thing — we’re really only in the initrd filesystem. An improved version of this tutorial should really cover how to at least access the real file system.
If you liked this tutorial, and fix it up a little, give me the link so I can link to your post — I believe in multiple versions of similar posts. That way we can choose.