MarkdownBlog Main Website All posts

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:

Further reading

Author

Made with by 0x4248