From 1b8fa91f836c3d5b4f57db88134d72dcd4dfc5cb Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 31 Oct 2021 23:28:25 -0500 Subject: [PATCH] Multiple mkroot changes. --- scripts/mkroot.sh | 109 ++++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/scripts/mkroot.sh b/scripts/mkroot.sh index 7abff1a7..f4040f3d 100755 --- a/scripts/mkroot.sh +++ b/scripts/mkroot.sh @@ -1,8 +1,13 @@ #!/bin/bash +# ----- Setup environment + +die() { echo "$@" >&2; exit 1; } +announce() { echo -e "\033]2;$CROSS $*\007\n=== $*"; } + # Clear environment variables by restarting script w/bare minimum passed through [ -z "$NOCLEAR" ] && exec env -i NOCLEAR=1 HOME="$HOME" PATH="$PATH" \ - "LINUX=$LINUX" "CROSS=$CROSS" CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@" + LINUX="$LINUX" CROSS="$CROSS" CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@" # assign command line NAME=VALUE args to env vars, keeping rest as packages while [ $# -ne 0 ]; do @@ -10,63 +15,63 @@ while [ $# -ne 0 ]; do { [ "$1" != '--' ] && PKG="${PKG:-plumbing} $1"; } shift done +mkdir -p ${TOP:=$PWD/root} ${LOG:=$TOP/log} ${BUILD:=$TOP/build} || exit 1 +: ${PKGDIR:=$PWD/scripts/root} -die() { echo "$@" >&2; exit 1; } -announce() { echo -e "\033]2;$CROSS $*\007\n=== $*"; } - -# Create target-independent working directories (cmdline can change locations) -TOP="$PWD/root" -mkdir -p ${BUILD:=$TOP/build} ${AIRLOCK:=$TOP/airlock} ${LOG:=$TOP/log} ||exit 1 - -# set CROSS_COMPILE from $CROSS using ccc. Handle "all" w/log, list, and err chk +# Are we cross compiling? if [ ! -z "$CROSS" ]; then [ ! -d "${CCC:=$PWD/ccc}" ] && die "No ccc symlink to compiler directory." - CROSS_COMPILE="$(echo "$CCC/$CROSS"-*cross/bin/"$CROSS"*-cc | sed 's/cc$//')" - if [ "${CROSS::3}" == all ]; then - for i in $(ls "$CCC" | sed -n 's/-.*//p' | sort -u | xargs); do - { rm -f "$LOG/$i-log".{failed,success} - "$0" "$@" CROSS=$i ; [ $? -eq 0 ] && mv "$LOG/$i".{txt,success} - } |& tee "$LOG/$i.txt" - [ ! -e "$LOG/$i.success" ] && - { mv "$LOG/$i".{txt,failed};[ "$CROSS" != allnonstop ] && exit 1; } + if [ "${CROSS::3}" == all ]; then # loop calling ourselves each target in ccc + for i in $(ls "$CCC" | sed -n 's/-.*//p' | sort -u); do + rm -f "$LOG/$i".{n,y} + { "$0" "$@" CROSS=$i && mv "$LOG/$i".{n,y};} |& tee "$LOG/$i.n" + [ ! -e "$LOG/$i.y" ] && [ "$CROSS" != allnonstop ] && exit 1; done exit - elif [ ! -e "${CROSS_COMPILE}cc" ]; then - ls "$CCC" | sed -n 's/-.*//p' | sort -u | xargs - exit + else # Set $CROSS_COMPILE and $CROSS_PATH from $CROSS using ccc directory + CROSS_COMPILE="$(echo "$CCC/$CROSS"-*cross/bin/"$CROSS"*-cc)" + [ ! -e "$CROSS_COMPILE" ] && # Show available targets + { ls "$CCC" | sed -n 's/-.*//p' | sort -u | xargs; exit;} + CROSS_PATH="$(dirname "$(which "$CROSS_COMPILE")")" + [ -z "$CROSS_PATH" ] && die "no $CROSS_COMPILE in path" + CROSS_COMPILE="${CROSS_COMPILE%cc}" fi fi ${CROSS_COMPILE}cc --static -xc - -o /dev/null <<< "int main(void){return 0;}"|| die "${CROSS_COMPILE}cc can't create static binaries" - -# Parse and sanity check $CROSS_COMPILE (if any) -if [ ! -z "$CROSS_COMPILE" ]; then - CROSS_PATH="$(dirname "$(which "${CROSS_COMPILE}cc")")" - [ -z "$CROSS_PATH" ] && die "no ${CROSS_COMPILE}cc in path" - : ${CROSS_BASE:=$(basename "$CROSS_COMPILE")} ${CROSS:=${CROSS_BASE/-*/}} -fi echo "Building for ${CROSS:=host}" -# Create target-specific work/output directories -: ${OUTPUT:=$TOP/$CROSS} ${PKGDIR:=$PWD/scripts/root} -MYBUILD="$BUILD/${CROSS_BASE:-host-}tmp" +# Create work/output directories (command line can override these) +mkdir -p ${OUTPUT:=$TOP/$CROSS} || exit 1 +MYBUILD="$BUILD/${CROSS}-tmp" # only rm -r things WE SET rm -rf "$MYBUILD" && mkdir -p "$MYBUILD" || exit 1 -[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT" # only blank if NOT set +[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT" -# When cross compiling build everything under a host toybox with known behavior +# ----- Build airlock + +# When cross compiling build under a host toybox with known behavior if [ ! -z "$CROSS_COMPILE" ]; then - if [ ! -e "$AIRLOCK/toybox" ]; then + if [ ! -e "${AIRLOCK:=$TOP/airlock}/toybox" ]; then announce "airlock" PREFIX="$AIRLOCK" KCONFIG_CONFIG="$TOP"/.airlock CROSS_COMPILE= \ make clean defconfig toybox install_airlock && rm "$TOP"/.airlock ||exit 1 fi - export PATH="$CROSS_PATH:$AIRLOCK" + export PATH="${CROSS_PATH:+$CROSS_PATH:}$AIRLOCK" + + # Install command line logging wrapper + if [ ! -z "$LLOG" ]; then + WRAPDIR="$TOP/$AIRLOCK/record-commands" && + export WRAPLOG="$LOG/commands-$CROSS.txt" && + KCONFIG_CONFIG="$TOP"/airlock source scripts/record-commands || exit 1 + fi fi -# Create new root filesystem's directory layout -mkdir -p "$ROOT"/{etc,tmp,proc,sys,dev,home,mnt,root,usr/{bin,sbin,lib},var} && -chmod a+rwxt "$ROOT"/tmp && ln -s usr/{bin,sbin,lib} "$ROOT" || exit 1 +# ----- Create new root filesystem's directory layout. + +# FHS wants boot media opt srv usr/{local,share}, stuff under /var... +mkdir -p "$ROOT"/{dev,etc/rc,home,mnt,proc,root,sys,tmp/run,usr/{bin,sbin,lib},var} && +chmod a+rwxt "$ROOT"/tmp && ln -s usr/{bin,sbin,lib} tmp/run "$ROOT" || exit 1 # Write init script. Runs as pid 1 from initramfs to set up and hand off system. cat > "$ROOT"/init << 'EOF' && @@ -75,14 +80,14 @@ cat > "$ROOT"/init << 'EOF' && export HOME=/home PATH=/bin:/sbin if ! mountpoint -q dev; then - mount -t devtmpfs dev dev || mdev -s - [ $$ -eq 1 ] && exec >/dev/console 2>&1 + mount -t devtmpfs dev dev + [ $$ -eq 1 ] && exec 0<>/dev/console 1>&0 2>&1 for i in ,fd /0,stdin /1,stdout /2,stderr do ln -sf /proc/self/fd${i/,*/} dev/${i/*,/}; done mkdir -p dev/{shm,pts} - mountpoint -q dev/pts || mount -t devpts dev/pts dev/pts chmod +t /dev/shm fi +mountpoint -q dev/pts || mount -t devpts dev/pts dev/pts mountpoint -q proc || mount -t proc proc proc mountpoint -q sys || mount -t sysfs sys sys @@ -94,7 +99,7 @@ if [ $$ -eq 1 ]; then # Setup networking for QEMU (needs /proc) [ "$(date +%s)" -lt 10000000 ] && sntp -sq time.google.com # Run package scripts (if any) - [ -e /etc/rc ] && for i in $(echo /etc/rc/* | sort); do . $i; done + for i in /etc/rc/*; do [ -e "$i" ] && . "$i"; done [ -z "$CONSOLE" ] && CONSOLE="$( "$ROOT"/etc/group || exit 1 announce toybox [ -e .config ] && [ -z "$PENDING" ] && CONF=silentoldconfig || unset CONF for i in $PENDING sh route; do XX="$XX"$'\n'CONFIG_${i^^?}=y; done -make clean ${CONF:-defconfig KCONFIG_ALLCONFIG=<(echo "$XX")} && -LDFLAGS=--static PREFIX="$ROOT" make toybox install || exit 1 +LDFLAGS=--static PREFIX="$ROOT" make clean \ + ${CONF:-defconfig KCONFIG_ALLCONFIG=<(echo "$XX")} toybox install || exit 1 # Build any packages listed on command line for i in $PKG; do - announce "$i"; PATH="$PKGDIR:$PATH" source $i; [ $? -ne 0 ] && die $i + announce "$i"; PATH="$PKGDIR:$PATH" source $i || die $i done if [ -z "$LINUX" ] || [ ! -d "$LINUX/kernel" ]; then @@ -133,8 +138,8 @@ if [ -z "$LINUX" ] || [ ! -d "$LINUX/kernel" ]; then else # Which architecture are we building a kernel for? LINUX="$(realpath "$LINUX")" - [ -z "$TARGET" ] && TARGET="${CROSS_BASE/-*/}" - [ -z "$TARGET" ] && TARGET="$(uname -m)" + [ -z "$TARGET" ] && + { [ "$CROSS" == host ] && TARGET="$(uname -m)" || TARGET="$CROSS"; } # Target-specific info in an (alphabetical order) if/else staircase # Each target needs board config, serial console, RTC, ethernet, block device. @@ -204,7 +209,7 @@ CONFIG_CMDLINE="console=ttyUL0 earlycon"' BUILTIN=1 # Write the qemu launch script if [ ! -z "$QEMU" ]; then - [ -z "$BUILTIN" ] && INITRD="-initrd ${CROSS_BASE}root.cpio.gz" + [ -z "$BUILTIN" ] && INITRD="-initrd ${CROSS}root.cpio.gz" echo qemu-system-"$QEMU" '"$@"' $QEMU_MORE -nographic -no-reboot -m 256 \ -kernel $(basename $VMLINUX) $INITRD \ "-append \"panic=1 HOST=$TARGET console=$KARGS \$KARGS\"" \ @@ -216,6 +221,8 @@ CONFIG_CMDLINE="console=ttyUL0 earlycon"' BUILTIN=1 announce "linux-$KARCH" pushd "$LINUX" && make distclean && popd && cp -sfR "$LINUX" "$MYBUILD/linux" && pushd "$MYBUILD/linux" && + # Work around x86-64 bug + sed -is '/select HAVE_STACK_VALIDATION/d' arch/x86/Kconfig && # Write miniconfig { echo "# make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG=$TARGET.miniconf" @@ -223,7 +230,7 @@ CONFIG_CMDLINE="console=ttyUL0 earlycon"' BUILTIN=1 echo "# CONFIG_EMBEDDED is not set" # Expand list of =y symbols, first generic then architecture-specific - for i in BINFMT_ELF,BINFMT_SCRIPT,NO_HZ,HIGH_RES_TIMERS,BLK_DEV,BLK_DEV_INITRD,RD_GZIP,BLK_DEV_LOOP,EXT4_FS,EXT4_USE_FOR_EXT2,VFAT_FS,FAT_DEFAULT_UTF8,MISC_FILESYSTEMS,SQUASHFS,SQUASHFS_XATTR,SQUASHFS_ZLIB,DEVTMPFS,DEVTMPFS_MOUNT,TMPFS,TMPFS_POSIX_ACL,NET,PACKET,UNIX,INET,IPV6,NETDEVICES,NET_CORE,NETCONSOLE,ETHERNET,COMPAT_32BIT_TIME,EARLY_PRINTK,IKCONFIG,IKCONFIG_PROC $KCONF ; do + for i in BINFMT_ELF,BINFMT_SCRIPT,NO_HZ,HIGH_RES_TIMERS,BLK_DEV,BLK_DEV_INITRD,RD_GZIP,BLK_DEV_LOOP,EXT4_FS,EXT4_USE_FOR_EXT2,VFAT_FS,FAT_DEFAULT_UTF8,MISC_FILESYSTEMS,SQUASHFS,SQUASHFS_XATTR,SQUASHFS_ZLIB,DEVTMPFS,DEVTMPFS_MOUNT,TMPFS,TMPFS_POSIX_ACL,NET,PACKET,UNIX,INET,IPV6,NETDEVICES,NET_CORE,NETCONSOLE,ETHERNET,COMPAT_32BIT_TIME,EARLY_PRINTK,IKCONFIG,IKCONFIG_PROC $KCONF $KEXTRA ; do echo "# architecture ${X:-independent}" sed -E '/^$/d;s/([^,]*)($|,)/CONFIG_\1=y\n/g' <<< "$i" X=specific @@ -248,7 +255,7 @@ CONFIG_CMDLINE="console=ttyUL0 earlycon"' BUILTIN=1 fi # clean up and package root filesystem for initramfs. -[ -z "$BUILTIN" ] && announce "${CROSS_BASE}root.cpio.gz" && +[ -z "$BUILTIN" ] && announce "${CROSS}root.cpio.gz" && (cd "$ROOT" && find . | cpio -o -H newc ${CROSS_COMPILE:+--no-preserve-owner} | gzip) \ - > "$OUTPUT/$CROSS_BASE"root.cpio.gz -rmdir "$MYBUILD" "$BUILD" 2>/dev/null # remove if empty + > "$OUTPUT/$CROSS"root.cpio.gz +rmdir "$MYBUILD" "$BUILD" 2>/dev/null || exit 0 # remove if empty, not an error -- 2.39.2