# busybox 1.36.1 (M5) [busybox](https://busybox.net) is one program that contains ~300 small Unix tools ("applets"): `awk`, `sed`, `vi`, `tar`, `gzip`, `wget`, `ps`, `adduser`, a shell (`ash`)... Which applet runs depends on the name it was started under (`argv[0]`), or on the first argument: `busybox awk ...`. ## Version **1.36.1** (2023-05-18), the newest release that busybox.net calls "stable". 1.37.0 and 1.38.0 exist but are marked "unstable" on the download page, so we wait. The tarball is pinned by SHA256 in `busybox.sha256` and downloaded once into `cache/` by `ports/fetch.sh`. ## Where it goes Contract v2 only, on the ext2 root: ``` /usr/lib/busybox/busybox the program (static-PIE, ~1 MB) /usr/lib/busybox/awk -> busybox one symlink per applet (320 of them) /usr/lib/busybox/LICENSE GPL v2 ``` The directory is **off** the default `PATH`, so the Foundry OS Rust tools (`/bin/ls`, ...) and dash (`/bin/sh`) stay the default. Use busybox as ```sh /usr/lib/busybox/busybox awk -F: '{print $1}' /etc/passwd /usr/lib/busybox/awk -F: '{print $1}' /etc/passwd # same thing PATH=/usr/lib/busybox:$PATH # all applets, this shell only /usr/lib/busybox/busybox ash # busybox's shell ``` ## Configuration (`busybox.config`) `busybox.config` is the complete `.config`, committed, and the build uses it as is (it fails if busybox would have to ask about a new option). It is made by `mkconfig.sh` from busybox's own `make defconfig` (nearly everything on), with these changes. `mkconfig.sh` lists every option with a comment, so the list there is the reference; in short: **Switched off (83 applets): things Rustbelt cannot do**, so they could only ever fail: | Group | Applets | Why not | |---|---|---| | Kernel modules | `insmod`, `rmmod`, `lsmod`, `modprobe`, `depmod`, `modinfo` | Rustbelt has no loadable modules | | Traffic control | `tc` | netlink; and 1.36.1's `tc` doesn't compile against current Linux headers | | Linux network setup | `ip` (+ `ipaddr`, `iplink`, `iproute`, ...), `brctl`, `udhcpc`, `udhcpd`, `arping`, `ether-wake`, `zcip`, `ifplugd`, `nameif`, `tunctl`, `vconfig`, `ifenslave`, `nbd-client`, ... | netlink or raw packet sockets; Rustbelt sets up its network itself (DHCP in the kernel) | | Hardware Rustbelt doesn't expose | flash/UBI tools, `i2c*`, `lspci`, `lsusb`, `hwclock`, `watchdog`, `devmem`, `acpid`, `beep`, `setserial` | no `/dev/mtd*`, `/dev/i2c-*`, `/dev/rtc`, `/sys` | | Linux console and framebuffer | `loadfont`, `setfont`, `kbd_mode`, `loadkmap`, `dumpkmap`, `setkeycodes`, `fbset`, `fbsplash`, `conspy` | Linux console ioctls; Rustbelt's console works differently | | Other kernel features | `mdev`, `uevent`, swap (`mkswap`, `swapon`, `swapoff`), `losetup`, `raidautorun`, floppy tools, `freeramdisk`, `eject`, `blkdiscard`, `fsfreeze`, `rdev`, `pivot_root`, `switch_root`, `nsenter`, `unshare`, `setarch`/`linux32`/`linux64`, `adjtimex` | hot-plug, swap, loop devices, RAID, namespaces, switching the root | SELinux and PAM are already off in defconfig, and nothing is built as a loadable module (busybox has none of its own anyway). **Kept on purpose**, even though they fail today: `ps`, `top`, `free`, `mount`, `df`, `mkfifo`, `chroot`, `dmesg`, `ping` and friends. They need kernel features that are planned (K7, K14, K15 in docs/kernel-requests.md), and the test runs them as expected failures, so we see when they start to work. `login`, `su`, `passwd`, `adduser`, `getty` stay for M6 (users). **Switched on (1 option): `FEATURE_PREFER_APPLETS`.** When one applet runs another (`xargs echo`, `find -exec`, `adduser` running `addgroup`), busybox normally looks the command up on `PATH`, where our busybox isn't. With this option it runs its own applet (through `/proc/self/exe`) instead. One exception, by busybox's design: `tar -z`/`-j` always run an external `gzip`/`bzip2` from `PATH`; put `/usr/lib/busybox` on `PATH` for those (or use a pipe: `tar -cf - dir | busybox gzip > dir.tgz`). ## Building `make busybox` (also part of `make image`): `ports/fetch.sh busybox cache`, then `build.sh cache out/ports/busybox-build out/ports/busybox`. It runs busybox's Makefile with ``` make CC=toolchain/foundry-cc LD=ld HOSTCC=gcc EXTRA_CFLAGS="-isystem " ``` - `CC=foundry-cc`: our gcc + musl wrapper, so the result is a static-PIE. - `LD=ld`: busybox links each directory with `ld -r` first, and that can't be combined with foundry-cc's `-static-pie`. The final link still uses CC. - `HOSTCC=gcc`: the little helper programs busybox runs during the build are for the build machine, not for Rustbelt. - Kernel headers: busybox includes a few Linux headers (``...) that musl doesn't have. `build.sh` copies the build machine's (`/usr/include/linux`, `asm`, `asm-generic`: Debian/Ubuntu package `linux-libc-dev`) into the build directory. - No `bzip2` program on the build machine? `build.sh` unpacks the tarball with Python (`untar.py`) and gives the build a tiny Python stand-in (`bzip2-shim.py`) for the one place it pipes through `bzip2`. To change the configuration: edit the lists in `mkconfig.sh`, run `ports/busybox/mkconfig.sh cache /tmp/bbcfg`, check `git diff ports/busybox/busybox.config`, then `make busybox`. ## Speed note Rustbelt reads the whole program file on every `execve` (no page cache yet), so starting the 1 MB busybox costs about 0.2 s, against about 0.04 s for a 16 KB sbase tool. Scripts that start hundreds of applets feel it. See K15 in docs/kernel-requests.md.