0

I'm learning about how Linux works and for that I'm watching Tutorial: Building the Simplest Possible Linux System by Rob Landley. He basically goes through some steps to build a minimal system and around 20:00 he starts explaining about building a "hello world binary" that he will later use as the init program for the kernel to run as the very first program.

My question is, why do I have to statically link the hello.c application I want to use as the init application for the kernel to run after booting (as mentioned at 21:39 and seen at 23:05)?

m4l490n
  • 175
  • 1
    You do? systemd seems to be dynamically linked: sudo file -L /proc/1/exe => /proc/1/exe: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked ... – muru Dec 28 '21 at 06:03
  • 2
    The init program can be anything that the internal kernel code which backs the execve system call can run. It can be a shell script, or a python script. The advantage of it being a statically linked binary is that it has less dependencies, so you don't need to have the run time linker present and libraries it wants to link to. So you might need something like /lib64/ld-linux-x86-64.so.2 and /lib/x86_64-linux-gnu/libc.so.6 in your initial filesystem as well as the init program itself. – icarus Dec 28 '21 at 07:38
  • 4
    Notice he doesn't say you have to statically compile it, he just says that he will statically compile it. As previous comments said, it might be better in some cases to eliminate dependencies. For instance, if some of the libraries are located in separate filesystem than the root filesystem. The init process is responsible for mounting all the filesystems (from fstab), so you could see how this becomes a problem. – aviro Dec 28 '21 at 08:04
  • @icarus I think this is the correct answer, could you convert this comment into an answer to accept it. I say this because he mentions something along these lines later in the video. – m4l490n Dec 28 '21 at 16:33
  • How old is this video series? This restriction was in effect long, long ago. – waltinator Dec 28 '21 at 17:34

2 Answers2

2

My question is, why do I have to statically build the hello.c application I want to use as the init application for the kernel to run after booting (as mentioned at 21:39 and seen at 23:05)?

There's no such requirement for the vanilla Linux kernel. It will happily load an init program along with its shared dependencies:

$ ls -la /sbin/init
lrwxrwxrwx. 1 root root 22 Nov 15 13:21 /sbin/init -> ../lib/systemd/systemd

$ ldd which /sbin/init linux-vdso.so.1 (0x00007ffcd31ee000) libsystemd-shared-249.so => /usr/lib/systemd/libsystemd-shared-249.so (0x00007fd28d983000) libseccomp.so.2 => /lib64/libseccomp.so.2 (0x00007fd28d950000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fd28d925000) libmount.so.1 => /lib64/libmount.so.1 (0x00007fd28d8e0000) libpam.so.0 => /lib64/libpam.so.0 (0x00007fd28d8ce000) libaudit.so.1 => /lib64/libaudit.so.1 (0x00007fd28d8a0000) libkmod.so.2 => /lib64/libkmod.so.2 (0x00007fd28d883000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fd28d868000) libc.so.6 => /lib64/libc.so.6 (0x00007fd28d65e000) libacl.so.1 => /lib64/libacl.so.1 (0x00007fd28d653000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007fd28d61b000) libcap.so.2 => /lib64/libcap.so.2 (0x00007fd28d611000) libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007fd28d5d5000) libgcrypt.so.20 => /lib64/libgcrypt.so.20 (0x00007fd28d499000) libip4tc.so.2 => /lib64/libip4tc.so.2 (0x00007fd28d48f000) liblz4.so.1 => /lib64/liblz4.so.1 (0x00007fd28d46b000) libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007fd28d17d000) libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007fd28d04b000) libzstd.so.1 => /lib64/libzstd.so.1 (0x00007fd28cf73000) liblzma.so.5 => /lib64/liblzma.so.5 (0x00007fd28cf47000) /lib64/ld-linux-x86-64.so.2 (0x00007fd28de62000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007fd28ceb0000) libeconf.so.0 => /lib64/libeconf.so.0 (0x00007fd28cea5000) libm.so.6 => /lib64/libm.so.6 (0x00007fd28cdc9000) libcap-ng.so.0 => /lib64/libcap-ng.so.0 (0x00007fd28cdbe000) libz.so.1 => /lib64/libz.so.1 (0x00007fd28cda4000) libattr.so.1 => /lib64/libattr.so.1 (0x00007fd28cd9c000) libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007fd28cd76000) libpcap.so.1 => /lib64/libpcap.so.1 (0x00007fd28cd29000) libffi.so.6 => /lib64/libffi.so.6 (0x00007fd28cd1c000) libibverbs.so.1 => /lib64/libibverbs.so.1 (0x00007fd28ccfa000) libnl-route-3.so.200 => /lib64/libnl-route-3.so.200 (0x00007fd28cc74000) libnl-3.so.200 => /lib64/libnl-3.so.200 (0x00007fd28cc50000)

  • 1
    ...Unless some of the libraries required by init are located on a different filesystem than the root filesystem. – aviro Dec 28 '21 at 10:52
  • @aviro I believe this is (partly) why there is no longer support for /usr as a separate filesystem – Chris Davies Dec 28 '21 at 16:35
  • @roima, I'm pretty sure that /usr can be installed on a separate filesystem. And anyway most of the dependencies are on /lib64. Maybe you mean other folder? – aviro Dec 28 '21 at 18:23
  • @aviro, there are some that seem to think a separate /usr isn't or shouldn't be supported: https://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken/ https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/ https://fedoraproject.org/wiki/Features/UsrMove https://wiki.debian.org/UsrMerge – ilkkachu Dec 29 '21 at 18:54
0

The init program can be anything that the internal kernel code which backs the execve system call can run.

Many systems use a shell script, but it could even be a python script.

The advantage of the init program being a statically linked binary is that it has less dependencies, so you don't require to have the run time linker and the shared libraries that it links to present.

On a 64 bit x86 system you might need something like /lib64/ld-linux-x86-64.so.2 and /lib/x86_64-linux-gnu/libc.so.6 in your initial filesystem as well as the init program itself.

icarus
  • 17,920