This guide has tons of problems (just look at the comments). Please use my new version here: https://github.com/bluedragon1221/minlinux2 instead of this old buggy one!
https://www.youtube.com/watch?v=QlzoegSuIzg
To build a minimal linux distro, we need three parts:
- The Kernel
- Userspace (busybox)
- Bootloader (syslinux)
When the system boots, it loads the kernel, which loads busybox.
Bootloader -> Kernel -> Userspace
It's bad to install locallly, so we'll do everything in an Ubuntu container.
docker run --privileged -it ubuntuYou'll notice that --privileged flag. It is required for mounting some stuff later on.
Start by updating the system:
apt updateThen we need to install some packages.
apt install bzip2 git vim make gcc libncurses-dev flex bison bc cpio libelf-dev libssl-devFirst, we need to get a kernel.
We'll start by cloning linux. We'll use the GitHub mirror, because why not?
git clone --depth 1 https://github.com/torvalds/linux.git
cd linux--depth 1 just means that it won't clone the entire git history. (That would be significantly longer)
Next, we need to make the kernel config. There's a lot of options, and I'm sure you can find some other tutorial for making a kernel config. For this, we'll just use the default options.
make menuconfigThen arrow over to < Exit >, and save the configuration.
So, without further ado, let's build the kernel.
make -j$(nproc)This will take a LONG time...
At the end, you should see a line that says:
Kernel at arch/x86/boot/bzImage is readyThis is our kernel binary. Since we'll need it later, let's copy it to another place.
mkdir /boot-files
cp arch/x86/boot/bzImage /boot-files/Busybox is a bundle of many basic linux utilities, for example ls, grep, and vi are all included.
First, let's clone the sources (this process will feel very similar to the Kernel)
git clone --depth 1 https://git.busybox.net/busybox
cd busyboxNow, we can edit the busybox config. In this one, we will need to change one option. Go to Settings ---> and toggle [ ] Build static binary (no shared libraries). This will make our build simpler; not depending on any shared libraries.
Then exit, and save changes, just like in the kernel.
Now we'll build it, just like the kernel:
make -j$(nproc)It shouldn't take nearly as long, but you never know...
Since busybox will go into our initramfs, let's make a folder for it in /boot-files:
mkdir /boot-files/initramfsNow, we'll install busybox to that directory:
make CONFIG_PREFIX=/boot-files/initramfs install
This will basically just create a bunch of symlinks in that folder
Also, we can remove linuxrc, because we don't need it.
rm /boot-files/initramfs/linuxrcThe kernel needs something to execute. It looks in /init for this file. On a normal linux system, this is a systemd binary, but here, it's just a shell script.
cd /boot-files/initramfs
echo << EOF > ./init
#!/bin/sh
/bin/sh
EOF
chmod +x ./initThis short little script will launch a shell as soon as we boot into the system.
An initramfs is a cpio archive. This archive needs to contain all of the files in initramfs/. First, let's create a list of all of those files:
find .Then pass it to cpio to create the archive:
find . | cpio -o -H newc > ../init.cpio-o creates a new archive, and -H newc specifies the type of the archive.
We don't want to create a whole partition for this device, and, luckily, we don't have to. We'll create an empty file and format it with fat.
dd if=/dev/zero of=./boot bs=1M count=50Hopefully you can spare 50M...
To format it, we'll need dosfstools:
apt install dosfstoolsThen to format it:
mkfs -t fat bootWe'll need the syslinux package:
apt install syslinuxThen we can install syslinux with:
syslinux ./bootWe need to mount that image (Here's why our container needed root privileges). Create the mountpoint, then mount it there.
mkdir m
mount boot mThen move the kernel binary and the initramfs to the image:
cp {bzImage,init.cpio} m/Now we can umount the filesystem:
umount mWe can test the image using qemu. Assuming you don't want to install qemu on your container, we'll copy the files to the host system.
docker cp {container_name}:/boot-files ~/boot-filesNow we can run ./boot with qemu:
qemu-system-x86_64 -drive format=raw,file=./boot -display gtkWe'll get a prompt that says boot: . Type,
/bzImage -initrd=/init.cpioJust wait for it to boot up, then you'll be greeted with a shell prompt!
~ # 
You can install any software that you want to the system using the following procedure:
- Build the software, with CONFIG_PREFIX=/boot-files/initramfs
- Remount ./boottom
- Delete the old init.cpioandm/init.cpio
- Create a new one, and copy it to m/
- Umount ./m