diff options
-rwxr-xr-x | scripts/mkroot.sh | 92 |
1 files changed, 48 insertions, 44 deletions
diff --git a/scripts/mkroot.sh b/scripts/mkroot.sh index 3e8d35b3..ade50a06 100755 --- a/scripts/mkroot.sh +++ b/scripts/mkroot.sh @@ -1,60 +1,60 @@ #!/bin/bash # Clear environment variables by restarting script w/bare minimum passed through -# set ALL= LINUX= CROSS= on command line [ -z "$NOCLEAR" ] && exec env -i NOCLEAR=1 HOME="$HOME" PATH="$PATH" \ - CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@" + "LINUX=$LINUX" "CROSS=$CROSS" CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@" -die() { echo "$@" >&2; exit 1; } -announce() { echo -e "\033]2;$CROSS $*\007\n=== $*"; } -getcross() { X="$(echo "$CCC/$1"-*cross/bin/"$1"*-cc)"; echo "${X%cc}"; } - -# assign command line NAME=VALUE args to env vars +# assign command line NAME=VALUE args to env vars, keeping rest as packages while [ $# -ne 0 ]; do [ "${1/=/}" != "$1" ] && eval "export ${1/=*/}=\"\${1#*=}\"" || { [ "$1" != '--' ] && PKG="${PKG:-plumbing} $1"; } shift done -# set output and work directories (can override on cmdline) +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 if [ ! -z "$CROSS" ]; then [ ! -d "${CCC:=$PWD/ccc}" ] && die "No ccc symlink to compiler directory." - if [ "$CROSS" == all ]; then + 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 ; [ $((X=$?)) -eq 0 ] && mv "$LOG/$i".{txt,success} } |& tee "$LOG/$i.txt" [ ! -e "$LOG/$i.success" ] && - { mv "$LOG/$i".{txt,failed};[ -z "$ALL" ] && exit 1; } - done; exit - elif [ ! -e "${CROSS_COMPILE:=$(getcross $CROSS)}cc" ]; then - ls "$CCC" | sed -n 's/-.*//p' | sort -u | xargs; exit + { mv "$LOG/$i".{txt,failed};[ "$CROSS" != allnonstop ] && exit 1; } + done + exit + elif [ ! -e "${CROSS_COMPILE}cc" ]; then + ls "$CCC" | sed -n 's/-.*//p' | sort -u | xargs + exit fi fi -# Digest $CROSS_COMPILE (if any) into appropriate environment variables. -if [ -z "$CROSS_COMPILE" ]; then - if ! cc --static -xc - -o /dev/null <<< "int main(void) {return 0;}"; then - echo "Warning: host compiler can't create static binaries." >&2; sleep 3 - fi -else +${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")")" - CROSS_BASE="$(basename "$CROSS_COMPILE")" [ -z "$CROSS_PATH" ] && die "no ${CROSS_COMPILE}cc in path" - : ${CROSS:=${CROSS_BASE/-*/}} + : ${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} -[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT" MYBUILD="$BUILD/${CROSS_BASE:-host-}tmp" rm -rf "$MYBUILD" && mkdir -p "$MYBUILD" || exit 1 +[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT" # only blank if NOT set -# Provide known $PATH contents (airlock) for cross compile builds +# When cross compiling build everything under a host toybox with known behavior if [ ! -z "$CROSS_COMPILE" ]; then if [ ! -e "$AIRLOCK/toybox" ]; then announce "airlock" @@ -64,11 +64,11 @@ if [ ! -z "$CROSS_COMPILE" ]; then export PATH="$CROSS_PATH:$AIRLOCK" fi -# directory layout +# 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 -# init script. Runs as pid 1 from initramfs to set up and hand off system. +# Write init script. Runs as pid 1 from initramfs to set up and hand off system. cat > "$ROOT"/init << 'EOF' && #!/bin/sh @@ -85,21 +85,20 @@ if ! mountpoint -q dev; then chmod +t /dev/shm fi -if [ $$ -eq 1 ]; then - # Setup networking for QEMU (needs /proc) +if [ $$ -eq 1 ]; then # Setup networking for QEMU (needs /proc) ifconfig lo 127.0.0.1 ifconfig eth0 10.0.2.15 route add default gw 10.0.2.2 [ "$(date +%s)" -lt 1000 ] && timeout 2 sntp -sq 10.0.2.2 # Ask host [ "$(date +%s)" -lt 10000000 ] && sntp -sq time.google.com - # Run expansion scripts (if any) - for i in $(echo /etc/rc/* | sort); do [ -e "$i" ] && . $i; done + # Run package scripts (if any) + [ -e /etc/rc ] && for i in $(echo /etc/rc/* | sort); do . $i; done [ -z "$CONSOLE" ] && CONSOLE="$(</sys/class/tty/console/active)" [ -z "$HANDOFF" ] && HANDOFF=/bin/sh && echo Type exit when done. exec oneit -c /dev/"${CONSOLE:-console}" $HANDOFF -else +else # for chroot /bin/sh umount /dev/pts /dev /sys /proc fi @@ -115,13 +114,16 @@ nobody:x:65534:65534:nobody:/proc/self:/dev/null EOF echo -e 'root:x:0:\nguest:x:500:\nnobody:x:65534:' > "$ROOT"/etc/group || exit 1 +# Build static toybox with existing .config if there is one, else defconfig+sh announce toybox [ -e .config ] && CONF=silentoldconfig || unset CONF make clean ${CONF:-defconfig KCONFIG_ALLCONFIG=<(echo $'CONFIG_SH=y\nCONFIG_ROUTE=y')} && LDFLAGS=--static PREFIX="$ROOT" make toybox install || exit 1 -# Build any modules -for i in $PKG; do announce "$i"; PATH="$PKGDIR:$PATH" source $i; done +# Build any packages listed on command line +for i in $PKG; do + announce "$i"; PATH="$PKGDIR:$PATH" source $i; [ $? -ne 0 ] && die $i +done if [ -z "$LINUX" ] || [ ! -d "$LINUX/kernel" ]; then echo 'No $LINUX directory, kernel build skipped.' @@ -178,14 +180,14 @@ else KARCH=powerpc QEMU="ppc64 -M pseries -vga none" KARGS=/dev/hvc0 VMLINUX=vmlinux KCONF=PPC64,PPC_PSERIES,CPU_LITTLE_ENDIAN,PPC_OF_BOOT_TRAMPOLINE,BLK_DEV_SD,SCSI_LOWLEVEL,SCSI_IBMVSCSI,ATA,NET_VENDOR_IBM,IBMVETH,HVC_CONSOLE,PPC_TRANSACTIONAL_MEM,PPC_DISABLE_WERROR,SECTION_MISMATCH_WARN_ONLY - elif [ "$TARGET" = s390x ] ; then + elif [ "$TARGET" = s390x ]; then QEMU="s390x" KARCH=s390 VMLINUX=arch/s390/boot/bzImage KCONF=MARCH_Z900,PACK_STACK,NET_CORE,VIRTIO_NET,VIRTIO_BLK,SCLP_TTY,SCLP_CONSOLE,SCLP_VT220_TTY,SCLP_VT220_CONSOLE,S390_GUEST - elif [ "$TARGET" == sh2eb ] ; then + elif [ "$TARGET" == sh2eb ]; then KARCH=sh VMLINUX=vmlinux KERNEL_CONFIG='CONFIG_MEMORY_START=0x10000000 -CONFIG_CMDLINE="console=ttyUL0 earlycon"' +CONFIG_CMDLINE="console=ttyUL0 earlycon"' BUILTIN=1 KCONF=CPU_SUBTYPE_J2,CPU_BIG_ENDIAN,SH_JCORE_SOC,SMP,BINFMT_ELF_FDPIC,JCORE_EMAC,SERIAL_UARTLITE,SERIAL_UARTLITE_CONSOLE,HZ_100,CMDLINE_OVERWRITE,SPI,SPI_JCORE,MMC,PWRSEQ_SIMPLE,MMC_BLOCK,MMC_SPI - elif [ "$TARGET" == sh4 ] ; then + elif [ "$TARGET" == sh4 ]; then QEMU="sh4 -M r2d -serial null -serial mon:stdio" KARCH=sh KARGS="ttySC1 noiotrap" VMLINUX=arch/sh/boot/zImage KERNEL_CONFIG="CONFIG_MEMORY_START=0x0c000000" @@ -194,10 +196,11 @@ CONFIG_CMDLINE="console=ttyUL0 earlycon"' else die "Unknown \$TARGET" fi - if [ ! -z "$QEMU" ] ; then - # Write the qemu launch script + # Write the qemu launch script + if [ ! -z "$QEMU" ]; then + [ -z "$BUILTIN" ] && INITRD="-initrd ${CROSS_BASE}root.cpio.gz" echo qemu-system-"$QEMU" '"$@"' $QEMU_MORE -nographic -no-reboot -m 256 \ - "-kernel $(basename "$VMLINUX") -initrd ${CROSS_BASE}root.cpio.gz" \ + -kernel $(basename $VMLINUX) $INITRD \ "-append \"quiet panic=1 HOST=$TARGET console=$KARGS \$KARGS\"" \ ${DTB:+-dtb "$(basename "$DTB")"} ";echo -e '\e[?7h'" \ > "$OUTPUT/qemu-$TARGET.sh" && @@ -214,11 +217,12 @@ CONFIG_CMDLINE="console=ttyUL0 earlycon"' echo "# CONFIG_EMBEDDED is not set" # Expand list of =y symbols, first generic then architecture-specific - for i in EARLY_PRINTK,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 $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 ; do echo "# architecture ${X:-independent}" sed -E '/^$/d;s/([^,]*)($|,)/CONFIG_\1=y\n/g' <<< "$i" X=specific done + [ ! -z "$BUILTIN" ] && echo -e CONFIG_INITRAMFS_SOURCE="\"$OUTPUT/fs\"" echo "$KERNEL_CONFIG" } > "$OUTPUT/miniconfig-$TARGET" && make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG="$OUTPUT/miniconfig-$TARGET" && @@ -238,7 +242,7 @@ CONFIG_CMDLINE="console=ttyUL0 earlycon"' fi # clean up and package root filesystem for initramfs. -rmdir "$MYBUILD" "$BUILD" 2>/dev/null -announce "${CROSS_BASE}root.cpio.gz" -(cd "$ROOT" && find . | cpio -o -H newc --no-preserve-owner | gzip) \ - > "$OUTPUT/$CROSS_BASE"root.cpio.gz +[ -z "$BUILTIN" ] && announce "${CROSS_BASE}root.cpio.gz" && + (cd "$ROOT" && find . | cpio -o -H newc --no-preserve-owner | gzip) \ + > "$OUTPUT/$CROSS_BASE"root.cpio.gz +rmdir "$MYBUILD" "$BUILD" 2>/dev/null # remove if empty |