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