foundry
Foundry OS: the operating system built on the Rustbelt kernel
5572 bytes ยท raw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | # 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 <kernel headers>"
```
- `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 (`<linux/fs.h>`...)
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.
|