3

I have a fairly standard initial ramdisk created using mkinitcpio. I'm on Arch GNU/Linux.

A while ago I got dropped to a rescue shell and poked around in the /bin of the ramdisk to see what was available. For some reason, there was a bunch of utilities that seemed irrelevant (think things like ping - why would you want that in a rescue environment?).

alex@alexs-arch-imac:/tmp$ mkdir initramfs
alex@alexs-arch-imac:/tmp$ cd initramfs
alex@alexs-arch-imac:/tmp/initramfs$ cp /boot/initramfs-linux.img .
alex@alexs-arch-imac:/tmp/initramfs$ cat initramfs-linux.img | unlzma - > 

initramfs-linux # needed because unlzma complains that it doesn't recognize the .img extension
alex@alexs-arch-imac:/tmp/initramfs$ cpio -iV < initramfs-linux
.............................................................................................................................................................................................................................................................................................................................................................
24225 blocks
alex@alexs-arch-imac:/tmp/initramfs$ ls
bin  buildconfig  config  dev  etc  hooks  init  init_functions  initramfs-linux  initramfs-linux.img  lib  lib64  new_root  proc  run  sbin  shutdown  sys  tmp  usr  VERSION
alex@alexs-arch-imac:/tmp/initramfs$ ls -l bin
lrwxrwxrwx 1 alex alex 7 Mar 24 17:06 bin -> usr/bin
alex@alexs-arch-imac:/tmp/initramfs$ ls bin
[         blkid    chown       cttyhack  dirname  egrep    free    hexdump   ip       iptunnel  less      ls      mkfifo    mount       nslookup  ping6     readlink  route    sha1sum    stat              tac     touch    uniq    yes
[[        busybox  chroot      cut       dmesg    env      getopt  ifconfig  ipaddr   kbd_mode  ln        lsblk   mknod     mountpoint  openvt    poweroff  reboot    sed      sha256sum  strings           tail    true     uptime
ash       cat      clear       dd        dmsetup  expr     grep    init      iplink   kill      loadfont  lsmod   mktemp    mv          pgrep     printf    rm        seq      sha512sum  switch_root       telnet  udevadm  vi
awk       chgrp    cp          depmod    du       false    halt    insmod    iproute  killall   loadkmap  md5sum  modinfo   nc          pidof     ps        rmdir     setfont  sleep      sync              test    umount   wc
basename  chmod    cryptsetup  df        echo     findmnt  head    install   iprule   kmod      losetup   mkdir   modprobe  netstat     ping      pwd       rmmod     sh       sort       systemd-tmpfiles  tftp    uname    wget
alex@alexs-arch-imac:/tmp/initramfs$ 

Notice that the image has the weirdest utilities. Just looking at it, I see wget, ping, telnet, sha1sum... why are these here?

Here's the output of my /etc/mkinitcpio.conf. Images were generated using mkinitcpio -p linux.

# vim:set ft=sh
# MODULES
# The following modules are loaded before any boot hooks are
# run.  Advanced users may wish to specify all system modules
# in this array.  For instance:
#     MODULES="piix ide_disk reiserfs"
MODULES=""

# BINARIES
# This setting includes any additional binaries a given user may
# wish into the CPIO image.  This is run last, so it may be used to
# override the actual binaries included by a given hook
# BINARIES are dependency parsed, so you may safely ignore libraries
BINARIES=""

# FILES
# This setting is similar to BINARIES above, however, files are added
# as-is and are not parsed in any way.  This is useful for config files.
FILES=""

# HOOKS
# This is the most important setting in this file.  The HOOKS control the
# modules and scripts added to the image, and what happens at boot time.
# Order is important, and it is recommended that you do not change the
# order in which HOOKS are added.  Run 'mkinitcpio -H <hook name>' for
# help on a given hook.
# 'base' is _required_ unless you know precisely what you are doing.
# 'udev' is _required_ in order to automatically load modules
# 'filesystems' is _required_ unless you specify your fs modules in MODULES
# Examples:
##   This setup specifies all modules in the MODULES setting above.
##   No raid, lvm2, or encrypted root is needed.
#    HOOKS="base"
#
##   This setup will autodetect all modules for your system and should
##   work as a sane default
#    HOOKS="base udev autodetect block filesystems"
#
##   This setup will generate a 'full' image which supports most systems.
##   No autodetection is done.
#    HOOKS="base udev block filesystems"
#
##   This setup assembles a pata mdadm array with an encrypted root FS.
##   Note: See 'mkinitcpio -H mdadm' for more information on raid devices.
#    HOOKS="base udev block mdadm encrypt filesystems"
#
##   This setup loads an lvm2 volume group on a usb device.
#    HOOKS="base udev block lvm2 filesystems"
#
##   NOTE: If you have /usr on a separate partition, you MUST include the
#    usr, fsck and shutdown hooks.
HOOKS="base udev autodetect modconf keyboard block encrypt resume filesystems fsck shutdown"

# COMPRESSION
# Use this to compress the initramfs image. By default, gzip compression
# is used. Use 'cat' to create an uncompressed image.
#COMPRESSION="gzip"
#COMPRESSION="bzip2"
COMPRESSION="lzma"
#COMPRESSION="xz"
#COMPRESSION="lzop"
#COMPRESSION="lz4"

# COMPRESSION_OPTIONS
# Additional options for the compressor
#COMPRESSION_OPTIONS=""
6

Initial ramdisks use Busybox to save space. Essentially, utilities like mv and cp all share a lot of common logic - open a file descriptor, read buffers into memory, etc. Busybox basically puts all the common logic into one binary which changes the way it behaves depending on the name with which it was called. Let's take a look at that ramdisk.

alex@alexs-arch-imac:/tmp/initramfs/bin$ ls -l
total 1308
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 [ -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 [[ -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ash -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 awk -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 basename -> busybox
-rwxr-xr-x 1 alex alex  68840 Mar 24 17:06 blkid
-rwxr-xr-x 1 alex alex 287096 Mar 24 17:06 busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 cat -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 chgrp -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 chmod -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 chown -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 chroot -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 clear -> busybox
-rwxr-xr-x 1 alex alex 130272 Mar 24 17:06 cp
-rwxr-xr-x 1 alex alex  59264 Mar 24 17:06 cryptsetup
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 cttyhack -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 cut -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 dd -> busybox
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 depmod -> kmod
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 df -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 dirname -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 dmesg -> busybox
-r-xr-xr-x 1 alex alex  92227 Mar 24 17:06 dmsetup
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 du -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 echo -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 egrep -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 env -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 expr -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 false -> busybox
-rwxr-xr-x 1 alex alex  53696 Mar 24 17:06 findmnt
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 free -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 getopt -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 grep -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 halt -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 head -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 hexdump -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ifconfig -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 init -> busybox
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 insmod -> kmod
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 install -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ip -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ipaddr -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 iplink -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 iproute -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 iprule -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 iptunnel -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 kbd_mode -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 kill -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 killall -> busybox
-rwxr-xr-x 1 alex alex 142424 Mar 24 17:06 kmod
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 less -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ln -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 loadfont -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 loadkmap -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 losetup -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ls -> busybox
-rwxr-xr-x 1 alex alex  70192 Mar 24 17:06 lsblk
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 lsmod -> kmod
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 md5sum -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 mkdir -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 mkfifo -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 mknod -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 mktemp -> busybox
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 modinfo -> kmod
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 modprobe -> kmod
-rwsr-xr-x 1 alex alex  40168 Mar 24 17:06 mount
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 mountpoint -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 mv -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 nc -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 netstat -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 nslookup -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 openvt -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 pgrep -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 pidof -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ping -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ping6 -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 poweroff -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 printf -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 ps -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 pwd -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 readlink -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 reboot -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 rm -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 rmdir -> busybox
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 rmmod -> kmod
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 route -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sed -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 seq -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 setfont -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sh -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sha1sum -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sha256sum -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sha512sum -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sleep -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sort -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 stat -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 strings -> busybox
-rwxr-xr-x 1 alex alex  14816 Mar 24 17:06 switch_root
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 sync -> busybox
-rwxr-xr-x 1 alex alex  63992 Mar 24 17:06 systemd-tmpfiles
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 tac -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 tail -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 telnet -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 test -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 tftp -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 touch -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 true -> busybox
-rwxr-xr-x 1 alex alex 264696 Mar 24 17:06 udevadm
-rwsr-xr-x 1 alex alex  27616 Mar 24 17:06 umount
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 uname -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 uniq -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 uptime -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 vi -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 wc -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 wget -> busybox
lrwxrwxrwx 1 alex alex      7 Mar 24 17:06 yes -> busybox
alex@alexs-arch-imac:/tmp/initramfs/bin$ 

As you can see, almost every single binary in this image is linked to Busybox.

alex@alexs-arch-imac:/tmp/initramfs/bin$ ls -l | grep --invert-match busybox -
total 1308
-rwxr-xr-x 1 alex alex  68840 Mar 24 17:06 blkid
-rwxr-xr-x 1 alex alex 130272 Mar 24 17:06 cp
-rwxr-xr-x 1 alex alex  59264 Mar 24 17:06 cryptsetup
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 depmod -> kmod
-r-xr-xr-x 1 alex alex  92227 Mar 24 17:06 dmsetup
-rwxr-xr-x 1 alex alex  53696 Mar 24 17:06 findmnt
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 insmod -> kmod
-rwxr-xr-x 1 alex alex 142424 Mar 24 17:06 kmod
-rwxr-xr-x 1 alex alex  70192 Mar 24 17:06 lsblk
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 lsmod -> kmod
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 modinfo -> kmod
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 modprobe -> kmod
-rwsr-xr-x 1 alex alex  40168 Mar 24 17:06 mount
lrwxrwxrwx 1 alex alex      4 Mar 24 17:06 rmmod -> kmod
-rwxr-xr-x 1 alex alex  14816 Mar 24 17:06 switch_root
-rwxr-xr-x 1 alex alex  63992 Mar 24 17:06 systemd-tmpfiles
-rwxr-xr-x 1 alex alex 264696 Mar 24 17:06 udevadm
-rwsr-xr-x 1 alex alex  27616 Mar 24 17:06 umount
alex@alexs-arch-imac:/tmp/initramfs/bin$ ls | wc -l # total number of files
116
alex@alexs-arch-imac:/tmp/initramfs/bin$ ls -l | grep --invert-match busybox - | grep --invert-match kmod | wc -l # number of real binaries minus two (busybox and kmod)
12

There are 116 files in the image, but only 14 of them are actually binaries. The rest are symlinks to either kmod or busybox.

So: the reason that there are so many random utilities is because you might as well put them in there. The symlinks don't take up any space, and even if you removed them, the functionality would remain in the Busybox binary, taking up space. Since there's no real reason to remove all the links, the packagers don't.

Here's another question to consider: why not simply remove the network functionality from the Busybox binary? As @Gilles mentions, there are legitimate (if not common) cases where you would need networking in an initcpio. Therefore, the packagers have two options: one, do what they do now and just include it all by default, or two, split networking functionality out into its own mkinitcpio hook. The former is dead-easy (you basically do nothing) and costs a very, very small amount, whereas the second is very complex (again, thanks to @Gilles for pointing this out) and the gains really are not significant enough to matter. Therefore, the packagers take the smart way out, and don't do anything with the networking.

  • See @Gilles's answer - netbooting is builtin, at least in Arch. – mikeserv Mar 26 '14 at 4:11
  • @mikeserv and see my reply. you didn't really mention "builtin", but I fail to see how you could have concluded this. almost nothing is builtin to Arch. that is why Arch is for power users, and that is why Arch is distinct from almost every other distro out there (exceptions mainly being Gentoo and LFS). – strugee Mar 26 '14 at 5:40
  • Now this i disagree with - quite a lot of things are builtin. Have a look at zcat /proc/config.gz - if youve got their default kernel, i bet youll find its pretty padded. Im willing to bet youve also got TCL man pages - maybe even in German. Probably Wayland is installed - it's a default dependency for X. /usr/share/firmware almost definitely contains far more than youll ever need. These are just the kinds of that happen when youre a popular distro. Arch is by no means minimal. – mikeserv Mar 26 '14 at 7:10
  • @mikeserv the kernel is "padded" because it requires a recompilation to change anything. if there was a way to split stuff out easily, it probably would be. re: Wayland, X itself is not installed by default. – strugee Mar 26 '14 at 15:39
  • I know why it is... Busybox requires a recompilation to change as well, by the way. – mikeserv Mar 26 '14 at 15:40
5

While it isn't a very common setup, some installations only have some very small local storage, or indeed none at all and retrieve the boot code including the kernel via TFTP. The kernel then mounts its root filesystem over the network, e.g. with NFS. For such systems, basic networking tools may be necessary to locate and mount the root filesystem.

The initial ramdisk contains kernel modules corresponding to the features needed to mount the root filesystem, the BusyBox utility suite, and a few more utilities. The initramfs is assembled based on the needs for your system by mkinitcpio (this is distribution-dependent, for example Debian-based distributions use the similar program mkinitramfs). Each driver is stored in a separate file, so it's possible to trim down the kernel modules in the initramfs to only the ones needed for your system (but at the expense of making your system unbootable on different hardware). BusyBox comes in a single binary containing all the features that were chosen at compile time, so trimming it down would involve recompiling it. Unless you're building an embedded device with a static setup and limited space, it's not worth the complexity.

  • This is the right answer, at least as far as Arch is concerned, I think. For instance, the live installation media is even distributed as an http bootable iPXE script. Many of the default init hooks are netboot related. – mikeserv Mar 26 '14 at 4:08
  • @mikeserv how the live media is distributed has nothing to do with what is in an initcpio. and besides, I have basically exactly the default, plus the encrypt hook, and nothing stands out. please explain which hook is netboot related. – strugee Mar 26 '14 at 5:30
  • I mean yes, base obviously pulls in the Busybox network stuff. but that was what the question was about: why base behaves this way. – strugee Mar 26 '14 at 5:32
  • @strugee I dont know, maybe youre right. But to me, it just makes sense to include basic default boot options in the basic default boot media - and you dont get more basic than initramfs. I mean, why would they want 30 different images? We're talking about a distribution that makes officially available a single, command-line-only installation image once per month. mkinitcpio and pacman virtually are Arch - might as well include the tools in init that youve already fine-tuned so well. Thats just how I see it. I dont know them personally or anything, though i know their init pretty well. – mikeserv Mar 26 '14 at 5:37
  • @mikeserv if it makes sense to include things that are "basic", you do not understand Arch (and that's OK). remember that everyone has a different definition of "basic". and I still don't understand why you're talking about live media. I'm talking about an initcpio that I generated myself when I installed Arch (and during kernel upgrades). – strugee Mar 26 '14 at 5:46
4

Short answer, it's a hold-over from where the busybox came from. Odds are low you'll ever need network access from the boot recovery environment. The odds are even lower you'll even have a network driver available -- distro kernels don't have them built-in, and they won't be in the initrd unless you put them there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.