Minimal (<10MB) base Linux/Gentoo system
Content on this page is probably outdated and represents my personal knowledge, feelings and understading of things at that time .
For a school assigment I had to do, I chosed the creation of a minimal linux live cd that boots up to some sort of a shell. I also got bonus points if I can get it under 10MB.
As a longtime Gentoo user I created a chroot and first tried trimming the standard base system down. But as I soon found out, that won’t work, at least not to the extend I wished to. And then I found the Tiny Gentoo wiki page describing an alternative option.
Unfortunately the TinyGentoo wiki page is a bit of a mess and sometimes outdated. (I’m still thinking if I should clean it up or create a separate wiki page based on my work.) Because of that I encountered quite some bugs/problems and solved/hacked together a solution for most of them.
So basicly, what do you really need for a Linux system to boot up. Ofcourse, you need the Linux kernel and a bootloader (Grub2 was my choice). For the next stage, you need a C library and a Shell with some standard commands/utilities. I chose those two from a standard embedded setup, namely uClibc and BusyBox. Next thing you need is some kind of a init system. BusyBox has it built in, but I chosed to go with OpenRC/baselayout. Now that we know all the “components” we will need, let’s try to compile and glue everything together.
As previously stated, this guide is heavly based on TinyGentoo and work of judepereira. It is also recommended that you have previous experiance with Gentoo and Gentoo installed on your workstation, but it is not a requirement.
In the process of writing this, it came to my attention that someone has recently done a similar tutorial: http://www.anticore.org/ratgentoo/
Teh guideFirst, you need to create a working directory, you don't need too much space - a few GB should be enough. Let's call this directory $MINI_ROOT.
Download the latest x86 uClibc stages from judepereira's blog and extract it to $MINI_ROOT.
Now we need to do some standard chores before we can chroot:
- "cp -L /etc/resolv.conf $MINI_ROOT/etc/resolv.conf" - for internet connectivity
- "mkdir -p $MINI_ROOT/usr/portage"
- Now if you have Gentoo installed on your workstation:
- "mount --bind /usr/portage $MINI_ROOT/usr/portage" - to avoid downloading the distfiles
- From the closest Gentoo mirror download the lasted portage snapshot
- Extract it in $MINI_ROOT/usr/portage
- "mount --bind /dev $MINI_ROOT/dev"
- "mount -t proc proc $MINI_ROOT/proc"
- "chroot $MINI_ROOT /bin/bash"
- "source /etc/profile"
- "ln -snf /usr/portage/profiles/uclibc/x86 /etc/make.profile" - symlink the appropriate profile
- "emerge -uDNav world" - we carefully update world. Please READ all the messages portage gives you and act accordingly.
Now we are ready to preapare our root FS. Create a directory inside your chroot where the root FS will reside. Let's call this directory $TARGET_ROOT. You also need to create "$TARGET_ROOT/proc" and "$TARGET_ROOT/sys".
Now it's time to install the packages.
"ROOT=$TARGET_ROOT USE=make-symlinks emerge -avkN baselayout uclibc busybox openrc mingetty" - this can take some time. Make sure the patched uclibc gets pulled in [insert patch notes here].
When portage finishes, you have to do some minor corrections:
- "cp /usr/lib/gcc/i386-gentoo-linux-uclibc/4.5.3/libgcc_s.so.1 $TARGET_ROOT/usr/lib/" - because even with static cimpiling, openrc doesen't compile fully staticly.
- "cp /misc/inittab $TARGET_ROOT/etc/" - copy the modified inittab
- "cp /misc/init $TARGET_ROOT/" - copy the init script
- edit "/etc/fstab", by default nothing in there is needed
- "adduser -h / -s /bin/ash -G users USERNAME"
- "rc-update del netmount default"
- "rc-update del net.lo boot"
- "rc-update del sysctl boot"
- "mkdir -p /tmp/iso/grub/" - create the directory structure
- "cp /boot/grub/stage2_eltorito /tmp/iso/grub/" - copy grub stage 2
- Create menu.lst in the grub directory, there is a sample in /misc/
- "cp -r $TARGET_ROOT /tmp/$TARGET_ROOT" - copy the target root for additional cleaning
- "rm -r /tmp/$TARGET_ROOT/var/*/* /tmp/$TARGET_ROOT/tmp/*" - more aggresive cleaning
- "cd /tmp/$TARGET_ROOT && find . | cpio -H newc -o | gzip -9 > /tmp/iso/initramfs-tinygentoo.igz && cd .." - Create initramfs
- "emerge -av gentoo-sources"
- "cd /usr/src/linux"
- "make menuconfig" - the only thing you really need is initramfs support
- "cp arch/i368/boot/bzImage /tmp/iso/boot/vmlinuz"
- "make INSTALL_MOD_PATH=$TARGET_ROOT modules_install" - if you have any modules, you need to recreate initramfs after this.
Some general tips:
- "dispatch-conf $TARGET_ROOT" - update config files in $TARGET_ROOT
- Use saved-config for tweaking (busybox/uclibc)
Notes about the custom ebuildsThere is a custom uClibc ebuild for version 0.9.30.1 that applies a simple patch that makes the uClibc compile. I would suggest that you first try to compile the latest stable and unstable uClibc ebuilds and resort to this ebuild (uclibc 0.9.30.1-r2).
Also, there are some sample configs for busybox and uclibc versions provided, because sometimes busybox doesen't compile and the easiest solution is to remove some parts of it. Note: this guide relies on the saved-config of busybox to compile with mdev support, the same could be achived with mdev use flag.