diff --git a/Dockerfile b/Dockerfile index 2e34ab2..6dd248d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/Justfile b/Justfile new file mode 100755 index 0000000..318d2c8 --- /dev/null +++ b/Justfile @@ -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 diff --git a/README.md b/README.md index 7022941..6972330 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/scripts/build-deps.sh b/scripts/build-deps.sh deleted file mode 100755 index cea46ff..0000000 --- a/scripts/build-deps.sh +++ /dev/null @@ -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 diff --git a/scripts/create-image.sh b/scripts/create-image.sh index 3b02635..3726e45 100755 --- a/scripts/create-image.sh +++ b/scripts/create-image.sh @@ -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 diff --git a/scripts/deps/README.md b/scripts/deps/README.md deleted file mode 100644 index 1d9b1ff..0000000 --- a/scripts/deps/README.md +++ /dev/null @@ -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. \ No newline at end of file diff --git a/scripts/deps/bash b/scripts/deps/bash deleted file mode 100755 index 0d34c82..0000000 --- a/scripts/deps/bash +++ /dev/null @@ -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 diff --git a/scripts/deps/busybox b/scripts/deps/busybox deleted file mode 100755 index 9ea1252..0000000 --- a/scripts/deps/busybox +++ /dev/null @@ -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 diff --git a/scripts/deps/usertest b/scripts/deps/usertest deleted file mode 100755 index a20ea70..0000000 --- a/scripts/deps/usertest +++ /dev/null @@ -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/ diff --git a/scripts/mac-experimental/README.md b/scripts/mac-experimental/README.md deleted file mode 100644 index 320d4c2..0000000 --- a/scripts/mac-experimental/README.md +++ /dev/null @@ -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! diff --git a/scripts/mac-experimental/build-deps.sh b/scripts/mac-experimental/build-deps.sh deleted file mode 100755 index 90bcec2..0000000 --- a/scripts/mac-experimental/build-deps.sh +++ /dev/null @@ -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 diff --git a/scripts/mac-experimental/create-image.sh b/scripts/mac-experimental/create-image.sh deleted file mode 100755 index c2fb6bb..0000000 --- a/scripts/mac-experimental/create-image.sh +++ /dev/null @@ -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 || exit 1 diff --git a/scripts/mac-experimental/deps/bash b/scripts/mac-experimental/deps/bash deleted file mode 100755 index 843f2e6..0000000 --- a/scripts/mac-experimental/deps/bash +++ /dev/null @@ -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 diff --git a/scripts/mac-experimental/deps/busybox b/scripts/mac-experimental/deps/busybox deleted file mode 100755 index f1fb9d2..0000000 --- a/scripts/mac-experimental/deps/busybox +++ /dev/null @@ -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 \ No newline at end of file diff --git a/scripts/symlinks.cmds b/scripts/symlinks.cmds deleted file mode 100644 index dcfe40a..0000000 --- a/scripts/symlinks.cmds +++ /dev/null @@ -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