2024-05-15
Building a Minimal Linux System With a initramfs (ARM64)
In this tutorial we will be building a minimal linux system with a initramfs from scratch. We will also test the linux kernel using QEMU.
Dependencies
apt-get update apt-get install -y git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison cpio apt-get install -y qemu-system-aarch64 vim nano
Downloading the sources
We need to download the sources including the linux kernel and busybox.
cd ~ git clone https://www.github.com/torvalds/linux git clone https://www.github.com/mirror/busybox
In future if the builds fail you can always re-download a stable version of the linux kernel from https://www.kernel.org/ and busybox from https://www.busybox.net/downloads/
Building the linux kernel
Now we need to build the linux kernel. First we need to configure the kernel. Run the following commands:
cd ~/linux make menuconfig
You can now configure the linux kernel to your needs. To save and exit press esc
twice and press save.
make -j$(nproc)
CHECK Has there been a file created called arch/arm64/boot/Image
if not then the build has failed and you need to check the error messages and fix them.
Building busybox
Now we need to build busybox. First we need to configure busybox. Run the following commands:
cd ~/busybox make defconfig make menuconfig
IMPORTANT STEP In the busybox configuration we need to change the Build static binary (no shared libs)
to y
and then save the configuration. This configuration is stored in settings>build options>build static binary (no shared libs)
.
Now we can build busybox:
make -j$(nproc)
Now we need to install busybox to our source directory:
make install
CHECK Has there been a folder created called /busybox/_install
. This should contain the busybox binary's and the base initramfs. If not then the build has failed and you need to check the error messages and retry this step.
Creating the initramfs
Now we need to create the initramfs. Run the following commands:
cd ~/busybox/_install mkdir -p dev mknod dev/console c 5 1 mknod dev/ram b 1 0
We now need to make a init
script which will be the first thing that runs when we boot linux. Run the following command:
nano init
Or if you prefer vim:
vim init
This should put you in a text editor. Copy the following into it:
#!/bin/sh mkdir /proc /sys /tmp mount -t proc none /proc mount -t sysfs none /sys mount -t tmpfs none /tmp echo "Welcome to Linux" exec /bin/sh
Now we need to make the init script executable:
chmod a+x init
Now we need to make the initramfs:
find -print0 | cpio -0oH newc | gzip -9 > ~/initramfs.cpio.gz
Now open finder and go to your Documents/busybox
folder and you should see a file called initramfs.cpio.gz
. Drag it to your user folder and rename it to initramfs.cpio.gz
. This will be important later on.
Running the linux kernel
Now we have everything we need to run the linux kernel.
qemu-system-aarch64 -kernel ~/linux/arch/arm64/boot/Image -initrd ~/initramfs.cpio.gz \ --append "root=/dev/ram rw init=/init.sh" -nographic \ -machine virt \ -cpu cortex-a57 \ -m 2G \
This should boot linux and you should see the following:
Welcome to Linux ~ #
Congratulations you have now successfully built linux and ran it from scratch.
See also
References
Thanks to the following references, without them this tutorial would not be possible: