How to generate initramfs image with busybox links?

9,142

Solution 1

It's not the kernel that's generating the initramfs, it's cpio. So what you're really looking for is a way to build a cpio archive that contains devices, symbolic links, etc.

Your method 2 uses usr/gen_init_cpio in the kernel source tree to build the cpio archive during the kernel build. That's indeed a good way of building a cpio archive without having to populate the local filesystem first (which would require being root to create all the devices, or using fakeroot or a FUSE filesystem which I'm not sure has been written already).

All you're missing is generating the input file to gen_init_cpio as a build step. E.g. in shell:

INITRAMFS_SOURCE_DIR=/home/brandon/rascal-initramfs
exec >initramfs_source.txt
echo "dir /bin 755 0 0"
echo "file /bin/busybox $INITRAMFS_SOURCE_DIR/bin/busybox 755 0 0"
for x in sh ls cp …; do echo "slink /bin/$x busybox 777 0 0" done
# etc …

If you want to reflect the symbolic links to busybox that are present in your build tree, here's a way (I assume you're building on Linux):

( cd "$INITRAMFS_SOURCE_DIR/bin" &&
  for x in *; do
    if [ "$(readlink "$x")" = busybox ]; then
      echo "slink /bin/$x busybox 777 0 0"
    fi
  done )

Here's a way to copy all your symbolic links:

find "$INITRAMFS_SOURCE_DIR" -type l -printf 'slink %p %l 777 0 0\n'

For busybox, maybe your build tree doesn't have the symlinks, and instead you want to create one for every utility that you've compiled in. The simplest way I can think of is to look through your busybox build tree for .*.o.cmd files: there's one per generated command.

find /path/to/busybox/build/tree -name '.*.cmd' -exec sh -c '
    for x; do
      x=${x##*/.}
      echo "slink /bin/${x%%.*} busybox 777 0 0"
    done
' _ {} +

Solution 2

The first few lines of the initscript in my initramfs are simply:

busybox --install -s

Creates the symlinks for you.. Only takes an unmeasurably small amount of time on my 500Mhz board, possibly longer on very low hardware, but likely manageable. Saves a bunch of issues remembering to create all the right links when you update BB...

Solution 3

If you are in the busybox shell (ash) you don't need to worry about aliases as they will be run as commands by default IIRC. Anyway busybox --help gives list of supported commands. In my case they are:

% busybox --help
BusyBox v1.17.4 (2010-11-25 12:49:55 GMT) multi-call binary.
Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.

Usage: busybox [function] [arguments]...
   or: function [arguments]...

    BusyBox is a multi-call binary that combines many common Unix
    utilities into a single executable.  Most people will create a
    link to busybox for each function they wish to use and BusyBox
    will act like whatever it was invoked as.

Currently defined functions:
    [, [[, acpid, addgroup, adduser, adjtimex, ar, arp, arping, ash, awk,
    basename, bb, bbconfig, bbsh, beep, blkid, bootchartd, brctl, bunzip2,
    bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown,
    chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, conspy,
    cp, cpio, crond, cryptpw, cttyhack, cut, date, dd, deallocvt, delgroup,
    deluser, depmod, devmem, df, dhcprelay, diff, dirname, dmesg,
    dnsdomainname, dos2unix, dpkg-deb, du, dumpkmap, dumpleases, echo, ed,
    egrep, eject, env, envdir, envuidgid, ether-wake, expand, expr, false,
    fbset, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs,
    flash_eraseall, flash_lock, flash_unlock, flashcp, flock, free,
    freeramdisk, fsck, fsck.minix, fsync, ftpd, fuser, getopt, getty, grep,
    gunzip, gzip, halt, hd, hdparm, head, hexdump, hostname, httpd,
    hwclock, id, ifconfig, ifdown, ifenslave, ifplugd, ifup, init, insmod,
    install, ionice, ip, ipaddr, ipcrm, ipcs, iplink, iproute, iprule,
    iptunnel, kbd_mode, kill, killall, killall5, klogd, last, length, less,
    linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login,
    logread, losetup, lpq, lpr, ls, lsattr, lsmod, lspci, lsusb, lzcat,
    lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mdev, mesg,
    microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.minix,
    mkfs.reiser, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo,
    modprobe, more, mount, mountpoint, mt, mv, nameif, nc, netstat, nice,
    nmeter, nohup, nslookup, ntpd, openvt, passwd, patch, pgrep, pidof,
    ping, ping6, pipe_progress, pivot_root, pkill, popmaildir, poweroff,
    printenv, printf, ps, pscan, pwd, raidautorun, rdate, rdev, readahead,
    readlink, readprofile, realpath, reboot, reformime, renice, reset,
    resize, rev, rm, rmdir, rmmod, route, rtcwake, run-parts, runlevel,
    runsv, runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setarch,
    setconsole, setfont, setkeycodes, setlogcons, setsid, setuidgid, sh,
    sha1sum, sha256sum, sha512sum, showkey, sleep, smemcap, softlimit,
    sort, split, start-stop-daemon, stat, strings, stty, su, sum, sv,
    svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail,
    tar, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top,
    touch, tr, traceroute, traceroute6, true, tty, ttysize, tunctl,
    tune2fs, ubiattach, ubidetach, udhcpc, udhcpd, umount, uname,
    uncompress, unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip,
    uptime, usleep, vconfig, vi, vlock, volname, wall, watch, watchdog, wc,
    wget, which, who, whoami, xargs, xz, xzcat, yes, zcat, zcip

In case of first method you create by mknod(1) command. For example:

# mknod /my/dir/with/initrd/dev/console -m 644 c 5 0
Share:
9,142

Related videos on Youtube

pingswept
Author by

pingswept

Embedded systems engineer. I am currently working on an embedded Linux board for my new startup, Rascal Micro.

Updated on September 17, 2022

Comments

  • pingswept
    pingswept over 1 year

    Having been directed to initramfs by an answer to my earlier question (thanks!), I've been working on getting initramfs working. I can now boot the kernel and drop to a shell prompt, where I can execute busybox commands, which is awesome.

    Here's where I'm stuck-- there are (at least) two methods of generating initramfs images:

    1. By passing the kernel a path to a prebuilt directory hierarchy to be compressed
    2. By passing the kernel the name of a file that lists the files to be included.

    The second method seemed a little cleaner, so I've been using that.

    Just for reference, here's my file list so far:

    dir /dev 755 0 0
    nod /dev/console 644 0 0 c 5 1
    nod /dev/loop0 644 0 0 b 7 0
    dir /bin 755 1000 1000
    slink /bin/sh busybox 777 0 0
    file /bin/busybox /home/brandon/rascal-initramfs/bin/busybox 755 0 0
    dir /proc 755 0 0
    dir /sys 755 0 0
    dir /mnt 755 0 0
    file /init /home/brandon/rascal-initramfs/init.sh 755 0 0
    

    Unfortunately, I have learned that busybox requires a long list of links to serve as aliases to all of its different commands. Is there a way to generate the list of all these commands so I can add it to my file list?

    Alternatively, I could switch to method 1, using the prebuilt directory hierarchy, but I'm not sure how to make the /dev nodes in that case.

    Both of these paths seem messy. Is there an elegant solution to this?

    • Léo Léopold Hertz 준영
      Léo Léopold Hertz 준영 almost 9 years
      Have you considered user6113's answer? It seems to be a good answer to your question.
  • Louis Gerbarg
    Louis Gerbarg over 13 years
    Actually isn't you're missing step posted? I.e. just after 'Just for reference, here's my file list so far:'?
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    @Maciej: Good point, I hadn't thought of that way of interpreting the question, but matching the capabilities of the busybox executable with the initramfs generation is a good idea anyway.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    In the OP's case, busybox --help is likely to only result in busybox: cannot execute binary file... Most embedded development is cross-compiling, we know pingswept is compiling for arm, and he's probably compiling on i386 or amd64.
  • pingswept
    pingswept over 13 years
    Yes, that is actually true. I can run busybox --help once I boot the kernel on the ARM board. That's useful, but it doesn't help so much with generating the initramfs image.
  • Louis Gerbarg
    Louis Gerbarg over 13 years
    @Gilles: I assumed that someone who cross-compiles kernel did think about and, for example, run in the emulator. @pingswept: Possibly above list will help.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 13 years
    At work, our automated build environment doesn't have access to an emulator. I think this the norm in embedded development.