1*cf5a6c84SAndroid Build Coastguard Worker#!/bin/bash 2*cf5a6c84SAndroid Build Coastguard Worker 3*cf5a6c84SAndroid Build Coastguard Worker# ------------------------------ Part 1: Setup ------------------------------- 4*cf5a6c84SAndroid Build Coastguard Worker 5*cf5a6c84SAndroid Build Coastguard Worker# Clear environment variables by restarting script w/bare minimum passed through 6*cf5a6c84SAndroid Build Coastguard Worker[ -z "$NOCLEAR" ] && exec env -i NOCLEAR=1 HOME="$HOME" PATH="$PATH" \ 7*cf5a6c84SAndroid Build Coastguard Worker LINUX="$LINUX" CROSS="$CROSS" CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@" 8*cf5a6c84SAndroid Build Coastguard Worker 9*cf5a6c84SAndroid Build Coastguard Worker! [ -d mkroot ] && echo "Run mkroot/mkroot.sh from toybox source dir." && exit 1 10*cf5a6c84SAndroid Build Coastguard Worker 11*cf5a6c84SAndroid Build Coastguard Worker# assign command line NAME=VALUE args to env vars, the rest are packages 12*cf5a6c84SAndroid Build Coastguard Workerfor i in "$@"; do 13*cf5a6c84SAndroid Build Coastguard Worker [ "${i/=/}" != "$i" ] && export "$i" || { [ "$i" != -- ] && PKG="$PKG $i"; } 14*cf5a6c84SAndroid Build Coastguard Workerdone 15*cf5a6c84SAndroid Build Coastguard Worker 16*cf5a6c84SAndroid Build Coastguard Worker# Set default directory locations (overrideable from command line) 17*cf5a6c84SAndroid Build Coastguard Worker: ${TOP:=$PWD/root} ${BUILD:=$TOP/build} ${LOG:=$BUILD/log} 18*cf5a6c84SAndroid Build Coastguard Worker: ${AIRLOCK:=$BUILD/airlock} ${CCC:=$PWD/ccc} ${PKGDIR:=$PWD/mkroot/packages} 19*cf5a6c84SAndroid Build Coastguard Worker 20*cf5a6c84SAndroid Build Coastguard Workerannounce() { printf "\033]2;$CROSS $*\007" 2>/dev/null >/dev/tty; printf "\n=== $*\n";} 21*cf5a6c84SAndroid Build Coastguard Workerdie() { echo "$@" >&2; exit 1; } 22*cf5a6c84SAndroid Build Coastguard Worker 23*cf5a6c84SAndroid Build Coastguard Worker# ----- Are we cross compiling (via CROSS_COMPILE= or CROSS=) 24*cf5a6c84SAndroid Build Coastguard Worker 25*cf5a6c84SAndroid Build Coastguard Workerif [ -n "$CROSS_COMPILE" ]; then 26*cf5a6c84SAndroid Build Coastguard Worker # airlock needs absolute path 27*cf5a6c84SAndroid Build Coastguard Worker [ -z "${X:=$(command -v "$CROSS_COMPILE"cc)}" ] && die "no ${CROSS_COMPILE}cc" 28*cf5a6c84SAndroid Build Coastguard Worker CROSS_COMPILE="$(realpath -s "${X%cc}")" 29*cf5a6c84SAndroid Build Coastguard Worker [ -z "$CROSS" ] && CROSS=${CROSS_COMPILE/*\//} CROSS=${CROSS/-*/} 30*cf5a6c84SAndroid Build Coastguard Worker 31*cf5a6c84SAndroid Build Coastguard Workerelif [ -n "$CROSS" ]; then # CROSS=all/allnonstop/$ARCH else list known $ARCHes 32*cf5a6c84SAndroid Build Coastguard Worker [ ! -d "$CCC" ] && die "No ccc symlink to compiler directory." 33*cf5a6c84SAndroid Build Coastguard Worker TARGETS="$(ls "$CCC" | sed -n 's/-.*//p' | sort -u)" 34*cf5a6c84SAndroid Build Coastguard Worker 35*cf5a6c84SAndroid Build Coastguard Worker if [ "${CROSS::3}" == all ]; then # loop calling ourselves for each target 36*cf5a6c84SAndroid Build Coastguard Worker for i in $TARGETS; do 37*cf5a6c84SAndroid Build Coastguard Worker "$0" "$@" CROSS=$i || [ "$CROSS" == allnonstop ] || exit 1 38*cf5a6c84SAndroid Build Coastguard Worker done; exit 39*cf5a6c84SAndroid Build Coastguard Worker 40*cf5a6c84SAndroid Build Coastguard Worker else # Find matching cross compiler under ccc/ else list available targets 41*cf5a6c84SAndroid Build Coastguard Worker CROSS_COMPILE="$(echo "$CCC/$CROSS"-*cross/bin/"$CROSS"*-cc)" # wildcard 42*cf5a6c84SAndroid Build Coastguard Worker [ ! -e "$CROSS_COMPILE" ] && echo $TARGETS && exit # list available targets 43*cf5a6c84SAndroid Build Coastguard Worker CROSS_COMPILE="${CROSS_COMPILE%cc}" # trim to prefix for cc/ld/as/nm/strip 44*cf5a6c84SAndroid Build Coastguard Worker fi 45*cf5a6c84SAndroid Build Coastguard Workerfi 46*cf5a6c84SAndroid Build Coastguard Worker 47*cf5a6c84SAndroid Build Coastguard Worker# Set per-target output directory (using "host" if not cross-compiling) 48*cf5a6c84SAndroid Build Coastguard Worker: ${CROSS:=host} ${OUTPUT:=$TOP/$CROSS} ${OUTDOC:=$OUTPUT/docs} 49*cf5a6c84SAndroid Build Coastguard Worker 50*cf5a6c84SAndroid Build Coastguard Worker# Verify selected compiler works 51*cf5a6c84SAndroid Build Coastguard Worker${CROSS_COMPILE}cc --static -xc - -o /dev/null <<< "int main(void){return 0;}"|| 52*cf5a6c84SAndroid Build Coastguard Worker die "${CROSS_COMPILE}cc can't create static binaries" 53*cf5a6c84SAndroid Build Coastguard Worker 54*cf5a6c84SAndroid Build Coastguard Worker# ----- Create hermetic build environment 55*cf5a6c84SAndroid Build Coastguard Worker 56*cf5a6c84SAndroid Build Coastguard Workerrm -rf generated 57*cf5a6c84SAndroid Build Coastguard Workerif [ -z "$NOAIRLOCK"] && [ -n "$CROSS_COMPILE" ]; then 58*cf5a6c84SAndroid Build Coastguard Worker # When cross compiling set host $PATH to binaries with known behavior by 59*cf5a6c84SAndroid Build Coastguard Worker # - building a host toybox later builds use as their command line 60*cf5a6c84SAndroid Build Coastguard Worker # - cherry-picking specific commands from old path via symlink 61*cf5a6c84SAndroid Build Coastguard Worker if [ ! -e "$AIRLOCK/toybox" ]; then 62*cf5a6c84SAndroid Build Coastguard Worker announce "airlock" && 63*cf5a6c84SAndroid Build Coastguard Worker PREFIX="$AIRLOCK" KCONFIG_CONFIG=.singleconfig_airlock CROSS_COMPILE= \ 64*cf5a6c84SAndroid Build Coastguard Worker make clean defconfig toybox install_airlock && # see scripts/install.sh 65*cf5a6c84SAndroid Build Coastguard Worker rm .singleconfig_airlock || exit 1 66*cf5a6c84SAndroid Build Coastguard Worker fi 67*cf5a6c84SAndroid Build Coastguard Worker export PATH="$AIRLOCK" 68*cf5a6c84SAndroid Build Coastguard Workerfi 69*cf5a6c84SAndroid Build Coastguard Worker 70*cf5a6c84SAndroid Build Coastguard Worker# Create per-target work directories 71*cf5a6c84SAndroid Build Coastguard WorkerTEMP="$BUILD/${CROSS}-tmp" && rm -rf "$TEMP" && 72*cf5a6c84SAndroid Build Coastguard Workermkdir -p "$TEMP" "$OUTPUT" "$LOG" || exit 1 73*cf5a6c84SAndroid Build Coastguard Worker[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT" 74*cf5a6c84SAndroid Build Coastguard WorkerLOG="$LOG/$CROSS" 75*cf5a6c84SAndroid Build Coastguard Worker 76*cf5a6c84SAndroid Build Coastguard Worker# ----- log build output 77*cf5a6c84SAndroid Build Coastguard Worker 78*cf5a6c84SAndroid Build Coastguard Worker# Install command line recording wrapper, logs all commands run from $PATH 79*cf5a6c84SAndroid Build Coastguard Workerif [ -z "$NOLOGPATH" ]; then 80*cf5a6c84SAndroid Build Coastguard Worker # Move cross compiler into $PATH so calls to it get logged 81*cf5a6c84SAndroid Build Coastguard Worker [ -n "$CROSS_COMPILE" ] && PATH="${CROSS_COMPILE%/*}:$PATH" && 82*cf5a6c84SAndroid Build Coastguard Worker CROSS_COMPILE=${CROSS_COMPILE##*/} 83*cf5a6c84SAndroid Build Coastguard Worker export WRAPDIR="$BUILD/record-commands" LOGPATH="$LOG"-commands.txt 84*cf5a6c84SAndroid Build Coastguard Worker rm -rf "$WRAPDIR" "$LOGPATH" generated/obj && 85*cf5a6c84SAndroid Build Coastguard Worker eval "$(WRAPDIR="$WRAPDIR" CROSS_COMPILE= NOSTRIP=1 mkroot/record-commands)"|| 86*cf5a6c84SAndroid Build Coastguard Worker exit 1 87*cf5a6c84SAndroid Build Coastguard Workerfi 88*cf5a6c84SAndroid Build Coastguard Worker 89*cf5a6c84SAndroid Build Coastguard Worker# Start logging stdout/stderr 90*cf5a6c84SAndroid Build Coastguard Workerrm -f "$LOG".{n,y} || exit 1 91*cf5a6c84SAndroid Build Coastguard Worker[ -z "$NOLOG" ] && exec > >(tee "$LOG".n) 2>&1 92*cf5a6c84SAndroid Build Coastguard Workerecho "Building for $CROSS" 93*cf5a6c84SAndroid Build Coastguard Worker 94*cf5a6c84SAndroid Build Coastguard Worker# ---------------------- Part 2: Create root filesystem ----------------------- 95*cf5a6c84SAndroid Build Coastguard Worker 96*cf5a6c84SAndroid Build Coastguard Worker# ----- Create new root filesystem's directory layout. 97*cf5a6c84SAndroid Build Coastguard Worker 98*cf5a6c84SAndroid Build Coastguard Worker# FHS wants boot media opt srv usr/{local,share}, stuff under /var... 99*cf5a6c84SAndroid Build Coastguard Workermkdir -p "$ROOT"/{dev,etc/rc,home,mnt,proc,root,sys,tmp/run,usr/{bin,sbin,lib},var} && 100*cf5a6c84SAndroid Build Coastguard Workerchmod a+rwxt "$ROOT"/tmp && ln -s usr/{bin,sbin,lib} tmp/run "$ROOT" || exit 1 101*cf5a6c84SAndroid Build Coastguard Worker 102*cf5a6c84SAndroid Build Coastguard Worker# Write init script. Runs as pid 1 from initramfs to set up and hand off system. 103*cf5a6c84SAndroid Build Coastguard Workercat > "$ROOT"/init << 'EOF' && 104*cf5a6c84SAndroid Build Coastguard Worker#!/bin/sh 105*cf5a6c84SAndroid Build Coastguard Worker 106*cf5a6c84SAndroid Build Coastguard Workerexport HOME=/home PATH=/bin:/sbin 107*cf5a6c84SAndroid Build Coastguard Worker 108*cf5a6c84SAndroid Build Coastguard Workerif ! mountpoint -q dev; then 109*cf5a6c84SAndroid Build Coastguard Worker mount -t devtmpfs dev dev 110*cf5a6c84SAndroid Build Coastguard Worker [ $$ -eq 1 ] && ! 2>/dev/null <0 && exec 0<>/dev/console 1>&0 2>&1 111*cf5a6c84SAndroid Build Coastguard Worker for i in ,fd /0,stdin /1,stdout /2,stderr 112*cf5a6c84SAndroid Build Coastguard Worker do ln -sf /proc/self/fd${i/,*/} dev/${i/*,/}; done 113*cf5a6c84SAndroid Build Coastguard Worker mkdir -p dev/shm 114*cf5a6c84SAndroid Build Coastguard Worker chmod +t /dev/shm 115*cf5a6c84SAndroid Build Coastguard Workerfi 116*cf5a6c84SAndroid Build Coastguard Workermountpoint -q dev/pts || { mkdir -p dev/pts && mount -t devpts dev/pts dev/pts;} 117*cf5a6c84SAndroid Build Coastguard Workermountpoint -q proc || mount -t proc proc proc 118*cf5a6c84SAndroid Build Coastguard Workermountpoint -q sys || mount -t sysfs sys sys 119*cf5a6c84SAndroid Build Coastguard Workerecho 0 99999 > /proc/sys/net/ipv4/ping_group_range 120*cf5a6c84SAndroid Build Coastguard Worker 121*cf5a6c84SAndroid Build Coastguard Workerif [ $$ -eq 1 ]; then 122*cf5a6c84SAndroid Build Coastguard Worker mountpoint -q mnt || [ -e /dev/?da ] && mount /dev/?da /mnt 123*cf5a6c84SAndroid Build Coastguard Worker 124*cf5a6c84SAndroid Build Coastguard Worker # Setup networking for QEMU (needs /proc) 125*cf5a6c84SAndroid Build Coastguard Worker ifconfig lo 127.0.0.1 126*cf5a6c84SAndroid Build Coastguard Worker ifconfig eth0 10.0.2.15 127*cf5a6c84SAndroid Build Coastguard Worker route add default gw 10.0.2.2 128*cf5a6c84SAndroid Build Coastguard Worker [ "$(date +%s)" -lt 1000 ] && timeout 2 sntp -sq 10.0.2.2 # Ask host 129*cf5a6c84SAndroid Build Coastguard Worker [ "$(date +%s)" -lt 10000000 ] && sntp -sq time.google.com 130*cf5a6c84SAndroid Build Coastguard Worker 131*cf5a6c84SAndroid Build Coastguard Worker # Run package scripts (if any) 132*cf5a6c84SAndroid Build Coastguard Worker for i in $(ls -1 /etc/rc 2>/dev/null | sort); do . /etc/rc/"$i"; done 133*cf5a6c84SAndroid Build Coastguard Worker echo 3 > /proc/sys/kernel/printk 134*cf5a6c84SAndroid Build Coastguard Worker 135*cf5a6c84SAndroid Build Coastguard Worker [ -z "$HANDOFF" ] && [ -e /mnt/init ] && HANDOFF=/mnt/init 136*cf5a6c84SAndroid Build Coastguard Worker [ -z "$HANDOFF" ] && HANDOFF=/bin/sh && echo -e '\e[?7hType exit when done.' 137*cf5a6c84SAndroid Build Coastguard Worker 138*cf5a6c84SAndroid Build Coastguard Worker setsid -c <>/dev/$(sed '$s@.*[ /]@@' /sys/class/tty/console/active) >&0 2>&1 \ 139*cf5a6c84SAndroid Build Coastguard Worker $HANDOFF 140*cf5a6c84SAndroid Build Coastguard Worker reboot -f & 141*cf5a6c84SAndroid Build Coastguard Worker sleep 5 142*cf5a6c84SAndroid Build Coastguard Workerelse # for chroot 143*cf5a6c84SAndroid Build Coastguard Worker /bin/sh 144*cf5a6c84SAndroid Build Coastguard Worker umount /dev/pts /dev /sys /proc 145*cf5a6c84SAndroid Build Coastguard Workerfi 146*cf5a6c84SAndroid Build Coastguard WorkerEOF 147*cf5a6c84SAndroid Build Coastguard Workerchmod +x "$ROOT"/init && 148*cf5a6c84SAndroid Build Coastguard Worker 149*cf5a6c84SAndroid Build Coastguard Worker# Google's nameserver, passwd+group with special (root/nobody) accounts + guest 150*cf5a6c84SAndroid Build Coastguard Workerecho "nameserver 8.8.8.8" > "$ROOT"/etc/resolv.conf && 151*cf5a6c84SAndroid Build Coastguard Workercat > "$ROOT"/etc/passwd << 'EOF' && 152*cf5a6c84SAndroid Build Coastguard Workerroot:x:0:0:root:/root:/bin/sh 153*cf5a6c84SAndroid Build Coastguard Workerguest:x:500:500:guest:/home/guest:/bin/sh 154*cf5a6c84SAndroid Build Coastguard Workernobody:x:65534:65534:nobody:/proc/self:/dev/null 155*cf5a6c84SAndroid Build Coastguard WorkerEOF 156*cf5a6c84SAndroid Build Coastguard Workerecho -e 'root:x:0:\nguest:x:500:\nnobody:x:65534:' > "$ROOT"/etc/group && 157*cf5a6c84SAndroid Build Coastguard Worker# Grab toybox version git or toys.h 158*cf5a6c84SAndroid Build Coastguard Worker: ${VERSION:=$(git describe --tags --abbrev=12 2>/dev/null)} && 159*cf5a6c84SAndroid Build Coastguard Worker: ${VERSION:=$(sed -n 's/.*TOYBOX_VERSION "\([^"]*\)".*/\1/p' toys.h)} && 160*cf5a6c84SAndroid Build Coastguard Worker# Optional file, basically a comment 161*cf5a6c84SAndroid Build Coastguard Workerecho $'NAME="mkroot"\nVERSION="'${VERSION#* }$'"\nHOME_URL="https://landley.net/toybox"' > "$ROOT"/etc/os-release || exit 1 162*cf5a6c84SAndroid Build Coastguard Worker 163*cf5a6c84SAndroid Build Coastguard Worker# Build any packages listed on command line 164*cf5a6c84SAndroid Build Coastguard Workerfor i in ${PKG:+plumbing $PKG}; do 165*cf5a6c84SAndroid Build Coastguard Worker pushd . 166*cf5a6c84SAndroid Build Coastguard Worker announce "$i"; PATH="$PKGDIR:$PATH" source $i || die $i 167*cf5a6c84SAndroid Build Coastguard Worker popd 168*cf5a6c84SAndroid Build Coastguard Workerdone 169*cf5a6c84SAndroid Build Coastguard Worker 170*cf5a6c84SAndroid Build Coastguard Worker# Build static toybox with existing .config if there is one, else defconfig+sh 171*cf5a6c84SAndroid Build Coastguard Workerif [ -z "$NOTOYBOX" ]; then 172*cf5a6c84SAndroid Build Coastguard Worker announce toybox 173*cf5a6c84SAndroid Build Coastguard Worker [ -n "$PENDING" ] && rm -f .config 174*cf5a6c84SAndroid Build Coastguard Worker grep -q CONFIG_SH=y .config 2>/dev/null && CONF=silentoldconfig || unset CONF 175*cf5a6c84SAndroid Build Coastguard Worker for i in $PENDING sh route; do XX="$XX"$'\n'CONFIG_${i^^?}=y; done 176*cf5a6c84SAndroid Build Coastguard Worker [ -e "$ROOT"/lib/libc.so ] || export LDFLAGS=--static 177*cf5a6c84SAndroid Build Coastguard Worker PREFIX="$ROOT" make clean \ 178*cf5a6c84SAndroid Build Coastguard Worker ${CONF:-defconfig KCONFIG_ALLCONFIG=<(echo "$XX")} toybox install || exit 1 179*cf5a6c84SAndroid Build Coastguard Worker unset LDFLAGS 180*cf5a6c84SAndroid Build Coastguard Workerfi 181*cf5a6c84SAndroid Build Coastguard Worker 182*cf5a6c84SAndroid Build Coastguard Worker# ------------------ Part 3: Build + package bootable system ------------------ 183*cf5a6c84SAndroid Build Coastguard Worker 184*cf5a6c84SAndroid Build Coastguard Worker# Convert comma separated values in $1 to CONFIG=$2 lines 185*cf5a6c84SAndroid Build Coastguard Workercsv2cfg() { sed -E '/^$/d;s/([^,]*)($|,)/CONFIG_\1\n/g' <<< "$1" | sed '/^$/!{/=/!s/.*/&='"$2/}";} 186*cf5a6c84SAndroid Build Coastguard Workerbe2csv() { eval "echo $*" | tr ' ' ,; } # brace expansion to csv 187*cf5a6c84SAndroid Build Coastguard Worker 188*cf5a6c84SAndroid Build Coastguard Worker# Set variables from $CROSS, die on unrecognized target: 189*cf5a6c84SAndroid Build Coastguard Worker# BUILTIN - if set, statically link initramfs into kernel image 190*cf5a6c84SAndroid Build Coastguard Worker# DTB - device tree binary file in build dir (qemu -dtb $DTB) 191*cf5a6c84SAndroid Build Coastguard Worker# KARCH - linux ARCH= build argument (selects arch/$ARCH directory in source) 192*cf5a6c84SAndroid Build Coastguard Worker# KARGS - linux kernel command line arguments (qemu -append "console=$KARGS") 193*cf5a6c84SAndroid Build Coastguard Worker# KCONF - kernel config options for target (expanded by csv2cfg above) 194*cf5a6c84SAndroid Build Coastguard Worker# VMLINUX - linux bootable kernel file in build dir (qemu -kernel $VMLINUX) 195*cf5a6c84SAndroid Build Coastguard Worker# QEMU - emulator name (qemu-system-$QEMU) and arguments 196*cf5a6c84SAndroid Build Coastguard Workerget_target_config() 197*cf5a6c84SAndroid Build Coastguard Worker{ 198*cf5a6c84SAndroid Build Coastguard Worker # Target-specific info in an (alphabetical order) if/else staircase 199*cf5a6c84SAndroid Build Coastguard Worker # Each target needs board config, serial console, RTC, ethernet, block device. 200*cf5a6c84SAndroid Build Coastguard Worker 201*cf5a6c84SAndroid Build Coastguard Worker KARGS=ttyS0 VMLINUX=vmlinux 202*cf5a6c84SAndroid Build Coastguard Worker if [ "$CROSS" == armv5l ] || [ "$CROSS" == armv4l ]; then 203*cf5a6c84SAndroid Build Coastguard Worker # This could use the same VIRT board as armv7, but let's demonstrate a 204*cf5a6c84SAndroid Build Coastguard Worker # different one requiring a separate device tree binary. 205*cf5a6c84SAndroid Build Coastguard Worker KARCH=arm KARGS=ttyAMA0 VMLINUX=zImage 206*cf5a6c84SAndroid Build Coastguard Worker QEMU="arm -M versatilepb -net nic,model=rtl8139 -net user" 207*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv CPU_ARM926T MMU VFP ARM_THUMB AEABI ARCH_VERSATILE ATAGS \ 208*cf5a6c84SAndroid Build Coastguard Worker DEPRECATED_PARAM_STRUCT BLK_DEV_SD NET_VENDOR_REALTEK 8139CP \ 209*cf5a6c84SAndroid Build Coastguard Worker ARM_ATAG_DTB_COMPAT{,_CMDLINE_EXTEND} PCI{,_VERSATILE} \ 210*cf5a6c84SAndroid Build Coastguard Worker SERIAL_AMBA_PL011{,_CONSOLE} RTC_{CLASS,DRV_PL031,HCTOSYS} \ 211*cf5a6c84SAndroid Build Coastguard Worker SCSI{,_LOWLEVEL,_SYM53C8XX_{2,MMIO,DMA_ADDRESSING_MODE=0}})" 212*cf5a6c84SAndroid Build Coastguard Worker DTB=versatile-pb.dtb 213*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == armv7l ] || [ "$CROSS" == aarch64 ]; then 214*cf5a6c84SAndroid Build Coastguard Worker if [ "$CROSS" == aarch64 ]; then 215*cf5a6c84SAndroid Build Coastguard Worker QEMU="aarch64 -M virt -cpu cortex-a57" KARCH=arm64 VMLINUX=Image 216*cf5a6c84SAndroid Build Coastguard Worker else 217*cf5a6c84SAndroid Build Coastguard Worker QEMU="arm -M virt" KARCH=arm VMLINUX=zImage 218*cf5a6c84SAndroid Build Coastguard Worker fi 219*cf5a6c84SAndroid Build Coastguard Worker KARGS=ttyAMA0 220*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv MMU SOC_DRA7XX VDSO CPU_IDLE KERNEL_MODE_NEON \ 221*cf5a6c84SAndroid Build Coastguard Worker ARCH_{MULTI_V7,VIRT,OMAP2PLUS_TYPICAL,ALPINE} ARM_{THUMB,CPUIDLE,LPAE} \ 222*cf5a6c84SAndroid Build Coastguard Worker ATA{,_SFF,_BMDMA,_PIIX,_GENERIC} VIRTIO_{MENU,NET,BLK,PCI,MMIO} \ 223*cf5a6c84SAndroid Build Coastguard Worker SERIAL_AMBA_PL011{,_CONSOLE} RTC_{CLASS,HCTOSYS,DRV_PL031} \ 224*cf5a6c84SAndroid Build Coastguard Worker PATA_{,OF_}PLATFORM PCI{,_HOST_GENERIC})" 225*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == hexagon ]; then 226*cf5a6c84SAndroid Build Coastguard Worker QEMU_M=comet KARCH="hexagon LLVM_IAS=1" KCONF=SPI,SPI_BITBANG,IOMMU_SUPPORT 227*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == i486 ] || [ "$CROSS" == i686 ] || 228*cf5a6c84SAndroid Build Coastguard Worker [ "$CROSS" == x86_64 ] || [ "$CROSS" == x32 ]; then 229*cf5a6c84SAndroid Build Coastguard Worker if [ "$CROSS" == i486 ]; then 230*cf5a6c84SAndroid Build Coastguard Worker QEMU="i386 -cpu 486 -global fw_cfg.dma_enabled=false" KCONF=M486 231*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == i686 ]; then 232*cf5a6c84SAndroid Build Coastguard Worker QEMU="i386 -cpu pentium3" KCONF=MPENTIUMII 233*cf5a6c84SAndroid Build Coastguard Worker else 234*cf5a6c84SAndroid Build Coastguard Worker QEMU=x86_64 KCONF=64BIT 235*cf5a6c84SAndroid Build Coastguard Worker [ "$CROSS" == x32 ] && KCONF=X86_X32 236*cf5a6c84SAndroid Build Coastguard Worker fi 237*cf5a6c84SAndroid Build Coastguard Worker KARCH=x86 VMLINUX=bzImage 238*cf5a6c84SAndroid Build Coastguard Worker KCONF+=,"$(be2csv UNWINDER_FRAME_POINTER PCI BLK_DEV_SD NET_VENDOR_INTEL \ 239*cf5a6c84SAndroid Build Coastguard Worker E1000 RTC_CLASS ATA{,_SFF,_BMDMA,_PIIX} SERIAL_8250{,_CONSOLE})" 240*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == m68k ]; then 241*cf5a6c84SAndroid Build Coastguard Worker QEMU_M=q800 KARCH=m68k 242*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv MMU M68040 M68KFPU_EMU MAC BLK_DEV_SD MACINTOSH_DRIVERS \ 243*cf5a6c84SAndroid Build Coastguard Worker NET_VENDOR_NATSEMI MACSONIC SCSI{,_LOWLEVEL,_MAC_ESP} \ 244*cf5a6c84SAndroid Build Coastguard Worker SERIAL_PMACZILOG{,_TTYS,_CONSOLE})" 245*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == microblaze ]; then 246*cf5a6c84SAndroid Build Coastguard Worker QEMU_M=petalogix-s3adsp1800 KARCH=microblaze KARGS=ttyUL0 247*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv MMU CPU_BIG_ENDIAN SERIAL_UARTLITE{,_CONSOLE} \ 248*cf5a6c84SAndroid Build Coastguard Worker XILINX_{EMACLITE,MICROBLAZE0_{FAMILY="spartan3adsp",USE_{{MSR,PCMP}_INSTR,BARREL,HW_MUL}=1}})" 249*cf5a6c84SAndroid Build Coastguard Worker elif [ "${CROSS#mips}" != "$CROSS" ]; then # mips mipsel mips64 mips64el 250*cf5a6c84SAndroid Build Coastguard Worker QEMU_M=malta KARCH=mips 251*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv MIPS_MALTA CPU_MIPS32_R2 BLK_DEV_SD NET_VENDOR_AMD PCNET32 \ 252*cf5a6c84SAndroid Build Coastguard Worker PCI SERIAL_8250{,_CONSOLE} ATA{,_SFF,_BMDMA,_PIIX} POWER_RESET{,_SYSCON})" 253*cf5a6c84SAndroid Build Coastguard Worker [ "${CROSS/64/}" == "$CROSS" ] && KCONF+=,CPU_MIPS32_R2 || 254*cf5a6c84SAndroid Build Coastguard Worker KCONF+=,64BIT,CPU_MIPS64_R1,MIPS32_O32 255*cf5a6c84SAndroid Build Coastguard Worker [ "${CROSS%el}" != "$CROSS" ] && KCONF+=,CPU_LITTLE_ENDIAN 256*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == or1k ]; then 257*cf5a6c84SAndroid Build Coastguard Worker KARCH=openrisc QEMU_M=or1k-sim KARGS=ttyS0 258*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv ETHOC SERIO SERIAL_OF_PLATFORM SERIAL_8250{,_CONSOLE})" 259*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == powerpc ]; then 260*cf5a6c84SAndroid Build Coastguard Worker KARCH=powerpc QEMU="ppc -M g3beige" 261*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv ALTIVEC PATA_MACIO BLK_DEV_SD MACINTOSH_DRIVERS SERIO \ 262*cf5a6c84SAndroid Build Coastguard Worker NET_VENDOR_{8390,NATSEMI} NE2K_PCI SERIAL_PMACZILOG{,_TTYS,_CONSOLE} \ 263*cf5a6c84SAndroid Build Coastguard Worker ATA{,_SFF,_BMDMA} ADB{,_CUDA} BOOTX_TEXT PPC_{PMAC,OF_BOOT_TRAMPOLINE})" 264*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == powerpc64 ] || [ "$CROSS" == powerpc64le ]; then 265*cf5a6c84SAndroid Build Coastguard Worker KARCH=powerpc QEMU="ppc64 -M pseries -vga none" KARGS=hvc0 266*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv PPC64 BLK_DEV_SD ATA NET_VENDOR_IBM IBMVETH HVC_CONSOLE \ 267*cf5a6c84SAndroid Build Coastguard Worker PPC_{PSERIES,OF_BOOT_TRAMPOLINE,TRANSACTIONAL_MEM,DISABLE_WERROR} \ 268*cf5a6c84SAndroid Build Coastguard Worker SCSI_{LOWLEVEL,IBMVSCSI})" 269*cf5a6c84SAndroid Build Coastguard Worker [ "$CROSS" == powerpc64le ] && KCONF=$KCONF,CPU_LITTLE_ENDIAN 270*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" = riscv32 ] || [ "$CROSS" = riscv64 ]; then 271*cf5a6c84SAndroid Build Coastguard Worker # Note: -hda file.img doesn't work, but this insane overcomplicated pile: 272*cf5a6c84SAndroid Build Coastguard Worker # -drive file=file.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 273*cf5a6c84SAndroid Build Coastguard Worker QEMU_M="virt -netdev user,id=net0 -device virtio-net-device,netdev=net0" 274*cf5a6c84SAndroid Build Coastguard Worker KARCH=riscv VMLINUX=Image 275*cf5a6c84SAndroid Build Coastguard Worker # Probably only about half of these kernel symbols are actually needed? 276*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv MMU SOC_VIRT NONPORTABLE CMODEL_MEDANY \ 277*cf5a6c84SAndroid Build Coastguard Worker RISCV_ISA_{ZICBO{M,Z},FALLBACK} FPU PCI{,_HOST_GENERIC} BLK_DEV_SD \ 278*cf5a6c84SAndroid Build Coastguard Worker SCSI_{PROC_FS,LOWLEVEL,VIRTIO} VIRTIO_{MENU,NET,BLK,PCI} SERIO_SERPORT \ 279*cf5a6c84SAndroid Build Coastguard Worker SERIAL_{EARLYCON,8250{,_CONSOLE,_PCI},OF_PLATFORM} HW_RANDOM{,_VIRTIO} \ 280*cf5a6c84SAndroid Build Coastguard Worker RTC_{CLASS,HCTOSYS} DMADEVICES VIRTIO_{MENU,PCI{,_LEGACY},INPUT,MMIO})" 281*cf5a6c84SAndroid Build Coastguard Worker [ "$CROSS" = riscv32 ] && KCONF+=,ARCH_RV32I 282*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" = s390x ]; then 283*cf5a6c84SAndroid Build Coastguard Worker KARCH=s390 VMLINUX=bzImage 284*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv MARCH_Z900 PACK_STACK S390_GUEST VIRTIO_{NET,BLK} \ 285*cf5a6c84SAndroid Build Coastguard Worker SCLP_VT220_{TTY,CONSOLE})" 286*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == sh2eb ]; then 287*cf5a6c84SAndroid Build Coastguard Worker BUILTIN=1 KARCH=sh 288*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv CPU_{SUBTYPE_J2,BIG_ENDIAN} SH_JCORE_SOC SMP JCORE_EMAC \ 289*cf5a6c84SAndroid Build Coastguard Worker FLATMEM_MANUAL MEMORY_START=0x10000000 CMDLINE_OVERWRITE DNOTIFY FUSE_FS \ 290*cf5a6c84SAndroid Build Coastguard Worker INOTIFY_USER SPI{,_JCORE} SERIAL_UARTLITE{,_CONSOLE} PWRSEQ_SIMPLE \ 291*cf5a6c84SAndroid Build Coastguard Worker MMC{,_BLOCK,_SPI} UIO{,_PDRV_GENIRQ} MTD{,_SPI_NOR,_SST25L,_OF_PARTS} \ 292*cf5a6c84SAndroid Build Coastguard Worker BINFMT_{ELF_FDPIC,MISC} I2C{,_HELPER_AUTO})" 293*cf5a6c84SAndroid Build Coastguard Worker KCONF+=,CMDLINE=\"console=ttyUL0\ earlycon\" 294*cf5a6c84SAndroid Build Coastguard Worker elif [ "$CROSS" == sh4 ] || [ "$CROSS" == sh4eb ]; then 295*cf5a6c84SAndroid Build Coastguard Worker QEMU_M="r2d -serial null -serial mon:stdio" KARCH=sh 296*cf5a6c84SAndroid Build Coastguard Worker KARGS="ttySC1 noiotrap" VMLINUX=zImage 297*cf5a6c84SAndroid Build Coastguard Worker KCONF="$(be2csv CPU_SUBTYPE_SH7751R MMU VSYSCALL SH_{FPU,RTS7751R2D} PCI \ 298*cf5a6c84SAndroid Build Coastguard Worker RTS7751R2D_PLUS SERIAL_SH_SCI{,_CONSOLE} NET_VENDOR_REALTEK 8139CP \ 299*cf5a6c84SAndroid Build Coastguard Worker BLK_DEV_SD ATA{,_SFF,_BMDMA} PATA_PLATFORM BINFMT_ELF_FDPIC \ 300*cf5a6c84SAndroid Build Coastguard Worker CMDLINE_EXTEND MEMORY_START=0x0c000000)" 301*cf5a6c84SAndroid Build Coastguard Worker#see also SPI{,_SH_SCI} MFD_SM501 RTC_{CLASS,DRV_{R9701,SH},HCTOSYS} 302*cf5a6c84SAndroid Build Coastguard Worker [ "$CROSS" == sh4eb ] && KCONF+=,CPU_BIG_ENDIAN 303*cf5a6c84SAndroid Build Coastguard Worker else die "Unknown \$CROSS=$CROSS" 304*cf5a6c84SAndroid Build Coastguard Worker fi 305*cf5a6c84SAndroid Build Coastguard Worker : ${QEMU:=$CROSS ${QEMU_M:+-M $QEMU_M}} 306*cf5a6c84SAndroid Build Coastguard Worker} 307*cf5a6c84SAndroid Build Coastguard Worker 308*cf5a6c84SAndroid Build Coastguard Worker# Linux kernel .config symbols common to all architectures 309*cf5a6c84SAndroid Build Coastguard Worker: ${GENERIC_KCONF:=$(be2csv PANIC_TIMEOUT=1 NO_HZ HIGH_RES_TIMERS RD_GZIP \ 310*cf5a6c84SAndroid Build Coastguard Worker BINFMT_{ELF,SCRIPT} BLK_DEV{,_INITRD,_LOOP} EXT4_{FS,USE_FOR_EXT2} \ 311*cf5a6c84SAndroid Build Coastguard Worker VFAT_FS FAT_DEFAULT_UTF8 MISC_FILESYSTEMS NLS_{CODEPAGE_437,ISO8859_1} \ 312*cf5a6c84SAndroid Build Coastguard Worker SQUASHFS{,_XATTR,_ZLIB} TMPFS{,_POSIX_ACL} DEVTMPFS{,_MOUNT} \ 313*cf5a6c84SAndroid Build Coastguard Worker NET{,DEVICES,_CORE,CONSOLE} PACKET UNIX INET IPV6 ETHERNET \ 314*cf5a6c84SAndroid Build Coastguard Worker COMPAT_32BIT_TIME EARLY_PRINTK IKCONFIG{,_PROC})} 315*cf5a6c84SAndroid Build Coastguard Worker 316*cf5a6c84SAndroid Build Coastguard Worker# ----- Build kernel for target 317*cf5a6c84SAndroid Build Coastguard Worker 318*cf5a6c84SAndroid Build Coastguard WorkerINITRAMFS=initramfs.cpio.gz 319*cf5a6c84SAndroid Build Coastguard Workerif [ -z "$LINUX" ] || [ ! -d "$LINUX/kernel" ]; then 320*cf5a6c84SAndroid Build Coastguard Worker echo 'No $LINUX directory, kernel build skipped.' 321*cf5a6c84SAndroid Build Coastguard Workerelse 322*cf5a6c84SAndroid Build Coastguard Worker # Which architecture are we building a kernel for? 323*cf5a6c84SAndroid Build Coastguard Worker LINUX="$(realpath "$LINUX")" 324*cf5a6c84SAndroid Build Coastguard Worker [ "$CROSS" == host ] && CROSS="$(uname -m)" 325*cf5a6c84SAndroid Build Coastguard Worker get_target_config 326*cf5a6c84SAndroid Build Coastguard Worker 327*cf5a6c84SAndroid Build Coastguard Worker # Write the qemu launch script 328*cf5a6c84SAndroid Build Coastguard Worker if [ -n "$QEMU" ]; then 329*cf5a6c84SAndroid Build Coastguard Worker [ -z "$BUILTIN" ] && INITRD='-initrd "$DIR"/'"$INITRAMFS" 330*cf5a6c84SAndroid Build Coastguard Worker { echo DIR='"$(dirname $0)";' qemu-system-"$QEMU" -m 256 '"$@"' $QEMU_MORE \ 331*cf5a6c84SAndroid Build Coastguard Worker -nographic -no-reboot -kernel '"$DIR"'/linux-kernel $INITRD \ 332*cf5a6c84SAndroid Build Coastguard Worker ${DTB:+-dtb '"$DIR"'/linux.dtb} \ 333*cf5a6c84SAndroid Build Coastguard Worker "-append \"HOST=$CROSS console=$KARGS \$KARGS\"" && 334*cf5a6c84SAndroid Build Coastguard Worker echo "echo -e '\\e[?7h'" 335*cf5a6c84SAndroid Build Coastguard Worker } > "$OUTPUT"/run-qemu.sh && 336*cf5a6c84SAndroid Build Coastguard Worker chmod +x "$OUTPUT"/run-qemu.sh || exit 1 337*cf5a6c84SAndroid Build Coastguard Worker fi 338*cf5a6c84SAndroid Build Coastguard Worker 339*cf5a6c84SAndroid Build Coastguard Worker announce "linux-$KARCH" 340*cf5a6c84SAndroid Build Coastguard Worker pushd "$LINUX" && make distclean && popd && 341*cf5a6c84SAndroid Build Coastguard Worker cp -sfR "$LINUX" "$TEMP/linux" && pushd "$TEMP/linux" && 342*cf5a6c84SAndroid Build Coastguard Worker 343*cf5a6c84SAndroid Build Coastguard Worker # Write microconfig (minimal symbol name/value list in CSV format) 344*cf5a6c84SAndroid Build Coastguard Worker mkdir -p "$OUTDOC" && 345*cf5a6c84SAndroid Build Coastguard Worker for i in "$GENERIC_KCONF" "$KCONF" ${MODULES+MODULES,MODULE_UNLOAD} "$KEXTRA" 346*cf5a6c84SAndroid Build Coastguard Worker do echo "$i"; done > "$OUTDOC"/linux-microconfig && 347*cf5a6c84SAndroid Build Coastguard Worker 348*cf5a6c84SAndroid Build Coastguard Worker # expand to miniconfig (symbol list to switch on after running "allnoconfig") 349*cf5a6c84SAndroid Build Coastguard Worker { 350*cf5a6c84SAndroid Build Coastguard Worker echo "# make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG=linux-miniconfig" 351*cf5a6c84SAndroid Build Coastguard Worker echo "# make ARCH=$KARCH -j \$(nproc)" 352*cf5a6c84SAndroid Build Coastguard Worker echo "# boot $VMLINUX${DTB:+ dtb $DTB} console=$KARGS" 353*cf5a6c84SAndroid Build Coastguard Worker echo 354*cf5a6c84SAndroid Build Coastguard Worker while read i; do 355*cf5a6c84SAndroid Build Coastguard Worker echo "# architecture ${X:-independent}" 356*cf5a6c84SAndroid Build Coastguard Worker csv2cfg "$i" y 357*cf5a6c84SAndroid Build Coastguard Worker X=${X:+extra} X=${X:-specific} 358*cf5a6c84SAndroid Build Coastguard Worker done < "$OUTDOC"/linux-microconfig 359*cf5a6c84SAndroid Build Coastguard Worker [ -n "$BUILTIN" ] && echo -e CONFIG_INITRAMFS_SOURCE="\"$OUTPUT/fs\"" 360*cf5a6c84SAndroid Build Coastguard Worker for i in $MODULES; do csv2cfg "$i" m; done 361*cf5a6c84SAndroid Build Coastguard Worker } > "$OUTDOC/linux-miniconfig" && 362*cf5a6c84SAndroid Build Coastguard Worker 363*cf5a6c84SAndroid Build Coastguard Worker # Expand miniconfig to full .config 364*cf5a6c84SAndroid Build Coastguard Worker make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG="$OUTDOC/linux-miniconfig" && 365*cf5a6c84SAndroid Build Coastguard Worker cp .config "$OUTDOC/linux-fullconfig" && 366*cf5a6c84SAndroid Build Coastguard Worker 367*cf5a6c84SAndroid Build Coastguard Worker # Build kernel. Copy config, device tree binary, and kernel binary to output 368*cf5a6c84SAndroid Build Coastguard Worker make ARCH=$KARCH CROSS_COMPILE="$CROSS_COMPILE" -j $(nproc) all || exit 1 369*cf5a6c84SAndroid Build Coastguard Worker [ -n "$DTB" ] && { cp "$(find -name $DTB)" "$OUTPUT/linux.dtb" || exit 1 ;} 370*cf5a6c84SAndroid Build Coastguard Worker if [ -n "$MODULES" ]; then 371*cf5a6c84SAndroid Build Coastguard Worker make ARCH=$KARCH INSTALL_MOD_PATH=modz modules_install && 372*cf5a6c84SAndroid Build Coastguard Worker (cd modz && find lib/modules | cpio -o -H newc -R +0:+0 ) | gzip \ 373*cf5a6c84SAndroid Build Coastguard Worker > "$OUTDOC/modules.cpio.gz" || exit 1 374*cf5a6c84SAndroid Build Coastguard Worker fi 375*cf5a6c84SAndroid Build Coastguard Worker [ ! -e "$VMLINUX" ] && VMLINUX=arch/$KARCH/boot/$VMLINUX 376*cf5a6c84SAndroid Build Coastguard Worker cp "$VMLINUX" "$OUTPUT"/linux-kernel && cd .. && rm -rf linux && popd ||exit 1 377*cf5a6c84SAndroid Build Coastguard Workerfi 378*cf5a6c84SAndroid Build Coastguard Worker 379*cf5a6c84SAndroid Build Coastguard Worker# clean up and package root filesystem for initramfs. 380*cf5a6c84SAndroid Build Coastguard Workerannounce initramfs 381*cf5a6c84SAndroid Build Coastguard Worker[ -z "$BUILTIN" ] && DIR="$OUTPUT" || DIR="$OUTDOC" 382*cf5a6c84SAndroid Build Coastguard Worker{ (cd "$ROOT" && find . -printf '%P\n' | cpio -o -H newc -R +0:+0 ) || exit 1 383*cf5a6c84SAndroid Build Coastguard Worker ! test -e "$OUTDOC/modules.cpio.gz" || zcat $_;} | gzip \ 384*cf5a6c84SAndroid Build Coastguard Worker > "$DIR/$INITRAMFS" || exit 1 385*cf5a6c84SAndroid Build Coastguard Worker 386*cf5a6c84SAndroid Build Coastguard Workermv "$LOG".{n,y} && echo "Output is in $OUTPUT" 387*cf5a6c84SAndroid Build Coastguard Workerrmdir "$TEMP" 2>/dev/null || exit 0 # remove if empty, not an error 388