aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/mkroot.sh92
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