2025-03-29 03:52:35 -04:00

141 lines
6.0 KiB
Bash

#!/bin/bash
# Builds a bootable floppy that contains a Linux OS acting as a router
set -e +h
if [ -z "${SCRIPT_DIR}" ]; then
export SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
fi
source "${SCRIPT_DIR}/.include.sh"
source "${SCRIPT_DIR}/packages.conf"
export BUILD_DIR="${SCRIPT_DIR}/build"
export SOURCE_DIR="${SCRIPT_DIR}/src"
export SYSROOT="${BUILD_DIR}/sysroot"
export OUT_FILE="${SCRIPT_DIR}/boot-disk.img"
export TARGET="i486-linux-musl"
# Default to using as many cores for building software as your system has for "make"
export MAKEFLAGS="${MAKEFLAGS:--j$(nproc)}"
if [ ! -d "${SYSROOT}/dev" ]; then
log "Creating basic directories and symlinks in target"
test -d "${SYSROOT}" || mkdir -p "${SYSROOT}" || fail create target directory "${SYSROOT}"
for DIR in /dev /proc /run /sys /usr/bin /usr/sbin /var/lib/misc /etc; do
test -d "${SYSROOT}${DIR}" || mkdir -p "${SYSROOT}${DIR}" || fail create basic directory "${DIR}" in target
done
test -e "${SYSROOT}/var/run" || ln -s ../run "${SYSROOT}/var/run" || fail create basic symlink /var/run
test -e "${SYSROOT}/bin" || ln -s usr/bin "${SYSROOT}/bin" || fail create basic symlink /bin
test -e "${SYSROOT}/sbin" || ln -s usr/sbin "${SYSROOT}/sbin" || fail create basic symlink /sbin
fi
if [ ! -e "${SYSROOT}/dev/console" ]; then
log "Creating basic device nodes"
test -e "${SYSROOT}/dev/console" || \
$SUDO mknod -m 640 "${SYSROOT}/dev/console" c 5 1 || fail create console node
test -e "${SYSROOT}/dev/null" || \
$SUDO mknod -m 664 "${SYSROOT}/dev/null" c 1 3 || fail create null node
fi
if [ ! -d "${BUILD_DIR}/musl-cross-toolchain" ]; then
log "Build musl-cross-make toolchain"
get_pkg_src "musl_cross_make"
cd "${SOURCE_DIR}/musl-cross-make-${MUSL_CROSS_MAKE_VERSION}"
echo "TARGET = ${TARGET}" > config.mak
echo "OUTPUT = ${BUILD_DIR}/musl-cross-toolchain" >> config.mak
make >/dev/null || fail build musl-cross-make toolchain
make install >/dev/null || fail install musl-cross-make toolchain
fi
export PATH="$PATH:${BUILD_DIR}/musl-cross-toolchain/bin"
if [ ! -e "${SYSROOT}/bin/busybox" ]; then
log "Build BusyBox binary"
get_pkg_src "busybox"
if [ ! -e "${SOURCE_DIR}/busybox-${BUSYBOX_VERSION}/.config" ]; then
cd "${SOURCE_DIR}/busybox-${BUSYBOX_VERSION}"
cp "${SCRIPT_DIR}/configs/busybox.config" ".config" || fail copy BusyBox configuration
sed "s#%%COMPPREFIX%%#${TARGET}-#" -i ".config" || fail Modify BusyBox compiler prefix
sed "s#%%TARGET_DIR%%#${SYSROOT}#" -i ".config" || fail Modify BusyBox target directory
fi
make >/dev/null || fail build BusyBox
make install >/dev/null || fail install BusyBox
fi
if [ ! -e "${SYSROOT}/usr/sbin/wg" ]; then
log "Build Wireguard Tools"
get_pkg_src "wireguard_tools"
cd "${SOURCE_DIR}/wireguard-tools-${WIREGUARD_TOOLS_VERSION}/src"
CC="${TARGET}-gcc" LD="${TARGET}-ld" CFLAGS="--static -static" LDFLAGS="-static" \
make >/dev/null || fail build Wireguard Tools
"${TARGET}-strip" wg || fail strip Wireguard binary
test -d "${SYSROOT}/usr/sbin" || mkdir -p "${SYSROOT}/usr/sbin" || fail create /usr/sbin in target
cp wg "${SYSROOT}/usr/sbin/wg" || fail copy Wireguard binary to target
fi
if [ ! -e "${SYSROOT}/usr/sbin/iptables" ]; then
log "Build IPtables"
get_pkg_src iptables
# When building IPtables statically, it includes all known extensions into the final binary
# We only need a few of them, so here we copy only the necessary extensions into the source tree
cd "${SOURCE_DIR}/iptables-${IPTABLES_VERSION}"
test -d "extensions.orig" || mv "extensions" "extensions.orig" || fail move IPtables extensions directory
test -d "extensions" || mkdir "extensions" || fail create new IPtables extensions directory
while read -r FILE; do
cp "extensions.orig/${FILE}" "extensions/" || fail copy IPtables extension file "${FILE}"
done < "${SCRIPT_DIR}/configs/iptables-extension-files"
builddir "iptables"
CFLAGS="--static -static" LDFLAGS="-static" \
"${SOURCE_DIR}/iptables-${IPTABLES_VERSION}/configure" \
--prefix= \
--disable-nftables \
--disable-devel \
--disable-ipv6 \
--disable-largefile \
--enable-static \
--disable-shared \
--host="${TARGET}" >/dev/null || fail configure IPtables
make >/dev/null || fail build IPtables
make install DESTDIR="${BUILD_DIR}/iptables-install" >/dev/null || fail temporarily install IPtables
"${TARGET}-strip" "${BUILD_DIR}/iptables-install/sbin/xtables-legacy-multi" || fail strip IPtables binary
cp -a "${BUILD_DIR}/iptables-install/sbin/." "${SYSROOT}/usr/sbin" || fail copy IPtables binary to target
fi
if [ -d "${SCRIPT_DIR}/initramfs-source" ]; then
log "Copying base files into target"
cp -a "${SCRIPT_DIR}/initramfs-source/." "${SYSROOT}/" || fail copy initramfs base files into target
fi
log "Building Linux kernel"
get_pkg_src "linux"
cd "${SOURCE_DIR}/linux-${LINUX_VERSION}"
if [ ! -e "${SOURCE_DIR}/linux-${LINUX_VERSION}/.config" ]; then
cp "${SCRIPT_DIR}/configs/linux.config" ".config" || fail copy Linux configuration
sed "s#%%INITRAMFS_SOURCE%%#${SYSROOT}#" -i ".config" || fail Modify Linux initramfs file source
sed "s#%%BUILDER_UID%%#$(id -u)#" -i ".config" || fail Modify Linux building user ID
sed "s#%%BUILDER_GID%%#$(id -g)#" -i ".config" || fail Modify Linux building user group ID
fi
make bzImage >/dev/null || fail build Linux kernel
KERNEL_SIZE="$(stat -c "%s" "arch/x86/boot/bzImage")"
if (( KERNEL_SIZE + 512 > 1024 * 1440 )); then
fail "check kernel size, $(( 1024 * 1440 - 512 - KERNEL_SIZE )) bytes over"
else
log "Kernel size valid"
fi
log "Create bootable floppy image"
get_pkg_src "tiny_floppy_bootloader"
cp "${SCRIPT_DIR}/configs/tfb-build.sh" "${SOURCE_DIR}/tiny-floppy-bootloader-${TINY_FLOPPY_BOOTLOADER_VERSION}/"
bash "${SOURCE_DIR}/tiny-floppy-bootloader-${TINY_FLOPPY_BOOTLOADER_VERSION}/tfb-build.sh" \
"${SOURCE_DIR}/linux-${LINUX_VERSION}/arch/x86/boot/bzImage" \
"${OUT_FILE}"
log "Done! Your floppy image is at ${OUT_FILE}"
log "To try it, run 'sudo bash run-qemu.sh $(basename "${OUT_FILE}")'"