Merge pull request #225 from arihant2math/new-image-scripts

This commit is contained in:
Matthew Leach
2026-02-20 04:53:06 +00:00
committed by GitHub
15 changed files with 123 additions and 723 deletions

View File

@@ -3,7 +3,7 @@ FROM ubuntu:latest AS base
# Install dependencies
RUN apt update
RUN apt install -y build-essential curl git wget
RUN apt install -y qemu-system-aarch64 dosfstools mtools
RUN apt install -y qemu-system-aarch64 mtools jq
# Install Rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
@@ -27,7 +27,6 @@ ENV PATH="/opt/arm-toolchain/bin:${PATH}"
# Build root fs image
FROM base as image-builder
RUN ./scripts/build-deps.sh
RUN ./scripts/create-image.sh
# Build final image

20
Justfile Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env just --justfile
create-image:
./scripts/create-image.sh
run:
#!/usr/bin/env sh
# Create moss.img if it doesn't exist
if [ ! -f moss.img ]; then
just create-image
fi
cargo run --release -- /bin/ash
test-unit:
#!/usr/bin/env sh
host_target="$(rustc --version --verbose | awk -F': ' '/^host:/ {print $2; exit}')"
cargo test --package libkernel --target "$host_target"
test-userspace:
cargo run -r -- /bin/usertest

View File

