Last in the section We explained how to create and test an initramfs image. In this section, we want to create a minimal root directory (rootfs) and static ve dynamic We will explain the differences between the files.

Static and Dynamic compilation

Static while a file doesn't need any dependencies dynamic A compiled file has dependencies. To find out if a file is dynamic ldd command is used.

$ ldd busybox not a dynamic executable $ ldd /bin/bash (0x00007ffd63d6a000) => /lib64/ (0x00007f6121182000) => /lib64 / (0x00007f6121141000) => /lib64/ (0x00007f6120f71000) => /lib64/ (0x00007f6120f30000) /lib64/ld- (0x00007f61212d2000)

All dynamic compiled files need file and interpreter file. Other than that are dependencies from additional libraries that the application uses. The dependency tree on Linux distributions is built with these in mind.

Now let's have a C source code like the one below and compile this source code.

#include int main(){ puts("Hello Word"); return 0; }
# dynamic compile gcc -o main.dynamic main.c # static compile gcc -o main.static main.c -static

You can check both with the ldd command.

Static files are larger in size because all the required libraries are included in a single file, causing it to increase in size. That's why in distributions, dynamic compilation is generally preferred over static.

Creating minimal rootfs

Now from a dynamic compiled file rootfs Let's create. For this, let's first copy our file to an empty directory and fillet Let's find out the name of the interpreter using the command.

$ file main main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/, for GNU/Linux 3.2.0, note stripped

Burada /lib64/ file should be in the same place in our directory. For this reason, let's open the lib64 directory and copy it into it.

$ mkdir lib64 $ install /lib64/ lib64/

Linux distributions have the /lib directory. We can symlink our lib64 directory here.

$ ln -s lib64 lib

Now too ldd Let's find their dependencies using the command and copy them as well.

$ ldd main (0x00007ffd1efe6000) => /lib64/ (0x00007f0af6a13000) /lib64/ (0x00007f0af6bfe000) # interpreter We do not copy it a second time because it has already been copied. # is not found in the system as a file. It comes from the linux kernel. We don't copy it either. # In this case we just need to copy our file. $ install /lib64/ lib64

Now we have created rootfs. to test chroot /main We can use the command.

$ chroot . /main HelloWord

As you can see we got minimal rootfs and ran it. If we want, we can change our rootfs directory to initramfs. The file we compiled /init Let's put the file in its place and repackage it. As follows kernel panic it will give error. This is because the main process of the system (pid 1) must not be closed.

kernel panic

initramfs The init in linux distributions is used to mount the partition where the system is installed and start the service manager in it. Service managers, on the other hand, are designed to never shut down. We can prevent it from closing by changing the C code in this example as follows.

#include int main(){ puts("Hello Word"); while(1); return 0; }

Now let's compile and package our initramfs image again.

Printing Hello World with Linux kernel

As you can see, we do not get a kernel panic error because our code does not exit.