Making Own Initramfs

02 Oct 2023 - Linux Mobile

Usually people reading Initramfs or initrd will immediately think it is the root file-sytem. Actually it only runs temporarily after the kernel boots and resets PID 1, initrd does not load external modules, initramfs is a small file-system that allows the kernel to show where to store real root file-system and firmware, the path to ext-modules

Initrd is a ramdisk that supports booting and switching to the real root filesystem. Usually /sbin/initrd

Initramfs is a mini root file-system, so it will be created in the file initramfs.cpio.gz including initramfs.list (used to declare a list of files and directories running in initramfs), later it will also be separated into init_function.sh to save the files. The functions are written in the init file, shortening the init. The initramfs.cpio.gz structure is as follows:

Linux Mobile
GNU/Linux Mobile
...

initramfs/

/                
├─ sys          Used for the sysfs mount.
├─ proc         Used for the procfs mount.
├─ dev          Used for the devtmpfs mount.
├─ run          Sometimes used by programs such as cryptsetup at runtime.
├─ bin          Used for standard binaries.
├─ sbin         Used for privileged binaries.
├─ lib          Used for 32 bit libraries.
├─ lib64        Used for 64 bit libraries.
├─ mnt
│   └─root      Used as a mountpoint for the root filesystem and target for switch_root.
├─ etc          Mostly used for the ''fstab''.
└─ root         Used for the root shell's homedir.

...

Every time you add a program to run like busybox or mount, you must add the libraries and place them in the directory as above.

...

root # type mount

    /bin/mount

root # lddtree /bin/mount

   /bin/mount (interpreter => /lib64/ld-linux-aarch64.so.1)
    libmount.so.1 => /lib64/libmount.so.1
    libblkid.so.1 => /lib64/libblkid.so.1
    libc.so.6 => /lib64/libc.so.6

root # type busybox

/bin/busybox (interpreter => None)

root # type findfs

    /bin/findfs

root # lddtree /bin/findfs

root # type switch_root

    /sbin/switch_root

root # lddtree /sbin/switch_root

...

Copy the libraries libmount.so.1, libblkid.so.1, libc.so.6 to folder /lib64. Do the same for busybox, findfs, switch_root

Write the mount and rescue_shell functions in init_fuction.sh and declare them in init to use the functions. Everything added must be declared in the initramfs.list so the kernel knows and switch_root to real root file-system

...

File initramfs/init_function.sh:

rescue_shell () {
    echo "$@"
    echo "Something went wrong. Dropping you to a shell."
    # The symlinks are not required any longer
    # but it helps tab completion
    /bin/busybox --install -s
    exec /bin/sh
}

File initramfs/init:

. /init_function.sh

PATH="/sbin:/bin"
# start for real here
# temporarily mount proc,sys and dev

mount -t proc proc /proc || rescue_shell
mount -t sysfs sysfs /sys || rescue_shell
mount -t devtmpfs devtmpfs /dev || rescue_shell

# mount using findfs
mount -o ro $(findfs LABEL=pmOS_root) /mnt/root/  || rescue_shell
mount -o ro $(findfs LABEL=pmOS_boot) /mnt/root/boot  || rescue_shell

# Clean up
umount /proc
umount /sys
umount /dev

# Boot the real thing
exec switch_root /mnt/root /sbin/init

...

Create the initramfs.list file to declare directories and files for the kernel booting to real root file-system

...

# directory structure
dir /proc	755 0 0
dir /usr        755 0 0
dir /bin        755 0 0
dir /sys        755 0 0
dir /var        755 0 0
#dir /lib        755 0 0
dir /lib64     755 0 0
dir /sbin       755 0 0
dir /mnt       755 0 0
dir /mnt/root   755 0 0
dir /etc        755 0 0
dir /root      700 0 0
dir /dev       755 0 0

nod /dev/null   666 0 0 c 1 3
nod /dev/tty    666 0 0 c 5 0
nod /dev/console        600 0 0 c 5 1

# busybox
# Output file name              Input file name
file /bin/busybox               /root/initramfs/bins/bin/busybox        755 0 0

# Need real mount as busybox did not support UUID
file /bin/mount                 /root/initramfs/bins/bin/mount          755 0 0

slink /bin/findfs                       /bin/busybox                    777 0 0
slink /sbin/switch_root                 /bin/busybox                    777 0 0
# libraries required by /sbin/fsck.ext4 and /sbin/fsck
# The /lib -> /lib64 symlink is mostly harmless but its not right on arm64
slink   /lib                            /lib64                          777 0 0

# Output file name                      Input file name
file    /lib/ld-linux-aarch64.so.1	    /root/initramfs/bins/lib/ld-linux-aarch64.so.1      755 0 0
file    /lib64/libblkid.so.1            /root/initramfs/bins/lib64/libblkid.so.1            755 0 0
file    /lib64/libc.so.6                /root/initramfs/bins/lib64/libc.so.6                755 0 0
file    /lib64/libmount.so.1            /root/initramfs/bins/lib64/libmount.so.1            755 0 0

file    /init                           /root/initramfs/init               755 0 0

...

Or using mainline kernel tools:

...

linux/usr/gen_initramfs.sh -h ## auto generate initramfs.cpio

linux/usr/gen_initramfs.sh -o ../initramfs.cpio /initramfs

...

Generate initramfs.list automatically in the linux directory to build mainline kernel

...

root # linux/usr/gen_initramfs.sh ../initramfs | tee ../initramfs.list

...

Create initramfs.cpio.gz

...

root # cd initramfs

root # find . -print0 | cpio --null --create --verbose --format=newc > initramfs.cpio

root # gzip --best initramfs.cpio > initramfs.cpio.gz

...

The auto-generate initramfs tools from distro: dracut, mkinitcpio, initramfs-tools, postmarketos-mkinitfs

Reference links:

...

https://wiki.gentoo.org/wiki/Initramfs

https://wiki.gentoo.org/wiki/Initramfs_-_make_your_own

https://gitlab.com/postmarketOS/pmaports/-/tree/master/main/postmarketos-initramfs?ref_type=heads

https://github.com/Project-DragonPi/DragonRoot

http://www.aclevername.com/articles/linux-xilinx-tutorial/minimalist-initramfs.html

https://github.com/Baonks81/TegraRoot

...
 

Recent Posts:

When I went through writing cpu throttle code for tegra,... more

They Did It

30 Apr 2023 - linuxmobile

After Google, Apple and smartphone companies successfully built geo location-based... more

Because when the user buys the devices, in addition to... more

When Android and ARM were in early time, there was... more

The reason I write this article because some people asked... more

Initially, when I stepped foot in GNU/Linux, I realized that... more

If you have armhf or arm64 GNU/Linux available, it’s quite... more

First of all, GNU/Linux running mainline kernel has 2 main... more

Because Android is a fork of GNU/Linux, that means only... more

When I created my personal blog from basic jekyll barebone,... more

U Boot On Tegra Soc

12 Feb 2023 - tegra

As mentioned in the previous post, Nexus 7 2012 grouper/tilapia... more

Fosdem 2023

05 Feb 2023 - linuxmobile

This event could view online at this link. They... more

I finished barebone static blog from Jekyll documents and... more

This is hard part about Tegra 3 T30L, which I... more

This post, I share my experiences from I/O and CPU... more

I wrote some lk2nd experiences at previous post. Xiaomi Redmi... more

How the system booting!? Let’s start, since Google created compatible... more

This is the first SoC on ARM. Nvidia made ULP... more

When I wanna push source code to git, I saw... more

When I was online, I saw some github.io website. I’ve... more

 
More articles