@@ -84,24 +84,29 @@ x86) before running on bare metal.
## Building and Running
### Prerequisites
You will need QEMU for AArch64 emulation, as well as dosfstools and mtools to create the
virtual file system.
You will need QEMU for AArch64 emulation, as well as wget, e2fsprogs, and jq for image creation.
We use `just` as a task runner to simplify common commands,
but you can also run the underlying commands directly if you prefer.
Additionally, you will need a version of
the [aarch64-none-elf](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain) toolchain installed.
To install `aarch64-none-elf` on any OS, download the appropriate release of `aarch64-none-elf` onto your computer,
unpack it, then export the `bin` directory to PATH (Can be done via running:
`export PATH="~/Downloads/arm-gnu-toolchain-X.X.relX-x86_64-aarch64-none-elf/bin:$PATH"`, where X is the version number
you downloaded onto your machine, in your terminal).
#### Debian/Ubuntu
```bash
sudo apt install qemu-system-aarch64 dosfstools mtools
sudo apt install qemu-system-aarch64 wget jq e2fsprogs just
```
Additionally you will need a version of the [aarch64-none-elf](https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain) toolchain installed.
#### Any x86_64 Linux OS
To install `aarch64-none-elf` on any OS, download the appropriate release of `aarch64-none-elf` onto your computer, unpack it, then export the `bin` directory to PATH (Can be done via running:
`export PATH="~/Downloads/arm-gnu-toolchain-X.X.relX-x86_64-aarch64-none-elf/bin:$PATH"`, where X is the version number you downloaded onto your machine.
in your terminal.)
#### macOS
There is experimental support for macOS in the scripts/mac-experimental folder. The scripts in there are not guaranteed to work for all macOS users and has only been tested on an M4 Apple Silicon MacBook Air.
```bash
brew install qemu wget jq e2fsprogs just
```
#### NixOS
@@ -111,42 +116,58 @@ Run the following command:
nix shell nixpkgs#pkgsCross.aarch64-embedded.stdenv.cc nixpkgs#pkgsCross.aarch64-embedded.stdenv.cc.bintools
```
### Preparing the image
First, run the following script to prepare the binaries for the image:
```bash
./scripts/build-deps.sh
```
This will download and build the necessary dependencies for the kernel and put them
into the `build` directory.
Once that is done, you can create the image using the following command:
```bash
./scripts/create-image.sh
```
This will create an image file named `moss.img` in the root directory of the
project, format it as ext4 image and create the necessary files and directories for
the kernel.
### Running via QEMU
To build the kernel and launch it in QEMU:
``` bash
cargo run --release
just run
```
If you don't have `just` installed, you can run the underlying commands directly:
``` bash
# First time only (to create the image)
./scripts/create-image.sh
# Then, to run the kernel in QEMU
# By default it will launch into bash, which alpine doesn't have, however `ash` and `sh` are both available.
cargo run --release -- /bin/ash
```
The kernel runs off of `moss.img`.
This image is a minimal alpine rootfs with the addition of a custom `usertest` binary in `/bin/usertest`.
### Running the Test Suite
Because `libkernel` is architecturally decoupled, you can run the logic tests on
your host machine:
``` bash
cargo test -p libkernel --target x86_64-unknown-linux-gnu
just test-unit
```
To run the userspace test suite in QEMU:
``` bash
just test-userspace
```
or
```bash
cargo run -r -- /bin/usertest
```
If you've made changes to the usertests and want to recreate the image, you can run:
``` bash
just create-image
```
or
```bash
./scripts/create-image.sh
```
### Roadmap & Status

View File

@@ -1,68 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
base="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. && pwd )"
mkdir -p "$base/build/bin"
rm -f "$base/build/bin"/*
pushd "$base/build" &>/dev/null || exit 1
if [ "$(uname -m)" == 'aarch64' ]; then
MUSL_CC="aarch64-linux-musl-native"
else
MUSL_CC="aarch64-linux-musl-cross"
fi
# Decide download source by checking musl.cc reachability first
PRIMARY_URL="https://musl.cc/${MUSL_CC}.tgz"
FALLBACK_URL="https://github.com/arihant2math/prebuilt-musl/raw/refs/heads/main/${MUSL_CC}.tgz"
if [ ! -f "${MUSL_CC}.tgz" ]; then
echo "Checking musl.cc reachability..."
if wget --spider --timeout=5 --tries=1 "$PRIMARY_URL" >/dev/null 2>&1; then
DOWNLOAD_URL="$PRIMARY_URL"
echo "musl.cc reachable. Using primary source."
else
echo "musl.cc not reachable. Using fallback source..."
DOWNLOAD_URL="$FALLBACK_URL"
fi
# Perform the actual download from the chosen source
wget "$DOWNLOAD_URL"
tar -xzf "${MUSL_CC}.tgz"
fi
popd &>/dev/null || exit 1
build=${build:-$(ls $base/scripts/deps)}
export CC="$base/build/${MUSL_CC}/bin/aarch64-linux-musl-gcc"
for script in "$base/scripts/deps/"*
do
[ -e "$script" ] || continue # skip if no file exists
[ -x "$script" ] || continue # skip if not executable
filename=$(basename "$script")
if [[ "$filename" == _* ]]
then
echo "Skipping: $filename"
continue
fi
# skip if not in build list
if ! grep -qw "$filename" <<< "$build";
then
echo "Skipping: $filename"
continue
fi
echo "Preparing: $filename"
# make sure each script is run in the base directory
pushd "$base" &>/dev/null || exit 1
bash "$script"
popd &>/dev/null || exit 1
done

View File

@@ -1,17 +1,57 @@
#!/usr/bin/env bash
set -euo pipefail
# Error if mkfs.ext4 is not installed
if ! command -v mkfs.ext4 &> /dev/null; then
echo "mkfs.ext4 could not be found. Please install e2fsprogs."
exit 1
fi
# Error if wget is not installed
if ! command -v wget &> /dev/null; then
echo "wget could not be found. Please install wget."
exit 1
fi
# Error if jq is not installed
if ! command -v jq &> /dev/null; then
echo "jq could not be found. Please install jq."
exit 1
fi
base="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. && pwd )"
pushd "$base" &>/dev/null || exit 1
img="$base/moss.img"
dd if=/dev/zero of="$img" bs=1M count=128
mkfs.ext4 -F "$img"
if [ -f "$img" ]; then
rm "$img"
fi
debugfs -w -f "$base/scripts/symlinks.cmds" "$img"
for file in "$base/build/bin"/*; do
debugfs -w "$img" -R "write $file /bin/$(basename "$file")"
done
touch "$img"
mkfs.ext4 "$img" 512M
popd &>/dev/null || exit 1
# Download alpine minirootfs to $base/build/ if it doesn't exist
if [ ! -f "$base/build/alpine-minirootfs.tar.gz" ]; then
echo "Downloading alpine minirootfs..."
mkdir -p "$base/build"
wget -O "$base/build/alpine-minirootfs.tar.gz" https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/aarch64/alpine-minirootfs-3.23.3-aarch64.tar.gz
fi
# Extract to directory $base/build/rootfs
if [ -d "$base/build/rootfs" ]; then
rm -rf "$base/build/rootfs"
fi
mkdir -p build/rootfs
tar -xzf "$base/build/alpine-minirootfs.tar.gz" -C "$base/build/rootfs"
# Copy any extra binaries in $base/build/extra_bins to $base/build/rootfs/bin
if [ -d "$base/build/extra_bins" ]; then
cp "$base/build/extra_bins/"* "$base/build/rootfs/bin/"
fi
# Build and copy over usertest
cd "$base"/usertest
usertest_binary="$(cargo build --message-format=json | jq -r 'select(.reason == "compiler-artifact") | .filenames[]' | grep "usertest")"
cp "$usertest_binary" "$base/build/rootfs/bin/usertest"
# make image
yes | mkfs.ext4 -d "$base/build/rootfs" "$img" || true

View File

@@ -1,6 +0,0 @@
Every executable file in this directory is executed by `build-deps.sh`.
When writing a new script you can assume you are in the root directory of the project.
Downloads, git repos, etc. should be placed in the `build` directory.
The built binaries should be placed in the `build/bin` directory.

View File

@@ -1,23 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
bash_repo="${bash_repo:-https://git.savannah.gnu.org/git/bash.git}"
bash_tag="${bash_tag:-bash-5.3}"
stdlib="${stdlib:-musl}"
CC="${CC:-aarch64-linux-$stdlib-gcc}"
pushd "build" &>/dev/null || exit 1
if [ ! -d "bash-5.3" ]; then
wget --retry-connrefused --waitretry=1 --read-timeout=20 --timeout=15 -t 10 https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz
tar xzf bash-5.3.tar.gz
fi
pushd "bash-5.3" &>/dev/null || exit 1
CFLAGS_FOR_BUILD="-std=c99" ./configure --without-bash-malloc --enable-static-link --host="aarch64-linux-$stdlib"
make clean
make
mv bash ../bin/bash
popd &>/dev/null || exit 1
popd &>/dev/null || exit 1

View File

@@ -1,9 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# busybox -- I couldn't get this to build. I ended up restoring to a third-party static binary which isn't ideal but it get's things running.
pushd "build" &>/dev/null || exit 1
wget https://github.com/shutingrz/busybox-static-binaries-fat/raw/refs/heads/main/busybox-aarch64-linux-gnu
chmod +x busybox-aarch64-linux-gnu
mv busybox-aarch64-linux-gnu bin/busybox
popd &>/dev/null || exit 1

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
pushd "usertest" &>/dev/null || exit 1
cargo build
popd &>/dev/null || exit 1
cp ./target/aarch64-unknown-linux-musl/debug/usertest build/bin/

View File

@@ -1,55 +0,0 @@
# Experimental macOS build scripts
This is the folder for experimental macOS build support on Apple Silicon (we do not plan to support x86_64 macOS).
These scripts are not guaranteed to work and are not actively supported by the maintainer or other contributors.
If you do have any issues, please mention @IAmTheNerdNextDoor in GitHub Issues.
### Dependencies
Regardless of stdlib, you will need:
- [Rustup](https://rustup.rs) (DO NOT install Rustup from Homebrew as you will incur conflicts. If you have Rustup installed from Homebrew, uninstall it and reinstall from the Rustup site.)
- [aarch64-none-elf](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)
- [Homebrew](https://brew.sh)
- QEMU (`brew install qemu`)
- e2fsprogs (`brew install e2fsprogs`)
- run `brew link --force e2fsprogs` to get mkfs.ext4 into your $PATH
- wget (`brew install wget`) is used by some scripts and is needed
If building for the GNU library:
- aarch64-unknown-linux-gnu (`brew tap messense/macos-cross-toolchains && brew install aarch64-unknown-linux-gnu`)
If building for the Musl library:
- Zig (`brew install zig`)
We use Zig to cross-compile to Linux musl on macOS.
When it comes to Rust, you need the nightly toolchain. To install it, run:
`rustup default nightly`
### Building
You can start building the initrd programs using this script:
```bash
./scripts/mac-experimental/build-deps.sh
```
musl programs are built by default.
If you want GNU program builds:
```bash
stdlib=gnu ./scripts/mac-experimental/build-deps.sh
```
After building, you can make the initrd with:
```bash
./scripts/mac-experimental/create-image.sh
```
The initrd should now be at `./moss.img`.
You can then build and run moss with:
`cargo run --release`
If you get an error about `aarch64-unknown-none-softfloat` during building, you need to install the target:
`rustup target install aarch64-unknown-none-softfloat`
Have fun!

View File

@@ -1,41 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
base="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../.. && pwd )"
mkdir -p "$base/build/bin"
rm -f "$base/build/bin"/*
pushd "$base/build" &>/dev/null || exit 1
popd &>/dev/null || exit 1
build=${build:-$(ls $base/scripts/deps)}
for script in "$base/scripts/mac-experimental/deps/"*
do
[ -e "$script" ] || continue # skip if no file exists
[ -x "$script" ] || continue # skip if not executable
filename=$(basename "$script")
if [[ "$filename" == _* ]]
then
echo "Skipping: $filename"
continue
fi
# skip if not in build list
if ! grep -qw "$filename" <<< "$build";
then
echo "Skipping: $filename"
continue
fi
echo "Preparing: $filename"
# make sure each script is run in the base directory
pushd "$base" &>/dev/null || exit 1
bash "$script"
popd &>/dev/null || exit 1
done

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
base="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../.. && pwd )"
pushd "$base" &>/dev/null || exit 1
img="$base/moss.img"
mount="$base/build/mount"
mkdir -p "$mount"
dd if=/dev/zero of="$img" bs=1M count=128
mkfs.ext4 -F "$img"
debugfs -w -f "$base/scripts/symlinks.cmds" "$img" </dev/null
for file in "$base/build/bin"/*; do
debugfs -w "$img" -R "write $file /bin/$(basename "$file")" </dev/null
done
popd &>/dev/null || exit 1

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
bash_repo="${bash_repo:-https://git.savannah.gnu.org/git/bash.git}"
bash_tag="${bash_tag:-bash-5.3}"
stdlib="${stdlib:-musl}"
if [ "$stdlib" == "gnu" ]; then
COMPILER="aarch64-linux-gnu-gcc"
else
COMPILER="zig cc -target aarch64-linux-musl"
fi
pushd "build" &>/dev/null || exit 1
if [ ! -d "bash" ]; then
git clone --depth 1 --branch "$bash_tag" "$bash_repo" "bash"
else
pushd "bash" &>/dev/null || exit 1
git pull
popd &>/dev/null || exit 1
fi
pushd "bash" &>/dev/null || exit 1
./configure --without-bash-malloc --enable-static-link --host="aarch64-linux-$stdlib" CC="$COMPILER"
make
mv bash ../bin/bash
popd &>/dev/null || exit 1
popd &>/dev/null || exit 1

View File

@@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
# busybox -- I couldn't get this to build. I ended up restoring to a third-party static binary which isn't ideal but it get's things running.
pushd "build" &>/dev/null || exit 1
wget https://github.com/shutingrz/busybox-static-binaries-fat/raw/refs/heads/main/busybox-aarch64-linux-gnu
chmod +x busybox-aarch64-linux-gnu
mv busybox-aarch64-linux-gnu bin/busybox
popd &>/dev/null || exit 1
popd &>/dev/null || exit 1

View File

@@ -1,408 +0,0 @@
mkdir /bin
mkdir /dev
mkdir /proc
mkdir /sys
mkdir /tmp
symlink /bin/[ /bin/busybox
symlink /bin/[[ /bin/busybox
symlink /bin/acpid /bin/busybox
symlink /bin/add-shell /bin/busybox
symlink /bin/addgroup /bin/busybox
symlink /bin/adduser /bin/busybox
symlink /bin/adjtimex /bin/busybox
symlink /bin/arch /bin/busybox
symlink /bin/arp /bin/busybox
symlink /bin/arping /bin/busybox
symlink /bin/ascii /bin/busybox
symlink /bin/ash /bin/busybox
symlink /bin/awk /bin/busybox
symlink /bin/base32 /bin/busybox
symlink /bin/base64 /bin/busybox
symlink /bin/basename /bin/busybox
symlink /bin/bc /bin/busybox
symlink /bin/beep /bin/busybox
symlink /bin/blkdiscard /bin/busybox
symlink /bin/blkid /bin/busybox
symlink /bin/blockdev /bin/busybox
symlink /bin/bootchartd /bin/busybox
symlink /bin/brctl /bin/busybox
symlink /bin/bunzip2 /bin/busybox
symlink /bin/bzcat /bin/busybox
symlink /bin/bzip2 /bin/busybox
symlink /bin/cal /bin/busybox
symlink /bin/cat /bin/busybox
symlink /bin/chat /bin/busybox
symlink /bin/chattr /bin/busybox
symlink /bin/chgrp /bin/busybox
symlink /bin/chmod /bin/busybox
symlink /bin/chown /bin/busybox
symlink /bin/chpasswd /bin/busybox
symlink /bin/chpst /bin/busybox
symlink /bin/chroot /bin/busybox
symlink /bin/chrt /bin/busybox
symlink /bin/chvt /bin/busybox
symlink /bin/cksum /bin/busybox
symlink /bin/clear /bin/busybox
symlink /bin/cmp /bin/busybox
symlink /bin/comm /bin/busybox
symlink /bin/conspy /bin/busybox
symlink /bin/cp /bin/busybox
symlink /bin/cpio /bin/busybox
symlink /bin/crc32 /bin/busybox
symlink /bin/crond /bin/busybox
symlink /bin/crontab /bin/busybox
symlink /bin/cryptpw /bin/busybox
symlink /bin/cttyhack /bin/busybox
symlink /bin/cut /bin/busybox
symlink /bin/date /bin/busybox
symlink /bin/dc /bin/busybox
symlink /bin/dd /bin/busybox
symlink /bin/deallocvt /bin/busybox
symlink /bin/delgroup /bin/busybox
symlink /bin/deluser /bin/busybox
symlink /bin/depmod /bin/busybox
symlink /bin/devmem /bin/busybox
symlink /bin/df /bin/busybox
symlink /bin/dhcprelay /bin/busybox
symlink /bin/diff /bin/busybox
symlink /bin/dirname /bin/busybox
symlink /bin/dmesg /bin/busybox
symlink /bin/dnsd /bin/busybox
symlink /bin/dnsdomainname /bin/busybox
symlink /bin/dos2unix /bin/busybox
symlink /bin/dpkg /bin/busybox
symlink /bin/dpkg-deb /bin/busybox
symlink /bin/du /bin/busybox
symlink /bin/dumpkmap /bin/busybox
symlink /bin/dumpleases /bin/busybox
symlink /bin/echo /bin/busybox
symlink /bin/ed /bin/busybox
symlink /bin/egrep /bin/busybox
symlink /bin/eject /bin/busybox
symlink /bin/env /bin/busybox
symlink /bin/envdir /bin/busybox
symlink /bin/envuidgid /bin/busybox
symlink /bin/ether-wake /bin/busybox
symlink /bin/expand /bin/busybox
symlink /bin/expr /bin/busybox
symlink /bin/factor /bin/busybox
symlink /bin/fakeidentd /bin/busybox
symlink /bin/fallocate /bin/busybox
symlink /bin/false /bin/busybox
symlink /bin/fatattr /bin/busybox
symlink /bin/fbset /bin/busybox
symlink /bin/fbsplash /bin/busybox
symlink /bin/fdflush /bin/busybox
symlink /bin/fdformat /bin/busybox
symlink /bin/fdisk /bin/busybox
symlink /bin/fgconsole /bin/busybox
symlink /bin/fgrep /bin/busybox
symlink /bin/find /bin/busybox
symlink /bin/findfs /bin/busybox
symlink /bin/flock /bin/busybox
symlink /bin/fold /bin/busybox
symlink /bin/free /bin/busybox
symlink /bin/freeramdisk /bin/busybox
symlink /bin/fsck /bin/busybox
symlink /bin/fsck.minix /bin/busybox
symlink /bin/fsfreeze /bin/busybox
symlink /bin/fstrim /bin/busybox
symlink /bin/fsync /bin/busybox
symlink /bin/ftpd /bin/busybox
symlink /bin/ftpget /bin/busybox
symlink /bin/ftpput /bin/busybox
symlink /bin/fuser /bin/busybox
symlink /bin/getopt /bin/busybox
symlink /bin/getty /bin/busybox
symlink /bin/grep /bin/busybox
symlink /bin/groups /bin/busybox
symlink /bin/gunzip /bin/busybox
symlink /bin/gzip /bin/busybox
symlink /bin/halt /bin/busybox
symlink /bin/hd /bin/busybox
symlink /bin/hdparm /bin/busybox
symlink /bin/head /bin/busybox
symlink /bin/hexdump /bin/busybox
symlink /bin/hexedit /bin/busybox
symlink /bin/hostid /bin/busybox
symlink /bin/hostname /bin/busybox
symlink /bin/httpd /bin/busybox
symlink /bin/hush /bin/busybox
symlink /bin/hwclock /bin/busybox
symlink /bin/i2cdetect /bin/busybox
symlink /bin/i2cdump /bin/busybox
symlink /bin/i2cget /bin/busybox
symlink /bin/i2cset /bin/busybox
symlink /bin/i2ctransfer /bin/busybox
symlink /bin/id /bin/busybox
symlink /bin/ifconfig /bin/busybox
symlink /bin/ifdown /bin/busybox
symlink /bin/ifenslave /bin/busybox
symlink /bin/ifplugd /bin/busybox
symlink /bin/ifup /bin/busybox
symlink /bin/inetd /bin/busybox
symlink /bin/init /bin/busybox
symlink /bin/insmod /bin/busybox
symlink /bin/install /bin/busybox
symlink /bin/ionice /bin/busybox
symlink /bin/iostat /bin/busybox
symlink /bin/ip /bin/busybox
symlink /bin/ipaddr /bin/busybox
symlink /bin/ipcalc /bin/busybox
symlink /bin/ipcrm /bin/busybox
symlink /bin/ipcs /bin/busybox
symlink /bin/iplink /bin/busybox
symlink /bin/ipneigh /bin/busybox
symlink /bin/iproute /bin/busybox
symlink /bin/iprule /bin/busybox
symlink /bin/iptunnel /bin/busybox
symlink /bin/kbd_mode /bin/busybox
symlink /bin/kill /bin/busybox
symlink /bin/killall /bin/busybox
symlink /bin/killall5 /bin/busybox
symlink /bin/klogd /bin/busybox
symlink /bin/last /bin/busybox
symlink /bin/less /bin/busybox
symlink /bin/link /bin/busybox
symlink /bin/linux32 /bin/busybox
symlink /bin/linux64 /bin/busybox
symlink /bin/linuxrc /bin/busybox
symlink /bin/ln /bin/busybox
symlink /bin/loadfont /bin/busybox
symlink /bin/loadkmap /bin/busybox
symlink /bin/logger /bin/busybox
symlink /bin/login /bin/busybox
symlink /bin/logname /bin/busybox
symlink /bin/logread /bin/busybox
symlink /bin/losetup /bin/busybox
symlink /bin/lpd /bin/busybox
symlink /bin/lpq /bin/busybox
symlink /bin/lpr /bin/busybox
symlink /bin/ls /bin/busybox
symlink /bin/lsattr /bin/busybox
symlink /bin/lsmod /bin/busybox
symlink /bin/lsof /bin/busybox
symlink /bin/lspci /bin/busybox
symlink /bin/lsscsi /bin/busybox
symlink /bin/lsusb /bin/busybox
symlink /bin/lzcat /bin/busybox
symlink /bin/lzma /bin/busybox
symlink /bin/lzop /bin/busybox
symlink /bin/makedevs /bin/busybox
symlink /bin/makemime /bin/busybox
symlink /bin/man /bin/busybox
symlink /bin/md5sum /bin/busybox
symlink /bin/mdev /bin/busybox
symlink /bin/mesg /bin/busybox
symlink /bin/microcom /bin/busybox
symlink /bin/mim /bin/busybox
symlink /bin/mkdir /bin/busybox
symlink /bin/mkdosfs /bin/busybox
symlink /bin/mke2fs /bin/busybox
symlink /bin/mkfifo /bin/busybox
symlink /bin/mkfs.ext2 /bin/busybox
symlink /bin/mkfs.minix /bin/busybox
symlink /bin/mkfs.vfat /bin/busybox
symlink /bin/mknod /bin/busybox
symlink /bin/mkpasswd /bin/busybox
symlink /bin/mkswap /bin/busybox
symlink /bin/mktemp /bin/busybox
symlink /bin/modinfo /bin/busybox
symlink /bin/modprobe /bin/busybox
symlink /bin/more /bin/busybox
symlink /bin/mount /bin/busybox
symlink /bin/mountpoint /bin/busybox
symlink /bin/mpstat /bin/busybox
symlink /bin/mt /bin/busybox
symlink /bin/mv /bin/busybox
symlink /bin/nameif /bin/busybox
symlink /bin/nanddump /bin/busybox
symlink /bin/nandwrite /bin/busybox
symlink /bin/nbd-client /bin/busybox
symlink /bin/nc /bin/busybox
symlink /bin/netstat /bin/busybox
symlink /bin/nice /bin/busybox
symlink /bin/nl /bin/busybox
symlink /bin/nmeter /bin/busybox
symlink /bin/nohup /bin/busybox
symlink /bin/nologin /bin/busybox
symlink /bin/nproc /bin/busybox
symlink /bin/nsenter /bin/busybox
symlink /bin/nslookup /bin/busybox
symlink /bin/ntpd /bin/busybox
symlink /bin/od /bin/busybox
symlink /bin/openvt /bin/busybox
symlink /bin/partprobe /bin/busybox
symlink /bin/passwd /bin/busybox
symlink /bin/paste /bin/busybox
symlink /bin/patch /bin/busybox
symlink /bin/pgrep /bin/busybox
symlink /bin/pidof /bin/busybox
symlink /bin/ping /bin/busybox
symlink /bin/ping6 /bin/busybox
symlink /bin/pipe_progress /bin/busybox
symlink /bin/pivot_root /bin/busybox
symlink /bin/pkill /bin/busybox
symlink /bin/pmap /bin/busybox
symlink /bin/popmaildir /bin/busybox
symlink /bin/poweroff /bin/busybox
symlink /bin/powertop /bin/busybox
symlink /bin/printenv /bin/busybox
symlink /bin/printf /bin/busybox
symlink /bin/ps /bin/busybox
symlink /bin/pscan /bin/busybox
symlink /bin/pstree /bin/busybox
symlink /bin/pwd /bin/busybox
symlink /bin/pwdx /bin/busybox
symlink /bin/raidautorun /bin/busybox
symlink /bin/rdate /bin/busybox
symlink /bin/rdev /bin/busybox
symlink /bin/readahead /bin/busybox
symlink /bin/readlink /bin/busybox
symlink /bin/readprofile /bin/busybox
symlink /bin/realpath /bin/busybox
symlink /bin/reboot /bin/busybox
symlink /bin/reformime /bin/busybox
symlink /bin/remove-shell /bin/busybox
symlink /bin/renice /bin/busybox
symlink /bin/reset /bin/busybox
symlink /bin/resize /bin/busybox
symlink /bin/resume /bin/busybox
symlink /bin/rev /bin/busybox
symlink /bin/rm /bin/busybox
symlink /bin/rmdir /bin/busybox
symlink /bin/rmmod /bin/busybox
symlink /bin/route /bin/busybox
symlink /bin/rpm /bin/busybox
symlink /bin/rpm2cpio /bin/busybox
symlink /bin/rtcwake /bin/busybox
symlink /bin/run-init /bin/busybox
symlink /bin/run-parts /bin/busybox
symlink /bin/runlevel /bin/busybox
symlink /bin/runsv /bin/busybox
symlink /bin/runsvdir /bin/busybox
symlink /bin/rx /bin/busybox
symlink /bin/script /bin/busybox
symlink /bin/scriptreplay /bin/busybox
symlink /bin/sed /bin/busybox
symlink /bin/seedrng /bin/busybox
symlink /bin/sendmail /bin/busybox
symlink /bin/seq /bin/busybox
symlink /bin/setarch /bin/busybox
symlink /bin/setconsole /bin/busybox
symlink /bin/setfattr /bin/busybox
symlink /bin/setfont /bin/busybox
symlink /bin/setkeycodes /bin/busybox
symlink /bin/setlogcons /bin/busybox
symlink /bin/setpriv /bin/busybox
symlink /bin/setserial /bin/busybox
symlink /bin/setsid /bin/busybox
symlink /bin/setuidgid /bin/busybox
symlink /bin/sh /bin/busybox
symlink /bin/sha1sum /bin/busybox
symlink /bin/sha256sum /bin/busybox
symlink /bin/sha3sum /bin/busybox
symlink /bin/sha512sum /bin/busybox
symlink /bin/showkey /bin/busybox
symlink /bin/shred /bin/busybox
symlink /bin/shuf /bin/busybox
symlink /bin/slattach /bin/busybox
symlink /bin/sleep /bin/busybox
symlink /bin/smemcap /bin/busybox
symlink /bin/softlimit /bin/busybox
symlink /bin/sort /bin/busybox
symlink /bin/split /bin/busybox
symlink /bin/ssl_client /bin/busybox
symlink /bin/start-stop-daemon /bin/busybox
symlink /bin/stat /bin/busybox
symlink /bin/strings /bin/busybox
symlink /bin/stty /bin/busybox
symlink /bin/su /bin/busybox
symlink /bin/sulogin /bin/busybox
symlink /bin/sum /bin/busybox
symlink /bin/sv /bin/busybox
symlink /bin/svc /bin/busybox
symlink /bin/svlogd /bin/busybox
symlink /bin/svok /bin/busybox
symlink /bin/swapoff /bin/busybox
symlink /bin/swapon /bin/busybox
symlink /bin/switch_root /bin/busybox
symlink /bin/sync /bin/busybox
symlink /bin/sysctl /bin/busybox
symlink /bin/syslogd /bin/busybox
symlink /bin/tac /bin/busybox
symlink /bin/tail /bin/busybox
symlink /bin/tar /bin/busybox
symlink /bin/taskset /bin/busybox
symlink /bin/tc /bin/busybox
symlink /bin/tcpsvd /bin/busybox
symlink /bin/tee /bin/busybox
symlink /bin/telnet /bin/busybox
symlink /bin/telnetd /bin/busybox
symlink /bin/test /bin/busybox
symlink /bin/tftp /bin/busybox
symlink /bin/tftpd /bin/busybox
symlink /bin/time /bin/busybox
symlink /bin/timeout /bin/busybox
symlink /bin/top /bin/busybox
symlink /bin/touch /bin/busybox
symlink /bin/tr /bin/busybox
symlink /bin/traceroute /bin/busybox
symlink /bin/traceroute6 /bin/busybox
symlink /bin/tree /bin/busybox
symlink /bin/true /bin/busybox
symlink /bin/truncate /bin/busybox
symlink /bin/ts /bin/busybox
symlink /bin/tsort /bin/busybox
symlink /bin/tty /bin/busybox
symlink /bin/ttysize /bin/busybox
symlink /bin/tunctl /bin/busybox
symlink /bin/ubiattach /bin/busybox
symlink /bin/ubidetach /bin/busybox
symlink /bin/ubimkvol /bin/busybox
symlink /bin/ubirename /bin/busybox
symlink /bin/ubirmvol /bin/busybox
symlink /bin/ubirsvol /bin/busybox
symlink /bin/ubiupdatevol /bin/busybox
symlink /bin/udhcpc /bin/busybox
symlink /bin/udhcpc6 /bin/busybox
symlink /bin/udhcpd /bin/busybox
symlink /bin/udpsvd /bin/busybox
symlink /bin/uevent /bin/busybox
symlink /bin/umount /bin/busybox
symlink /bin/uname /bin/busybox
symlink /bin/unexpand /bin/busybox
symlink /bin/uniq /bin/busybox
symlink /bin/unix2dos /bin/busybox
symlink /bin/unlink /bin/busybox
symlink /bin/unlzma /bin/busybox
symlink /bin/unshare /bin/busybox
symlink /bin/unxz /bin/busybox
symlink /bin/unzip /bin/busybox
symlink /bin/uptime /bin/busybox
symlink /bin/users /bin/busybox
symlink /bin/usleep /bin/busybox
symlink /bin/uudecode /bin/busybox
symlink /bin/uuencode /bin/busybox
symlink /bin/vconfig /bin/busybox
symlink /bin/vi /bin/busybox
symlink /bin/vlock /bin/busybox
symlink /bin/volname /bin/busybox
symlink /bin/w /bin/busybox
symlink /bin/wall /bin/busybox
symlink /bin/watch /bin/busybox
symlink /bin/watchdog /bin/busybox
symlink /bin/wc /bin/busybox
symlink /bin/wget /bin/busybox
symlink /bin/which /bin/busybox
symlink /bin/who /bin/busybox
symlink /bin/whoami /bin/busybox
symlink /bin/whois /bin/busybox
symlink /bin/xargs /bin/busybox
symlink /bin/xxd /bin/busybox
symlink /bin/xz /bin/busybox
symlink /bin/xzcat /bin/busybox
symlink /bin/yes /bin/busybox
symlink /bin/zcat /bin/busybox
symlink /bin/zcip /bin/busybox
quit