From b63e5766770f1af702890c640179bcb51f73c2e1 Mon Sep 17 00:00:00 2001 From: Marcelo Alencar Date: Wed, 31 Mar 2021 18:44:04 -0300 Subject: [PATCH] usr.sbin/installboot: Synchronize on NetBSD-current (30/03/2021 16:09 UTC) --- distrib/sets/lists/base/mi | 5 + distrib/sets/lists/minix-base/mi | 7 +- distrib/sets/lists/minix-debug/mi | 2 +- distrib/sets/lists/minix-man/mi | 2 +- etc/mtree/NetBSD.dist.base | 3 + minix/commands/setup/setup.sh | 4 +- minix/commands/updateboot/updateboot.sh | 2 +- releasetools/release.functions | 4 +- releasetools/release.sh | 2 +- share/Makefile | 16 +- share/installboot/Makefile | 9 + share/installboot/evbarm/Makefile | 12 + share/installboot/evbarm/boards.plist | 507 +++++ share/installboot/evbmips/Makefile | 12 + share/installboot/evbmips/boards.plist | 43 + tools/installboot/Makefile | 31 +- usr.sbin/installboot/Makefile | 58 +- usr.sbin/installboot/arch/alpha.c | 15 +- usr.sbin/installboot/arch/amiga.c | 14 +- usr.sbin/installboot/arch/emips.c | 15 +- usr.sbin/installboot/arch/evbarm.c | 119 + usr.sbin/installboot/arch/evbmips.c | 119 + usr.sbin/installboot/arch/ews4800mips.c | 10 +- usr.sbin/installboot/arch/hp300.c | 13 +- usr.sbin/installboot/arch/hppa.c | 12 +- usr.sbin/installboot/arch/i386.c | 57 +- usr.sbin/installboot/arch/landisk.c | 30 +- usr.sbin/installboot/arch/macppc.c | 14 +- usr.sbin/installboot/arch/news.c | 24 +- usr.sbin/installboot/arch/next68k.c | 12 +- usr.sbin/installboot/arch/pmax.c | 14 +- usr.sbin/installboot/arch/sparc.c | 14 +- usr.sbin/installboot/arch/sparc64.c | 12 +- usr.sbin/installboot/arch/sun68k.c | 24 +- usr.sbin/installboot/arch/vax.c | 14 +- usr.sbin/installboot/arch/x68k.c | 14 +- usr.sbin/installboot/evboards.c | 1974 +++++++++++++++++ usr.sbin/installboot/evboards.h | 69 + .../{installboot_nbsd.8 => installboot.8} | 467 +++- usr.sbin/installboot/installboot.c | 56 +- usr.sbin/installboot/installboot.h | 34 +- usr.sbin/installboot/machines.c | 74 +- 42 files changed, 3639 insertions(+), 300 deletions(-) create mode 100644 share/installboot/Makefile create mode 100644 share/installboot/evbarm/Makefile create mode 100644 share/installboot/evbarm/boards.plist create mode 100644 share/installboot/evbmips/Makefile create mode 100644 share/installboot/evbmips/boards.plist create mode 100644 usr.sbin/installboot/arch/evbarm.c create mode 100644 usr.sbin/installboot/arch/evbmips.c create mode 100644 usr.sbin/installboot/evboards.c create mode 100644 usr.sbin/installboot/evboards.h rename usr.sbin/installboot/{installboot_nbsd.8 => installboot.8} (65%) diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi index 973d93021..707c80f05 100644 --- a/distrib/sets/lists/base/mi +++ b/distrib/sets/lists/base/mi @@ -2956,6 +2956,11 @@ ./usr/share/i18n/iconv base-sysutil-share ./usr/share/i18n/iconv/iconv.dir base-sysutil-share nls ./usr/share/info base-texinfo-share +./usr/share/installboot base-sysutil-share +./usr/share/installboot/evbarm base-sysutil-share +./usr/share/installboot/evbarm/boards.plist base-sysutil-share +./usr/share/installboot/evbmips base-sysutil-share +./usr/share/installboot/evbmips/boards.plist base-sysutil-share ./usr/share/keymaps base-sys-share ./usr/share/keymaps/amiga base-sys-share ./usr/share/keymaps/atari base-sys-share diff --git a/distrib/sets/lists/minix-base/mi b/distrib/sets/lists/minix-base/mi index e850720e1..b7ccef7d9 100644 --- a/distrib/sets/lists/minix-base/mi +++ b/distrib/sets/lists/minix-base/mi @@ -1115,7 +1115,7 @@ ./usr/sbin/groupmod minix-base ./usr/sbin/i2cscan minix-base ./usr/sbin/inetd minix-base -./usr/sbin/installboot_nbsd minix-base +./usr/sbin/installboot minix-base ./usr/sbin/kernel minix-base ./usr/sbin/link minix-base ./usr/sbin/lwresd minix-base @@ -2011,6 +2011,11 @@ ./usr/share/info/ld.info minix-base binutils ./usr/share/info/texinfo.info minix-base ./usr/share/info/vi.info minix-base +./usr/share/installboot minix-base +./usr/share/installboot/evbarm minix-base +./usr/share/installboot/evbarm/boards.plist minix-base +./usr/share/installboot/evbmips minix-base +./usr/share/installboot/evbmips/boards.plist minix-base ./usr/share/keymaps minix-base ./usr/share/legal minix-base ./usr/share/legal/COPYRIGHT minix-base diff --git a/distrib/sets/lists/minix-debug/mi b/distrib/sets/lists/minix-debug/mi index fbf022a39..c0c17b287 100644 --- a/distrib/sets/lists/minix-debug/mi +++ b/distrib/sets/lists/minix-debug/mi @@ -637,7 +637,7 @@ ./usr/libdata/debug/usr/sbin/fbdctl.debug minix-debug debug ./usr/libdata/debug/usr/sbin/i2cscan.debug minix-debug debug ./usr/libdata/debug/usr/sbin/inetd.debug minix-debug debug -./usr/libdata/debug/usr/sbin/installboot_nbsd.debug minix-debug debug +./usr/libdata/debug/usr/sbin/installboot.debug minix-debug debug ./usr/libdata/debug/usr/sbin/kernel.debug minix-debug debug ./usr/libdata/debug/usr/sbin/link.debug minix-debug debug ./usr/libdata/debug/usr/sbin/makefs.debug minix-debug debug diff --git a/distrib/sets/lists/minix-man/mi b/distrib/sets/lists/minix-man/mi index 58ac5bd6e..e0dbc82f0 100644 --- a/distrib/sets/lists/minix-man/mi +++ b/distrib/sets/lists/minix-man/mi @@ -3514,7 +3514,7 @@ ./usr/man/man8/inet.8 minix-man obsolete ./usr/man/man8/inetd.8 minix-man ./usr/man/man8/init.8 minix-man -./usr/man/man8/installboot_nbsd.8 minix-man +./usr/man/man8/installboot.8 minix-man ./usr/man/man8/intr.8 minix-man ./usr/man/man8/irdpd.8 minix-man obsolete ./usr/man/man8/link.8 minix-man diff --git a/etc/mtree/NetBSD.dist.base b/etc/mtree/NetBSD.dist.base index 1d45091eb..a4d7615ff 100644 --- a/etc/mtree/NetBSD.dist.base +++ b/etc/mtree/NetBSD.dist.base @@ -250,6 +250,9 @@ ./usr/share/i18n/esdb/UTF ./usr/share/i18n/iconv ./usr/share/info +./usr/share/installboot +./usr/share/installboot/evbarm +./usr/share/installboot/evbmips ./usr/share/keymaps ./usr/share/kyua-atf-compat ./usr/share/kyua-cli diff --git a/minix/commands/setup/setup.sh b/minix/commands/setup/setup.sh index 2a7e76fe1..c21514a47 100644 --- a/minix/commands/setup/setup.sh +++ b/minix/commands/setup/setup.sh @@ -73,7 +73,7 @@ check_mbr() read ok if [ "$ok" = Y -o "$ok" = y -o "$ok" = "" ] then - installboot_nbsd -m "$disk" /usr/mdec/mbr >/dev/null + installboot -m "$disk" /usr/mdec/mbr >/dev/null fi fi rm temp_mbr_netbsd @@ -547,7 +547,7 @@ test -n "$keymap" && cp -p "/usr/lib/keymaps/$keymap.map" /mnt/etc/keymap # XXX we have to use "-f" here, because installboot worries about BPB, which # we don't have... -installboot_nbsd -f /dev/$primary /usr/mdec/bootxx_minixfs3 >/dev/null || exit +installboot -f /dev/$primary /usr/mdec/bootxx_minixfs3 >/dev/null || exit # give the install the boot loader cp /usr/mdec/boot_monitor /mnt/ minixdir=/mnt/boot/minix_default diff --git a/minix/commands/updateboot/updateboot.sh b/minix/commands/updateboot/updateboot.sh index 18a7a54f7..07ef71621 100755 --- a/minix/commands/updateboot/updateboot.sh +++ b/minix/commands/updateboot/updateboot.sh @@ -35,6 +35,6 @@ then fi echo "Installing bootxx_minixfs3 into $disk." -installboot_nbsd "$disk" "$MDEC/bootxx_minixfs3" +installboot "$disk" "$MDEC/bootxx_minixfs3" sync diff --git a/releasetools/release.functions b/releasetools/release.functions index 4fa6d39dd..0084a0070 100644 --- a/releasetools/release.functions +++ b/releasetools/release.functions @@ -12,7 +12,7 @@ make_hdimage() # installboot -m needs at least 1KB dd < /dev/zero >tmpimage count=2 partition -fm tmpimage 2 81:$rootsects* 0:0 81:$usrsects - installboot_nbsd -m tmpimage /usr/mdec/mbr + installboot -m tmpimage /usr/mdec/mbr dd < tmpimage > subpart count=1 primsects=`expr 1 + $rootsects + $usrsects` @@ -26,7 +26,7 @@ make_hdimage() dd < /dev/zero count=$padsects } > hdimage partition -m hdimage 81:`expr $primsects + $padsects`* - installboot_nbsd -m hdimage /usr/mdec/mbr + installboot -m hdimage /usr/mdec/mbr } retrieve() diff --git a/releasetools/release.sh b/releasetools/release.sh index 9b3e4b59d..b702b130e 100755 --- a/releasetools/release.sh +++ b/releasetools/release.sh @@ -336,7 +336,7 @@ isosects=`expr $isosects + $isopad` dd if=$TMPDISKUSR bs=$BS count=$USRBLOCKS ) >m mv m $IMG # Make CD partition table -installboot_nbsd -m $IMG /usr/mdec/mbr +installboot -m $IMG /usr/mdec/mbr # Make sure there is no hole..! Otherwise the ISO format is # unreadable. partition -m $IMG 0 81:$isosects 81:$ROOTSECTS 81:$USRSECTS diff --git a/share/Makefile b/share/Makefile index ebcab691f..302acc2f3 100644 --- a/share/Makefile +++ b/share/Makefile @@ -1,21 +1,29 @@ -# $NetBSD: Makefile,v 1.33 2014/08/08 09:34:10 apb Exp $ +# $NetBSD: Makefile,v 1.36 2019/05/07 05:02:42 thorpej Exp $ # from @(#)Makefile 8.1 (Berkeley) 6/5/93 # Missing: ms .include -#__MINIX: dict doc examples me \ +#__MINIX: dict examples me \ # tabset tmac wscons xml - .if ${MKSHARE} != "no" || \ make(clean) || make(cleandir) || make(distclean) || make(obj) -SUBDIR= legal man misc mk \ +SUBDIR= installboot legal man misc mk \ terminfo + +#__MINIX: +#.if ${MKGROFF} != "no" +#SUBDIR+=doc +#.endif + .if ${MKNLS} != "no" SUBDIR+=i18n locale nls .endif .endif +#__MINIX: +#SUBDIR.roff+= doc + # Speedup stubs for some subtrees that don't need to run these rules includes-examples includes-man: @true diff --git a/share/installboot/Makefile b/share/installboot/Makefile new file mode 100644 index 000000000..c63c13e61 --- /dev/null +++ b/share/installboot/Makefile @@ -0,0 +1,9 @@ +# $NetBSD: Makefile,v 1.2 2020/06/21 17:15:51 thorpej Exp $ + +.include + +.if ${MKSHARE} != "no" +SUBDIR= evbarm evbmips +.endif + +.include diff --git a/share/installboot/evbarm/Makefile b/share/installboot/evbarm/Makefile new file mode 100644 index 000000000..efb8b8571 --- /dev/null +++ b/share/installboot/evbarm/Makefile @@ -0,0 +1,12 @@ +# $NetBSD: Makefile,v 1.1 2019/05/07 05:02:42 thorpej Exp $ + +NOOBJ= # defined + +.include + +.if ${MKSHARE} != "no" +FILES= boards.plist +FILESDIR= /usr/share/installboot/evbarm +.endif + +.include diff --git a/share/installboot/evbarm/boards.plist b/share/installboot/evbarm/boards.plist new file mode 100644 index 000000000..984eb689c --- /dev/null +++ b/share/installboot/evbarm/boards.plist @@ -0,0 +1,507 @@ + + + + + + terasic,de0-atlas + + description + Terasic DE-0(Atlas) + u-boot-pkg + de0-nanosoc + + + + hardkernel,odroid-c2 + + description + Hardkernel ODROID-C2 + u-boot-pkg + odroid-c2 + + libretech,cc + + description + Libre Computer Board AML-S905X-CC + u-boot-pkg + libretech-cc + + + + hardkernel,odroid-xu3 + + description + Hardkernel Odroid XU3 + u-boot-pkg + odroid-xu3 + + + + pine64,rock64 + + description + Pine64 Rock64 + u-boot-pkg + rock64 + + pine64,rockpro64 + + description + Pine64 RockPro64 + u-boot-pkg + rockpro64 + + pine64,pinebook-pro + + description + Pine64 Pinebook Pro + u-boot-pkg + pinebook-pro + + asus,rk3288-tinker + + description + Rockchip RK3288 Asus Tinker Board + u-boot-pkg + tinker + + + + bananapi,bpi-r2 + + description + Bananapi BPI-R2 + u-boot-pkg + bananapi-r2 + + + + nvidia,jetson-tk1 + + description + NVIDIA Tegra124 Jetson TK1 + u-boot-pkg + jetson-tk1 + + nvidia,p2371-2180 + + description + NVIDIA Jetson TX1 Developer Kit + u-boot-pkg + jetson-tx1 + + nvidia,p2771-0000 + + description + NVIDIA Jetson TX2 Developer Kit + u-boot-pkg + jetson-tx2 + + nvidia,p3450-0000 + + description + NVIDIA Jetson Nano Developer Kit + u-boot-pkg + jetson-nano + + + + ti,omap3-beagle + + description + TI OMAP3 BeagleBoard + u-boot-pkg + beagleboard + + ti,am335x-bone + + description + TI AM335x BeagleBone + u-boot-pkg + beaglebonewhite + + ti,am335x-bone-black + + description + TI AM335x BeagleBone Black + u-boot-pkg + beagleboneblack + + ti,omap4-panda + + description + TI OMAP4 PandaBoard + u-boot-pkg + pandaboard + + ti,omap4-panda-es + + description + TI OMAP4 PandaBoard-ES + u-boot-pkg + pandaboard + + + + + lamobo,lamobo-r1 + + description + Lamobo R1 + u-boot-pkg + lamobo-r1 + + lemaker,bananapi + + description + LeMaker Banana Pi + u-boot-pkg + bananapi + + lemaker,bananapro + + description + LeMaker Banana Pro + u-boot-pkg + bananapro + + sinovoip,bpi-m2-zero + + description + Banana Pi BPI-M2 Zero + u-boot-pkg + bananapi-m2-zero + + sinovoip,bpi-m3 + + description + Banana Pi BPI-M3 + u-boot-pkg + bananapi-m3 + + sinovoip,bpi-p2-zero + + description + Banana Pi BPI-P2 Zero + u-boot-pkg + bananapi-p2-zero + + + cubietech,cubieboard2 + + description + Cubietech Cubieboard2 + u-boot-pkg + cubieboard2 + + cubietech,a80-cubieboard4 + + description + Cubietech Cubieboard4 + u-boot-pkg + cubieboard4 + + cubietech,cubietruck + + description + Cubietech Cubietruck + u-boot-pkg + cubietruck + + cubietech,cubietruck-plus + + description + Cubietech Cubietruck Plus + u-boot-pkg + cubietruck-plus + + + friendlyarm,nanopi-m1 + + description + FriendlyArm NanoPi M1 + u-boot-pkg + nanopi-m1 + + friendlyarm,nanopi-neo + + description + FriendlyARM NanoPi NEO + u-boot-pkg + nanopi-neo + + friendlyarm,nanopi-neo-plus2 + + description + FriendlyARM NanoPi NEO Plus2 + u-boot-pkg + nanopi-neo-plus2 + + friendlyarm,nanopi-neo2 + + description + FriendlyARM NanoPi NEO 2 + u-boot-pkg + nanopi-neo2 + + friendlyarm,nanopi-r1 + + description + FriendlyARM NanoPi R1 + u-boot-pkg + nanopi-r1 + + + libretech,all-h3-cc-h2-plus + + description + Libre Computer Board ALL-H3-CC H2+ + u-boot-pkg + libretech-all-h3-cc-h2-plus + + libretech,all-h3-cc-h3 + + description + Libre Computer Board ALL-H3-CC H3 + u-boot-pkg + libretech-all-h3-cc-h3 + + libretech,all-h3-cc-h5 + + description + Libre Computer Board ALL-H3-CC H5 + u-boot-pkg + libretech-all-h3-cc-h5 + + + merrii,a31-hummingbird + + description + Merrii A31 Hummingbird + u-boot-pkg + hummingbird-a31 + + + nextthing,chip + + description + NextThing C.H.I.P. + u-boot-pkg + chip + + nextthing,pocketchip + + description + NextThing PocketC.H.I.P. + u-boot-pkg + pocketchip + + nextthing,chip-pro + + description + NextThing C.H.I.P. Pro + u-boot-pkg + chip-pro + + + olimex,a10-olinuxino-lime + + description + Olimex A10-OLinuXino-LIME + u-boot-pkg + a10-olinuxino-lime + + olimex,a20-olinuxino-lime2 + + description + Olimex A20-OLinuXino-LIME2 + u-boot-pkg + a20-olinuxino-lime2 + + olimex,a20-olinuxino-lime2-emmc + + description + Olimex A20-OLinuXino-LIME2-eMMC + u-boot-pkg + a20-olinuxino-lime2-emmc + + olimex,a20-olinuxino-micro + + description + Olimex A20-OLinuXino-MICRO + u-boot-pkg + a20-olinuxino-micro-emmc + + olimex,a20-olinuxino-micro-emmc + + description + Olimex A20-OLinuXino-MICRO-eMMC + u-boot-pkg + a20-olinuxino-micro-emmc + + + pine64,pine64-plus + + description + Pine64+ + u-boot-pkg + pine64-plus + + pine64,pine64 + + description + Pine64 + u-boot-pkg + pine64 + + pine64,pinebook + + description + Pinebook + u-boot-pkg + pinebook + + pine64,sopine-baseboard + + description + SoPine with baseboard + u-boot-pkg + sopine-baseboard + + pine64,pine64-lts + + description + Pine64 LTS + + u-boot-pkg + sopine-baseboard + + pine64,pine-h64 + + description + Pine H64 + u-boot-pkg + pine-h64 + + + terasic,de0-atlas + + description + Terasic DE-0(Atlas) + u-boot-pkg + de0-nanosoc + + + xunlong,orangepi-2 + + description + Xunlong Orange Pi 2 + u-boot-pkg + orangepi-2 + + xunlong,orangepi-one + + description + Xunlong Orange Pi One + u-boot-pkg + orangepi-one + + xunlong,orangepi-lite + + description + Xunlong Orange Pi Lite + u-boot-pkg + orangepi-lite + + xunlong,orangepi-lite2 + + description + Xunlong Orange Pi Lite2 + u-boot-pkg + orangepi-lite2 + + xunlong,orangepi-plus2e + + description + Xunlong Orange Pi Plus 2E + u-boot-pkg + orangepi-plus2e + + xunlong,orangepi-zero + + description + Xunlong Orange Pi Zero + u-boot-pkg + orangepi-zero + + xunlong,orangepi-zero-plus + + description + Xunlong Orange Pi Zero Plus + u-boot-pkg + orangepi-zero-plus + + + + digilent,zynq-zybo + + description + Digilent Zybo board + u-boot-pkg + zynq-zybo + + digilent,zynq-zybo-z7 + + description + Digilent Zybo Z7 board + u-boot-pkg + zynq-zybo-z7 + + + diff --git a/share/installboot/evbmips/Makefile b/share/installboot/evbmips/Makefile new file mode 100644 index 000000000..b684bf130 --- /dev/null +++ b/share/installboot/evbmips/Makefile @@ -0,0 +1,12 @@ +# $NetBSD: Makefile,v 1.1 2020/06/22 03:15:48 rin Exp $ + +NOOBJ= # defined + +.include + +.if ${MKSHARE} != "no" +FILES= boards.plist +FILESDIR= /usr/share/installboot/evbmips +.endif + +.include diff --git a/share/installboot/evbmips/boards.plist b/share/installboot/evbmips/boards.plist new file mode 100644 index 000000000..4bff3467b --- /dev/null +++ b/share/installboot/evbmips/boards.plist @@ -0,0 +1,43 @@ + + + + + + img,ci20 + + description + MIPS Creator CI20 + u-boot-pkg + ci20 + + + diff --git a/tools/installboot/Makefile b/tools/installboot/Makefile index dd0e97ca3..f7cad6871 100644 --- a/tools/installboot/Makefile +++ b/tools/installboot/Makefile @@ -1,11 +1,40 @@ -# $NetBSD: Makefile,v 1.11 2011/03/06 18:15:30 bouyer Exp $ +# $NetBSD: Makefile,v 1.13 2020/06/21 17:17:01 thorpej Exp $ + +.include HOSTPROGNAME= ${_TOOL_PREFIX}installboot HOST_SRCDIR= usr.sbin/installboot +LIBPROP_INC= ${.CURDIR}/../../common/include +HOST_CPPFLAGS+= -I${LIBPROP_INC} + HOST_CPPFLAGS+= -I. -I${.CURDIR} -I${.CURDIR}/../mips-elf2ecoff HOST_CPPFLAGS+= -I${TOOLDIR}/include/nbinclude +HOST_CPPFLAGS+= -DEVBOARDS_PLIST_BASE=\"${TOOLDIR}\" + +LIBPROP_OBJ!= cd ${.CURDIR}/../libprop && ${PRINTOBJDIR} +LDADD+= -L${LIBPROP_OBJ} -lprop + +SHARE_SRCDIR= ${.CURDIR}/../../share +HOST_SHAREDIR= ${TOOLDIR}/share + +BOARDDB_SRCDIR= ${SHARE_SRCDIR}/installboot +BOARDDB_DSTDIR= ${HOST_SHAREDIR}/installboot + +BOARDDBS= evbarm evbmips + +.for _d in ${BOARDDBS} +install: .PHONY install.${_d}.boards.plist +install.${_d}.boards.plist: .PHONY ${BOARDDB_DSTDIR}/${_d}/boards.plist +${BOARDDB_DSTDIR}/${_d}/boards.plist: ${BOARDDB_SRCDIR}/${_d}/boards.plist + ${_MKTARGET_INSTALL} + ${HOST_INSTALL_DIR} ${HOST_SHAREDIR} + ${HOST_INSTALL_DIR} ${BOARDDB_DSTDIR} + ${HOST_INSTALL_DIR} ${BOARDDB_DSTDIR}/${_d} + ${HOST_INSTALL_FILE} -m ${NONBINMODE} ${.ALLSRC} ${.TARGET} +.endfor + .include "${.CURDIR}/../Makefile.nbincludes" .include "${.CURDIR}/../Makefile.host" diff --git a/usr.sbin/installboot/Makefile b/usr.sbin/installboot/Makefile index c1308193b..22d2a835d 100644 --- a/usr.sbin/installboot/Makefile +++ b/usr.sbin/installboot/Makefile @@ -1,13 +1,12 @@ -# $NetBSD: Makefile,v 1.50 2015/06/06 15:45:47 joerg Exp $ +# $NetBSD: Makefile,v 1.56 2020/09/06 07:20:31 mrg Exp $ # .include -PROG= installboot_nbsd -MAN= installboot_nbsd.8 +PROG= installboot +MAN= installboot.8 SRCS= installboot.c sum.c machines.c fstypes.c install_master.c - .if !defined(__MINIX) ARCH_XLAT= amd64-i386.c news68k-news.c newsmips-news.c ARCH_XLAT+= sun2-sun68k.c sun3-sun68k.c @@ -17,24 +16,55 @@ ARCH_XLAT= amd64-i386.c .if !defined(SMALLPROG) && !defined(ARCH_FILES) .if !defined(__MINIX) -ARCH_FILES= alpha.c amiga.c emips.c ews4800mips.c hp300.c hppa.c i386.c -ARCH_FILES+= landisk.c macppc.c news.c next68k.c pmax.c -ARCH_FILES+= sparc.c sparc64.c sun68k.c vax.c x68k.c +ARCH_FILES= alpha.c amiga.c +ARCH_FILES+= emips.c evbarm.c evbmips.c ews4800mips.c +ARCH_FILES+= hp300.c hppa.c +ARCH_FILES+= i386.c +ARCH_FILES+= landisk.c +ARCH_FILES+= macppc.c +ARCH_FILES+= news.c next68k.c +ARCH_FILES+= pmax.c +ARCH_FILES+= sparc.c sparc64.c sun68k.c +ARCH_FILES+= vax.c +ARCH_FILES+= x68k.c .else -ARCH_FILES= i386.c +ARCH_FILES+= i386.c .endif # !defined(__MINIX) .else ARCH_FILES?= ${ARCH_XLAT:M${MACHINE}-*:S/${MACHINE}-//} .if empty(ARCH_FILES) ARCH_FILES= ${MACHINE}.c .endif +COPTS.machines.c+= -DSINGLE_ARCH=ib_mach_${MACHINE} .endif SRCS+=${ARCH_FILES} +.if !empty(ARCH_FILES:C/(evbarm|evbmips)/evboard/:Mevboard.c) +SRCS+=evboards.c +.endif + +.if !empty(ARCH_FILES:C/(evbarm|evbmips)/fdt/:Mfdt.c) +FDTDIR= ${.CURDIR}/../../sys/external/bsd/libfdt/dist +.PATH: ${FDTDIR} +CPPFLAGS+= -DSUPPORT_FDT -I${FDTDIR} +SRCS+=fdt.c fdt_ro.c fdt_strerror.c +# XXX libfdt has some sign-comparison issues +COPTS.fdt.c+= -Wno-error=sign-compare +COPTS.fdt_ro.c+= -Wno-error=sign-compare +COPTS.fdt_strerror.c+= -Wno-error=sign-compare +.endif + + +.if !defined(HOSTPROGNAME) +.if !empty(ARCH_FILES:C/(evbarm|evbmips)/ofw/:Mofw.c) +CPPFLAGS+= -DSUPPORT_OPENFIRMWARE +.endif +.endif + .if !defined(__MINIX) .if empty(ARCH_FILES:C/(macppc|news|sparc|sun68k|x68k)/stg2/:Mstg2.c) -CPPFLAGS += -DNO_STAGE2 +CPPFLAGS+= -DNO_STAGE2 .else SRCS+= bbinfo.c @@ -63,8 +93,18 @@ CPPFLAGS+= -I${.CURDIR} -I. COPTS.${f}.c+= -Wno-pointer-sign .endfor +.if !empty(SRCS:Mevboards.c) +LDADD+= -lprop +DPADD+= ${LIBPROP} +.endif + LDADD+= -lutil DPADD+= ${LIBUTIL} .endif +.if !defined(__MINIX) +CWARNFLAGS.clang+= -Wno-error=address-of-packed-member +.endif # !defined(__MINIX) +CWARNFLAGS.gcc+= ${GCC_NO_ADDR_OF_PACKED_MEMBER} + .include diff --git a/usr.sbin/installboot/arch/alpha.c b/usr.sbin/installboot/arch/alpha.c index e2de898d4..66e649cb7 100644 --- a/usr.sbin/installboot/arch/alpha.c +++ b/usr.sbin/installboot/arch/alpha.c @@ -1,4 +1,4 @@ -/* $NetBSD: alpha.c,v 1.21 2011/08/14 17:50:17 christos Exp $ */ +/* $NetBSD: alpha.c,v 1.22 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -95,7 +95,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: alpha.c,v 1.21 2011/08/14 17:50:17 christos Exp $"); +__RCSID("$NetBSD: alpha.c,v 1.22 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -121,9 +121,14 @@ static void check_sparc(const struct alpha_boot_block * const, static int alpha_clearboot(ib_params *); static int alpha_setboot(ib_params *); -struct ib_mach ib_mach_alpha = - { "alpha", alpha_setboot, alpha_clearboot, no_editboot, - IB_STAGE1START | IB_ALPHASUM | IB_APPEND | IB_SUNSUM }; +struct ib_mach ib_mach_alpha = { + .name = "alpha", + .setboot = alpha_setboot, + .clearboot = alpha_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE1START | IB_ALPHASUM | IB_APPEND | + IB_SUNSUM, +}; static int alpha_clearboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/amiga.c b/usr.sbin/installboot/arch/amiga.c index 4acccfd2e..7d455dfdf 100644 --- a/usr.sbin/installboot/arch/amiga.c +++ b/usr.sbin/installboot/arch/amiga.c @@ -1,4 +1,4 @@ -/* $NetBSD: amiga.c,v 1.9 2015/06/05 05:02:48 mlelstv Exp $ */ +/* $NetBSD: amiga.c,v 1.10 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: amiga.c,v 1.9 2015/06/05 05:02:48 mlelstv Exp $"); +__RCSID("$NetBSD: amiga.c,v 1.10 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -64,9 +64,13 @@ u_int32_t chksum(u_int32_t *, int); static int amiga_setboot(ib_params *); -struct ib_mach ib_mach_amiga = - { "amiga", amiga_setboot, no_clearboot, no_editboot, - IB_STAGE1START | IB_STAGE2START | IB_COMMAND }; +struct ib_mach ib_mach_amiga = { + .name = "amiga", + .setboot = amiga_setboot, + .clearboot = no_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE1START | IB_STAGE2START | IB_COMMAND, +}; static int amiga_setboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/emips.c b/usr.sbin/installboot/arch/emips.c index a1e2e2e50..e3bfaafaa 100644 --- a/usr.sbin/installboot/arch/emips.c +++ b/usr.sbin/installboot/arch/emips.c @@ -1,4 +1,4 @@ -/* $NetBSD: emips.c,v 1.1 2011/01/26 01:18:55 pooka Exp $ */ +/* $NetBSD: emips.c,v 1.2 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc. @@ -105,7 +105,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: emips.c,v 1.1 2011/01/26 01:18:55 pooka Exp $"); +__RCSID("$NetBSD: emips.c,v 1.2 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -125,10 +125,13 @@ __RCSID("$NetBSD: emips.c,v 1.1 2011/01/26 01:18:55 pooka Exp $"); static int emips_clearboot(ib_params *); static int emips_setboot(ib_params *); -struct ib_mach ib_mach_emips = - { "emips", emips_setboot, emips_clearboot, no_editboot, - IB_STAGE1START | IB_APPEND | IB_SUNSUM }; - +struct ib_mach ib_mach_emips = { + .name = "emips", + .setboot = emips_setboot, + .clearboot = emips_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE1START | IB_APPEND | IB_SUNSUM, +}; static int emips_clearboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/evbarm.c b/usr.sbin/installboot/arch/evbarm.c new file mode 100644 index 000000000..977cfb762 --- /dev/null +++ b/usr.sbin/installboot/arch/evbarm.c @@ -0,0 +1,119 @@ +/* $NetBSD: evbarm.c,v 1.1 2019/05/07 05:02:42 thorpej Exp $ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include +#if !defined(__lint) +__RCSID("$NetBSD: evbarm.c,v 1.1 2019/05/07 05:02:42 thorpej Exp $"); +#endif /* !__lint */ + +#include +#include +#include +#include + +#include "installboot.h" +#include "evboards.h" + +static int evbarm_setboot(ib_params *); +static int evbarm_clearboot(ib_params *); +static int evbarm_editboot(ib_params *); +static void evbarm_usage(ib_params *); + +struct ib_mach ib_mach_evbarm = { + .name = "evbarm", + .setboot = evbarm_setboot, + .clearboot = evbarm_clearboot, + .editboot = evbarm_editboot, + .usage = evbarm_usage, + .valid_flags = IB_BOARD | IB_DTB | IB_MEDIA, + .mach_flags = MF_UBOOT, +}; + +static int +evbarm_setboot(ib_params *params) +{ + evb_board board; + int rv = 0; + + if (!evb_db_load(params)) { + warnx("Unable to load board db."); + return 0; + } + + board = evb_db_get_board(params); + if (board == NULL) + goto out; + + rv = evb_uboot_setboot(params, board); + + out: + if (params->mach_data) { + prop_object_release(params->mach_data); + params->mach_data = NULL; + } + return rv; +} + +static int +evbarm_clearboot(ib_params *params) +{ + + return no_clearboot(params); +} + +static int +evbarm_editboot(ib_params *params) +{ + + return no_editboot(params); +} + +static void +evbarm_usage(ib_params *params) +{ + + if (!evb_db_load(params)) { + warnx("Unable to load board db."); + return; + } + + fprintf(stderr, "Known boards (for -o board=...) are:\n"); + evb_db_list_boards(params, stderr); + + if (params->mach_data) { + prop_object_release(params->mach_data); + params->mach_data = NULL; + } +} diff --git a/usr.sbin/installboot/arch/evbmips.c b/usr.sbin/installboot/arch/evbmips.c new file mode 100644 index 000000000..f2452594d --- /dev/null +++ b/usr.sbin/installboot/arch/evbmips.c @@ -0,0 +1,119 @@ +/* $NetBSD: evbmips.c,v 1.1 2020/06/21 17:17:02 thorpej Exp $ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include +#if !defined(__lint) +__RCSID("$NetBSD: evbmips.c,v 1.1 2020/06/21 17:17:02 thorpej Exp $"); +#endif /* !__lint */ + +#include +#include +#include +#include + +#include "installboot.h" +#include "evboards.h" + +static int evbmips_setboot(ib_params *); +static int evbmips_clearboot(ib_params *); +static int evbmips_editboot(ib_params *); +static void evbmips_usage(ib_params *); + +struct ib_mach ib_mach_evbmips = { + .name = "evbmips", + .setboot = evbmips_setboot, + .clearboot = evbmips_clearboot, + .editboot = evbmips_editboot, + .usage = evbmips_usage, + .valid_flags = IB_BOARD | IB_DTB | IB_MEDIA, + .mach_flags = MF_UBOOT, +}; + +static int +evbmips_setboot(ib_params *params) +{ + evb_board board; + int rv = 0; + + if (!evb_db_load(params)) { + warnx("Unable to load board db."); + return 0; + } + + board = evb_db_get_board(params); + if (board == NULL) + goto out; + + rv = evb_uboot_setboot(params, board); + + out: + if (params->mach_data) { + prop_object_release(params->mach_data); + params->mach_data = NULL; + } + return rv; +} + +static int +evbmips_clearboot(ib_params *params) +{ + + return no_clearboot(params); +} + +static int +evbmips_editboot(ib_params *params) +{ + + return no_editboot(params); +} + +static void +evbmips_usage(ib_params *params) +{ + + if (!evb_db_load(params)) { + warnx("Unable to load board db."); + return; + } + + fprintf(stderr, "Known boards (for -o board=...) are:\n"); + evb_db_list_boards(params, stderr); + + if (params->mach_data) { + prop_object_release(params->mach_data); + params->mach_data = NULL; + } +} diff --git a/usr.sbin/installboot/arch/ews4800mips.c b/usr.sbin/installboot/arch/ews4800mips.c index 3a8e5d08a..360e93dde 100644 --- a/usr.sbin/installboot/arch/ews4800mips.c +++ b/usr.sbin/installboot/arch/ews4800mips.c @@ -5,7 +5,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: ews4800mips.c,v 1.2 2006/02/18 10:08:07 dsl Exp $"); +__RCSID("$NetBSD: ews4800mips.c,v 1.3 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -16,8 +16,12 @@ __RCSID("$NetBSD: ews4800mips.c,v 1.2 2006/02/18 10:08:07 dsl Exp $"); static int ews4800mips_setboot(ib_params *); -struct ib_mach ib_mach_ews4800mips = - { "ews4800mips", ews4800mips_setboot, no_clearboot, no_editboot, 0}; +struct ib_mach ib_mach_ews4800mips = { + .name = "ews4800mips", + .setboot = ews4800mips_setboot, + .clearboot = no_clearboot, + .editboot = no_editboot, +}; struct bbinfo_params ews4800mips_bbparams = { EWS4800MIPS_BBINFO_MAGIC, diff --git a/usr.sbin/installboot/arch/hp300.c b/usr.sbin/installboot/arch/hp300.c index c5de67bba..b0a89abac 100644 --- a/usr.sbin/installboot/arch/hp300.c +++ b/usr.sbin/installboot/arch/hp300.c @@ -1,4 +1,4 @@ -/* $NetBSD: hp300.c,v 1.15 2013/06/14 03:54:43 msaitoh Exp $ */ +/* $NetBSD: hp300.c,v 1.16 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: hp300.c,v 1.15 2013/06/14 03:54:43 msaitoh Exp $"); +__RCSID("$NetBSD: hp300.c,v 1.16 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ /* We need the target disklabel.h, not the hosts one..... */ @@ -64,8 +64,13 @@ __RCSID("$NetBSD: hp300.c,v 1.15 2013/06/14 03:54:43 msaitoh Exp $"); static int hp300_setboot(ib_params *); -struct ib_mach ib_mach_hp300 = - { "hp300", hp300_setboot, no_clearboot, no_editboot, IB_APPEND }; +struct ib_mach ib_mach_hp300 = { + .name = "hp300", + .setboot = hp300_setboot, + .clearboot = no_clearboot, + .editboot = no_editboot, + .valid_flags = IB_APPEND, +}; static int hp300_setboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/hppa.c b/usr.sbin/installboot/arch/hppa.c index d418c3c6b..05158336f 100644 --- a/usr.sbin/installboot/arch/hppa.c +++ b/usr.sbin/installboot/arch/hppa.c @@ -1,4 +1,4 @@ -/* $NetBSD: hppa.c,v 1.1 2014/02/24 07:23:44 skrll Exp $ */ +/* $NetBSD: hppa.c,v 1.2 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: hppa.c,v 1.1 2014/02/24 07:23:44 skrll Exp $"); +__RCSID("$NetBSD: hppa.c,v 1.2 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ /* We need the target disklabel.h, not the hosts one..... */ @@ -65,8 +65,12 @@ __RCSID("$NetBSD: hppa.c,v 1.1 2014/02/24 07:23:44 skrll Exp $"); static int hppa_clearboot(ib_params *); static int hppa_setboot(ib_params *); -struct ib_mach ib_mach_hppa = - { "hppa", hppa_setboot, hppa_clearboot, no_editboot, 0}; +struct ib_mach ib_mach_hppa = { + .name = "hppa", + .setboot = hppa_setboot, + .clearboot = hppa_clearboot, + .editboot = no_editboot, +}; static int hppa_clearboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/i386.c b/usr.sbin/installboot/arch/i386.c index c4fb1e035..3de985047 100644 --- a/usr.sbin/installboot/arch/i386.c +++ b/usr.sbin/installboot/arch/i386.c @@ -1,4 +1,4 @@ -/* $NetBSD: i386.c,v 1.40 2013/06/14 03:54:43 msaitoh Exp $ */ +/* $NetBSD: i386.c,v 1.42 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: i386.c,v 1.40 2013/06/14 03:54:43 msaitoh Exp $"); +__RCSID("$NetBSD: i386.c,v 1.42 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -75,27 +75,37 @@ static const struct console_name { static int i386_setboot(ib_params *); static int i386_editboot(ib_params *); -struct ib_mach ib_mach_i386 = - { "i386", i386_setboot, no_clearboot, i386_editboot, - IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR | - IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT | +struct ib_mach ib_mach_i386 = { + .name = "i386", + .setboot = i386_setboot, + .clearboot = no_clearboot, + .editboot = i386_editboot, + .valid_flags = IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | + IB_CONSADDR | IB_KEYMAP | IB_PASSWORD | + IB_TIMEOUT | #if !defined(__minix) - IB_MODULES | IB_BOOTCONF | - IB_STAGE1START }; + IB_MODULES | IB_BOOTCONF | + IB_STAGE1START #else - IB_MODULES | IB_BOOTCONF }; + IB_MODULES | IB_BOOTCONF #endif /* !defined(__minix) */ +}; -struct ib_mach ib_mach_amd64 = - { "amd64", i386_setboot, no_clearboot, i386_editboot, - IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | IB_CONSADDR | - IB_KEYMAP | IB_PASSWORD | IB_TIMEOUT | +struct ib_mach ib_mach_amd64 = { + .name = "amd64", + .setboot = i386_setboot, + .clearboot = no_clearboot, + .editboot = i386_editboot, + .valid_flags = IB_RESETVIDEO | IB_CONSOLE | IB_CONSPEED | + IB_CONSADDR | IB_KEYMAP | IB_PASSWORD | + IB_TIMEOUT | #if !defined(__minix) - IB_MODULES | IB_BOOTCONF | - IB_STAGE1START }; + IB_MODULES | IB_BOOTCONF | + IB_STAGE1START #else - IB_MODULES | IB_BOOTCONF }; + IB_MODULES | IB_BOOTCONF #endif /* !defined(__minix) */ +}; /* * Attempting to write the 'labelsector' (or a sector near it - within 8k?) @@ -426,8 +436,19 @@ i386_setboot(ib_params *params) return 0; } - /* Find size of old BPB, and copy into new bootcode */ - if (!is_zero(disk_buf.b + 3 + 8, disk_buf.b[1] - 1 - 8)) { + /* + * Find size of old BPB, and copy into new bootcode + * + * The 2nd byte (b[1]) contains jmp short relative offset. + * If it is zero or some invalid input that is smaller than 9, + * it will cause overflow and call is_zero() with enormous size. + * Add a paranoid check to prevent this scenario. + * + * Verify that b[0] contains JMP (0xeb) and b[2] NOP (0x90). + */ + if (disk_buf.b[0] == 0xeb && disk_buf.b[1] >= 9 && + disk_buf.b[2] == 0x90 && + !is_zero(disk_buf.b + 3 + 8, disk_buf.b[1] - 1 - 8)) { struct mbr_bpbFAT16 *bpb = (void *)(disk_buf.b + 3 + 8); /* Check enough space before the FAT for the bootcode */ u = le16toh(bpb->bpbBytesPerSec) diff --git a/usr.sbin/installboot/arch/landisk.c b/usr.sbin/installboot/arch/landisk.c index d58aa08d9..3f265670d 100644 --- a/usr.sbin/installboot/arch/landisk.c +++ b/usr.sbin/installboot/arch/landisk.c @@ -1,4 +1,4 @@ -/* $NetBSD: landisk.c,v 1.6 2013/10/19 17:08:15 christos Exp $ */ +/* $NetBSD: landisk.c,v 1.8 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: landisk.c,v 1.6 2013/10/19 17:08:15 christos Exp $"); +__RCSID("$NetBSD: landisk.c,v 1.8 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -53,9 +53,13 @@ __RCSID("$NetBSD: landisk.c,v 1.6 2013/10/19 17:08:15 christos Exp $"); static int landisk_setboot(ib_params *); -struct ib_mach ib_mach_landisk = - { "landisk", landisk_setboot, no_clearboot, no_editboot, - IB_TIMEOUT }; +struct ib_mach ib_mach_landisk = { + .name = "landisk", + .setboot = landisk_setboot, + .clearboot = no_clearboot, + .editboot = no_editboot, + .valid_flags = IB_TIMEOUT, +}; static int landisk_setboot(ib_params *params) @@ -100,12 +104,18 @@ landisk_setboot(ib_params *params) goto done; } if (mbr.mbr_magic != le16toh(MBR_MAGIC)) { - if (params->flags & IB_VERBOSE) { - printf( - "Ignoring MBR with invalid magic in sector 0 of `%s'\n", - params->filesystem); + const char *p = (const char *)&mbr; + const char *e = p + sizeof(mbr); + while (p < e && !*p) + p++; + if (p != e) { + if (params->flags & IB_VERBOSE) { + printf( + "Ignoring MBR with invalid magic in sector 0 of `%s'\n", + params->filesystem); + } + memset(&mbr, 0, sizeof(mbr)); } - memset(&mbr, 0, sizeof(mbr)); } /* diff --git a/usr.sbin/installboot/arch/macppc.c b/usr.sbin/installboot/arch/macppc.c index 1f4e88beb..cb2187d03 100644 --- a/usr.sbin/installboot/arch/macppc.c +++ b/usr.sbin/installboot/arch/macppc.c @@ -1,4 +1,4 @@ -/* $NetBSD: macppc.c,v 1.11 2008/05/24 19:15:21 tsutsui Exp $ */ +/* $NetBSD: macppc.c,v 1.12 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: macppc.c,v 1.11 2008/05/24 19:15:21 tsutsui Exp $"); +__RCSID("$NetBSD: macppc.c,v 1.12 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -67,9 +67,13 @@ static int writeapplepartmap(ib_params *, struct bbinfo_params *, uint8_t *); static int macppc_clearboot(ib_params *); static int macppc_setboot(ib_params *); -struct ib_mach ib_mach_macppc = - { "macppc", macppc_setboot, macppc_clearboot, no_editboot, - IB_STAGE2START }; +struct ib_mach ib_mach_macppc = { + .name = "macppc", + .setboot = macppc_setboot, + .clearboot = macppc_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE2START, +}; static int macppc_clearboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/news.c b/usr.sbin/installboot/arch/news.c index 27acd8b5d..afa81d3ad 100644 --- a/usr.sbin/installboot/arch/news.c +++ b/usr.sbin/installboot/arch/news.c @@ -1,4 +1,4 @@ -/* $NetBSD: news.c,v 1.7 2008/04/28 20:24:16 martin Exp $ */ +/* $NetBSD: news.c,v 1.8 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: news.c,v 1.7 2008/04/28 20:24:16 martin Exp $"); +__RCSID("$NetBSD: news.c,v 1.8 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -57,13 +57,21 @@ static int news68k_setboot(ib_params *); static int newsmips_clearboot(ib_params *); static int newsmips_setboot(ib_params *); -struct ib_mach ib_mach_news68k = - { "news68k", news68k_setboot, news68k_clearboot, no_editboot, - IB_STAGE2START }; +struct ib_mach ib_mach_news68k = { + .name = "news68k", + .setboot = news68k_setboot, + .clearboot = news68k_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE2START, +}; -struct ib_mach ib_mach_newsmips = - { "newsmips", newsmips_setboot, newsmips_clearboot, no_editboot, - IB_STAGE2START }; +struct ib_mach ib_mach_newsmips = { + .name = "newsmips", + .setboot = newsmips_setboot, + .clearboot = newsmips_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE2START, +}; /* * news68k specific support diff --git a/usr.sbin/installboot/arch/next68k.c b/usr.sbin/installboot/arch/next68k.c index e897a40d9..52db24d50 100644 --- a/usr.sbin/installboot/arch/next68k.c +++ b/usr.sbin/installboot/arch/next68k.c @@ -1,4 +1,4 @@ -/* $NetBSD: next68k.c,v 1.8 2013/06/14 03:54:43 msaitoh Exp $ */ +/* $NetBSD: next68k.c,v 1.9 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: next68k.c,v 1.8 2013/06/14 03:54:43 msaitoh Exp $"); +__RCSID("$NetBSD: next68k.c,v 1.9 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -54,8 +54,12 @@ __RCSID("$NetBSD: next68k.c,v 1.8 2013/06/14 03:54:43 msaitoh Exp $"); static uint16_t nextstep_checksum(const void *, const void *); static int next68k_setboot(ib_params *); -struct ib_mach ib_mach_next68k = - { "next68k", next68k_setboot, no_clearboot, no_editboot, 0}; +struct ib_mach ib_mach_next68k = { + .name = "next68k", + .setboot = next68k_setboot, + .clearboot = no_clearboot, + .editboot = no_editboot, +}; static uint16_t nextstep_checksum(const void *vbuf, const void *vlimit) diff --git a/usr.sbin/installboot/arch/pmax.c b/usr.sbin/installboot/arch/pmax.c index 962cd2a83..88a0244c7 100644 --- a/usr.sbin/installboot/arch/pmax.c +++ b/usr.sbin/installboot/arch/pmax.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmax.c,v 1.15 2013/10/21 15:37:46 christos Exp $ */ +/* $NetBSD: pmax.c,v 1.16 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc. @@ -98,7 +98,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: pmax.c,v 1.15 2013/10/21 15:37:46 christos Exp $"); +__RCSID("$NetBSD: pmax.c,v 1.16 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -121,9 +121,13 @@ static int load_bootstrap(ib_params *, char **, static int pmax_clearboot(ib_params *); static int pmax_setboot(ib_params *); -struct ib_mach ib_mach_pmax = - { "pmax", pmax_setboot, pmax_clearboot, no_editboot, - IB_STAGE1START | IB_APPEND | IB_SUNSUM }; +struct ib_mach ib_mach_pmax = { + .name = "pmax", + .setboot = pmax_setboot, + .clearboot = pmax_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE1START | IB_APPEND | IB_SUNSUM, +}; static int diff --git a/usr.sbin/installboot/arch/sparc.c b/usr.sbin/installboot/arch/sparc.c index 2629442d9..817ac7124 100644 --- a/usr.sbin/installboot/arch/sparc.c +++ b/usr.sbin/installboot/arch/sparc.c @@ -1,4 +1,4 @@ -/* $NetBSD: sparc.c,v 1.11 2008/04/28 20:24:16 martin Exp $ */ +/* $NetBSD: sparc.c,v 1.12 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: sparc.c,v 1.11 2008/04/28 20:24:16 martin Exp $"); +__RCSID("$NetBSD: sparc.c,v 1.12 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -65,9 +65,13 @@ static int sparc_setheader(ib_params *, struct bbinfo_params *, uint8_t *); static int sparc_clearboot(ib_params *); static int sparc_setboot(ib_params *); -struct ib_mach ib_mach_sparc = - { "sparc", sparc_setboot, sparc_clearboot, no_editboot, - IB_STAGE2START }; +struct ib_mach ib_mach_sparc = { + .name = "sparc", + .setboot = sparc_setboot, + .clearboot = sparc_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE2START, +}; static int sparc_clearboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/sparc64.c b/usr.sbin/installboot/arch/sparc64.c index 4fc87721c..109399d76 100644 --- a/usr.sbin/installboot/arch/sparc64.c +++ b/usr.sbin/installboot/arch/sparc64.c @@ -1,4 +1,4 @@ -/* $NetBSD: sparc64.c,v 1.18 2010/01/14 16:27:49 tsutsui Exp $ */ +/* $NetBSD: sparc64.c,v 1.19 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: sparc64.c,v 1.18 2010/01/14 16:27:49 tsutsui Exp $"); +__RCSID("$NetBSD: sparc64.c,v 1.19 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -79,8 +79,12 @@ __RCSID("$NetBSD: sparc64.c,v 1.18 2010/01/14 16:27:49 tsutsui Exp $"); static int sparc64_clearboot(ib_params *); static int sparc64_setboot(ib_params *); -struct ib_mach ib_mach_sparc64 = - { "sparc64", sparc64_setboot, sparc64_clearboot, no_editboot, 0}; +struct ib_mach ib_mach_sparc64 = { + .name = "sparc64", + .setboot = sparc64_setboot, + .clearboot = sparc64_clearboot, + .editboot = no_editboot, +}; static int sparc64_clearboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/sun68k.c b/usr.sbin/installboot/arch/sun68k.c index a4c900b5a..4981eb29d 100644 --- a/usr.sbin/installboot/arch/sun68k.c +++ b/usr.sbin/installboot/arch/sun68k.c @@ -1,4 +1,4 @@ -/* $NetBSD: sun68k.c,v 1.21 2008/04/28 20:24:16 martin Exp $ */ +/* $NetBSD: sun68k.c,v 1.22 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: sun68k.c,v 1.21 2008/04/28 20:24:16 martin Exp $"); +__RCSID("$NetBSD: sun68k.c,v 1.22 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -49,13 +49,21 @@ __RCSID("$NetBSD: sun68k.c,v 1.21 2008/04/28 20:24:16 martin Exp $"); static int sun68k_clearboot(ib_params *); static int sun68k_setboot(ib_params *); -struct ib_mach ib_mach_sun2 = - { "sun2", sun68k_setboot, sun68k_clearboot, no_editboot, - IB_STAGE2START }; +struct ib_mach ib_mach_sun2 = { + .name = "sun2", + .setboot = sun68k_setboot, + .clearboot = sun68k_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE2START, +}; -struct ib_mach ib_mach_sun3 = - { "sun3", sun68k_setboot, sun68k_clearboot, no_editboot, - IB_STAGE2START }; +struct ib_mach ib_mach_sun3 = { + .name = "sun3", + .setboot = sun68k_setboot, + .clearboot = sun68k_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE2START, +}; static struct bbinfo_params bbparams = { SUN68K_BBINFO_MAGIC, diff --git a/usr.sbin/installboot/arch/vax.c b/usr.sbin/installboot/arch/vax.c index c67f08885..21070859a 100644 --- a/usr.sbin/installboot/arch/vax.c +++ b/usr.sbin/installboot/arch/vax.c @@ -1,4 +1,4 @@ -/* $NetBSD: vax.c,v 1.18 2014/11/13 16:02:25 christos Exp $ */ +/* $NetBSD: vax.c,v 1.19 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: vax.c,v 1.18 2014/11/13 16:02:25 christos Exp $"); +__RCSID("$NetBSD: vax.c,v 1.19 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -100,9 +100,13 @@ static int load_bootstrap(ib_params *, char **, static int vax_clearboot(ib_params *); static int vax_setboot(ib_params *); -struct ib_mach ib_mach_vax = - { "vax", vax_setboot, vax_clearboot, no_editboot, - IB_STAGE1START | IB_APPEND | IB_SUNSUM }; +struct ib_mach ib_mach_vax = { + .name = "vax", + .setboot = vax_setboot, + .clearboot = vax_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE1START | IB_APPEND | IB_SUNSUM, +}; static int vax_clearboot(ib_params *params) diff --git a/usr.sbin/installboot/arch/x68k.c b/usr.sbin/installboot/arch/x68k.c index ee78cf7ec..94f9d50a3 100644 --- a/usr.sbin/installboot/arch/x68k.c +++ b/usr.sbin/installboot/arch/x68k.c @@ -1,4 +1,4 @@ -/* $NetBSD: x68k.c,v 1.4 2008/04/28 20:24:16 martin Exp $ */ +/* $NetBSD: x68k.c,v 1.5 2019/05/07 04:35:31 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: x68k.c,v 1.4 2008/04/28 20:24:16 martin Exp $"); +__RCSID("$NetBSD: x68k.c,v 1.5 2019/05/07 04:35:31 thorpej Exp $"); #endif /* !__lint */ #include @@ -59,9 +59,13 @@ static int x68k_clearheader(ib_params *, struct bbinfo_params *, uint8_t *); static int x68k_clearboot(ib_params *); static int x68k_setboot(ib_params *); -struct ib_mach ib_mach_x68k = - { "x68k", x68k_setboot, x68k_clearboot, no_editboot, - IB_STAGE1START | IB_STAGE2START }; +struct ib_mach ib_mach_x68k = { + .name = "x68k", + .setboot = x68k_setboot, + .clearboot = x68k_clearboot, + .editboot = no_editboot, + .valid_flags = IB_STAGE1START | IB_STAGE2START, +}; static struct bbinfo_params bbparams = { X68K_BBINFO_MAGIC, diff --git a/usr.sbin/installboot/evboards.c b/usr.sbin/installboot/evboards.c new file mode 100644 index 000000000..d2f1ee74d --- /dev/null +++ b/usr.sbin/installboot/evboards.c @@ -0,0 +1,1974 @@ +/* $NetBSD: evboards.c,v 1.5 2020/06/07 00:58:58 thorpej Exp $ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include +#if !defined(__lint) +__RCSID("$NetBSD: evboards.c,v 1.5 2020/06/07 00:58:58 thorpej Exp $"); +#endif /* !__lint */ + +#include +#include /* for roundup() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef SUPPORT_FDT +#include "libfdt.h" +#endif + +#if !HAVE_NBTOOL_CONFIG_H +#include + +#ifdef SUPPORT_OPENFIRMWARE +#include +#include +#endif + +#endif /* ! HAVE_NBTOOL_CONFIG_H */ + +#include "installboot.h" +#include "evboards.h" + +/* + * The board database is implemented as a property list. The base + * system provides a set of known boards, keyed by their "compatible" + * device tree property. + * + * The database provided by the base system is meant to help guide + * the user as to which u-boot package needs to be installed on the + * system in order to write the boot loader to the boot media. The + * base board plist is specific to the $MACHINE (e.g. "evbarm"), and + * is installed along with the build tools, e.g.: + * + * (native location) + * /usr/sbin/installboot + * /usr/share/installboot/evbarm/boards.plist + * /usr/share/installboot/evbmips/boards.plist + * + * (example cross host tool location) + * /usr/local/xnbsd/bin/nbinstallboot + * /usr/local/xnbsd/share/installboot/evbarm/boards.plist + * /usr/local/xnbsd/share/installboot/evbmips/boards.plist + * + * The schema of the base board plist is as follows: + * + * + * + * + * example,example-board + * + * + * description + * Example Co. Example Board + * + * + * u-boot-pkg + * exampleboard + * + * + * + * + * Individual u-boot packages install their own overlay property list + * files that installboot(8) then scans for. These overlay files are + * named "installboot.plist", and are installed alongside the u-boot + * binaries by the individual u-boot packages, for example: + * + * /usr/pkg/share/u-boot/exampleboard/installboot.plist + * /usr/pkg/share/u-boot/exampleboard/u-boot-with-spl.bin + * + * installboot(8) scans a set of directories looking for "installboot.plist" + * overlay files one directory deep. For example: + * + * /usr/pkg/share/u-boot/ + * exampleboard/installboot.plist + * superarmdeluxe/installboot.plist + * dummy/ + * + * In this example, "/usr/pkg/share/u-boot" is scanned, it would identify + * "exampleboard" and "superarmdeluxe" as directories containing overlays + * and load them. + * + * The default path scanned for u-boot packages is: + * + * /usr/pkg/share/u-boot + * + * This can be overridden with the INSTALLBOOT_UBOOT_PATHS environment + * variable, which contains a colon-sparated list of directories, e.g.: + * + * /usr/pkg/share/u-boot:/home/jmcneill/hackityhack/u-boot + * + * The scan only consults the top-level children of the specified directory. + * + * Each overlay includes complete board objects that entirely replace + * the system-provided board objects in memory. Some of the keys in + * overlay board objects are computed at run-time and should not appear + * in the plists loaded from the file system. + * + * The schema of the overlay board plists are as follows: + * + * + * + * + * example,example-board + * + * + * description + * Example Co. Example Board + * + * + * u-boot-install + * + * + * + * + * + * runtime-u-boot-path + * /usr/pkg/share/u-boot/exampleboard + * + * + * + * + * The installation objects provide a description of the steps needed + * to install u-boot on the boot media. Each installation object it + * itself an array of step object. + * + * A basic installation object has a single step that instructs + * installboot(8) to write a file to a specific offset onto the + * boot media. + * + * u-boot-install + * + * + * + * + * + * file-name + * u-boot-with-spl.bin + * + * + * image-offset + * 8192 + * + * + * + * Some installations require multiple steps with special handling. + * + * u-boot-install + * + * <-- + * -- Step 1: Write the initial portion of the boot + * -- loader onto the media. The loader has a "hole" + * -- to leave room for the MBR partition table. Take + * -- care not to scribble over the table. + * --> + * + * file-name + * u-boot-img.bin + * + * + * + * file-size + * 442 + * + * + * + * preserve + * + * + * <-- + * -- Step 2: Write the rest of the loader after the + * -- MBR partition table. + * --> + * + * file-name + * u-boot-img.bin + * + * + * file-offset + * 512 + * + * + * image-offset + * 512 + * + * + * + * There are some addditional directives for installing on raw flash devices: + * + * u-boot-install-spi + * + * + * input-block-size + * 2048 + * + * + * input-pad-size + * 2048 + * + * + * output-size + * 2097152 + * + * <-- Key: "output-block-size" + * -- Value: an integer specifying the size of + * -- the blocks used to write to the + * -- output device. If the output device + * -- simulates a disk block storage device, + * -- then this value must be a multiple of + * -- the reported sector size. + * -- (optional) + * --> + * output-block-size + * 65536 + * + * + * + * For boards that require a media specification to be provided, it + * may be the case that two media types have identical steps. It + * could be confusing for users to see a list of media types that does + * not include the media type on which they are installing, so there + * is an alias capability: + * + * u-boot-install-spi + * + * . + * . + * . + * + * u-boot-install-sdmmc + * + * . + * . + * . + * + * <-- Steps for eMMC are identical to SDMMC on this board. --> + * u-boot-install-emmc + * u-boot-install-sdmmc + */ + +/* + * make_path -- + * Build a path into the given buffer with the specified + * format. Returns NULL if the path won't fit. + */ +static __printflike(3,4) const char * +make_path(char *buf, size_t bufsize, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vsnprintf(buf, bufsize, fmt, ap); + va_end(ap); + + if (ret < 0 || (size_t)ret >= bufsize) + return NULL; + + return buf; +} + +#ifndef EVBOARDS_PLIST_BASE +#define EVBOARDS_PLIST_BASE "/usr" +#endif + +static const char evb_db_base_location[] = + EVBOARDS_PLIST_BASE "/share/installboot"; + +#ifndef DEFAULT_UBOOT_PKG_PATH +#define DEFAULT_UBOOT_PKG_PATH "/usr/pkg/share/u-boot" +#endif + +#ifndef UBOOT_PATHS_ENV_VAR +#define UBOOT_PATHS_ENV_VAR "INSTALLBOOT_UBOOT_PATHS" +#endif + +static const char evb_uboot_pkg_path[] = DEFAULT_UBOOT_PKG_PATH; + +/* + * evb_db_base_path -- + * Returns the path to the base board db file. + */ +static const char * +evb_db_base_path(ib_params *params, char *buf, size_t bufsize) +{ + + return make_path(buf, bufsize, "%s/%s/boards.plist", + evb_db_base_location, params->machine->name); +} + +/* + * evb_uboot_pkg_paths -- + * Returns an array of u-boot package paths to scan for + * installboot.plist files. + * + * Number of array elements, not including the NULL terminator, + * is returned in *countp. + * + * The working buffer is returned in *bufp so that the caller + * can free it. + */ +static char ** +evb_uboot_pkg_paths(ib_params *params, int *countp, void **bufp) +{ + char **ret_array = NULL; + char *buf = NULL; + const char *pathspec; + int i, count; + char *cp, *startcp; + + pathspec = getenv(UBOOT_PATHS_ENV_VAR); + if (pathspec == NULL) + pathspec = evb_uboot_pkg_path; + + if (strlen(pathspec) == 0) + goto out; + + /* Count the path elements. */ + for (cp = __UNCONST(pathspec), count = 0;;) { + count++; + cp = strchr(cp, ':'); + if (cp == NULL) + break; + cp++; + } + + buf = malloc((sizeof(char *) * (count + 1)) + + strlen(pathspec) + 1); + if (buf == NULL) + goto out; + + /* + * Because we want to follow the usual "paths are listed in priority + * order" semantics, we reverse the order of the paths when we put + * them into the array we feed to fts. This is because we always + * overwrite existing entries as we find them, thus the last board + * object found one a given key is the one that will be used. + */ + + ret_array = (char **)buf; + startcp = buf + (sizeof(char *) * (count + 1)); + /* this is a safe strcpy(); don't replace it. */ + strcpy(startcp, pathspec); + + cp = strrchr(startcp, ':'); + if (cp == NULL) + cp = startcp; + + for (i = 0;;) { + if (*cp == ':') { + ret_array[i++] = cp+1; + *cp-- = '\0'; + } else + ret_array[i++] = cp; + if (cp == startcp) + break; + cp = strrchr(cp, ':'); + if (cp == NULL) + cp = startcp; + } + assert(i == count); + ret_array[i] = NULL; + + out: + if (ret_array == NULL) { + if (buf != NULL) + free(buf); + } else { + if (countp != NULL) + *countp = count; + if (bufp != NULL) + *bufp = buf; + } + return ret_array; +} + +static const char step_file_name_key[] = "file-name"; +static const char step_file_offset_key[] = "file-offset"; +static const char step_file_size_key[] = "file-size"; +static const char step_image_offset_key[] = "image-offset"; +static const char step_input_block_size_key[] = "input-block-size"; +static const char step_input_pad_size_key[] = "input-pad-size"; +static const char step_output_size_key[] = "output-size"; +static const char step_output_block_size_key[] = "output-block-size"; +static const char step_preserve_key[] = "preserve"; + +static bool +validate_ubstep_object(evb_ubstep obj) +{ + /* + * evb_ubstep is a dictionary with the following keys: + * + * "file-name" (string) (required) + * "file-offset" (number) (optional) + * "file-size" (number) (optional) + * "image-offset" (number) (optional) + * "input-block-size" (number) (optional) + * "input-pad-size" (number) (optional) + * "output-size" (number) (optional) + * "output-block-size" (number) (optional) + * "preserve" (bool) (optional) + */ + if (prop_object_type(obj) != PROP_TYPE_DICTIONARY) + return false; + + prop_object_t v; + + v = prop_dictionary_get(obj, step_file_name_key); + if (v == NULL || + prop_object_type(v) != PROP_TYPE_STRING) + return false; + + v = prop_dictionary_get(obj, step_file_offset_key); + if (v != NULL && + prop_object_type(v) != PROP_TYPE_NUMBER) + return false; + + v = prop_dictionary_get(obj, step_file_size_key); + if (v != NULL && + prop_object_type(v) != PROP_TYPE_NUMBER) + return false; + + v = prop_dictionary_get(obj, step_image_offset_key); + if (v != NULL && + prop_object_type(v) != PROP_TYPE_NUMBER) + return false; + + bool have_input_block_size = false; + bool have_input_pad_size = false; + + v = prop_dictionary_get(obj, step_input_block_size_key); + if (v != NULL) { + have_input_block_size = true; + if (prop_object_type(v) != PROP_TYPE_NUMBER) + return false; + } + + v = prop_dictionary_get(obj, step_input_pad_size_key); + if (v != NULL) { + have_input_pad_size = true; + if (prop_object_type(v) != PROP_TYPE_NUMBER) + return false; + } + + /* Must have both or neither of input-{block,pad}-size. */ + if (have_input_block_size ^ have_input_pad_size) + return false; + + v = prop_dictionary_get(obj, step_output_size_key); + if (v != NULL && + prop_object_type(v) != PROP_TYPE_NUMBER) + return false; + + v = prop_dictionary_get(obj, step_output_block_size_key); + if (v != NULL && + prop_object_type(v) != PROP_TYPE_NUMBER) + return false; + + v = prop_dictionary_get(obj, step_preserve_key); + if (v != NULL && + prop_object_type(v) != PROP_TYPE_BOOL) + return false; + + return true; +} + +static bool +validate_ubinstall_object(evb_board board, evb_ubinstall obj) +{ + /* + * evb_ubinstall is either: + * -- an array with one or more evb_ubstep objects. + * -- a string representing an alias of another evb_ubinstall + * object + * + * (evb_ubsteps is just a convenience type for iterating + * over the steps.) + */ + + if (prop_object_type(obj) == PROP_TYPE_STRING) { + evb_ubinstall tobj = prop_dictionary_get(board, + prop_string_value((prop_string_t)obj)); + + /* + * The target evb_ubinstall object must exist + * and must itself be a proper evb_ubinstall, + * not another alias. + */ + if (tobj == NULL || + prop_object_type(tobj) != PROP_TYPE_ARRAY) { + return false; + } + return true; + } + + if (prop_object_type(obj) != PROP_TYPE_ARRAY) + return false; + if (prop_array_count(obj) < 1) + return false; + + prop_object_t v; + prop_object_iterator_t iter = prop_array_iterator(obj); + + while ((v = prop_object_iterator_next(iter)) != NULL) { + if (!validate_ubstep_object(v)) + break; + } + + prop_object_iterator_release(iter); + return v == NULL; +} + +static const char board_description_key[] = "description"; +static const char board_u_boot_pkg_key[] = "u-boot-pkg"; +static const char board_u_boot_path_key[] = "runtime-u-boot-path"; +static const char board_u_boot_install_key[] = "u-boot-install"; + +static bool +validate_board_object(evb_board obj, bool is_overlay) +{ + /* + * evb_board is a dictionary with the following keys: + * + * "description" (string) (required) + * "u-boot-pkg" (string) (optional, base only) + * "runtime-u-boot-path" (string) (required, overlay only) + * + * With special consideration for these keys: + * + * Either this key and no other "u-boot-install*" keys: + * "u-boot-install" (string) (required, overlay only) + * + * Or one or more keys of the following pattern: + * "u-boot-install-*" (string) (required, overlay only) + */ + bool has_default_install = false; + bool has_media_install = false; + + if (prop_object_type(obj) != PROP_TYPE_DICTIONARY) + return false; + + prop_object_t v; + + v = prop_dictionary_get(obj, board_description_key); + if (v == NULL || + prop_object_type(v) != PROP_TYPE_STRING) + return false; + + v = prop_dictionary_get(obj, board_u_boot_pkg_key); + if (v != NULL && + (is_overlay || prop_object_type(v) != PROP_TYPE_STRING)) + return false; + + /* + * "runtime-u-boot-path" is added to an overlay after we've + * validated the board object, so simply make sure it's not + * present. + */ + v = prop_dictionary_get(obj, board_u_boot_path_key); + if (v != NULL) + return false; + + prop_object_iterator_t iter = prop_dictionary_iterator(obj); + prop_dictionary_keysym_t key; + while ((key = prop_object_iterator_next(iter)) != NULL) { + const char *cp = prop_dictionary_keysym_value(key); + if (strcmp(cp, board_u_boot_install_key) == 0) { + has_default_install = true; + } else if (strncmp(cp, board_u_boot_install_key, + sizeof(board_u_boot_install_key) - 1) == 0 && + cp[sizeof(board_u_boot_install_key) - 1] == '-') { + has_media_install = true; + } else { + continue; + } + v = prop_dictionary_get_keysym(obj, key); + assert(v != NULL); + if (!is_overlay || !validate_ubinstall_object(obj, v)) + break; + } + prop_object_iterator_release(iter); + if (key != NULL) + return false; + + /* + * Overlays must have only a default install key OR one or more + * media install keys. + */ + if (is_overlay) + return has_default_install ^ has_media_install; + + /* + * Base board objects must have neither. + */ + return (has_default_install | has_media_install) == false; +} + +/* + * evb_db_load_overlay -- + * Load boards from an overlay file into the db. + */ +static void +evb_db_load_overlay(ib_params *params, const char *path, + const char *runtime_uboot_path) +{ + prop_dictionary_t overlay; + struct stat sb; + + if (params->flags & IB_VERBOSE) + printf("Loading '%s'.\n", path); + + if (stat(path, &sb) < 0) { + warn("'%s'", path); + return; + } else { + overlay = prop_dictionary_internalize_from_file(path); + if (overlay == NULL) { + warnx("unable to parse overlay '%s'", path); + return; + } + } + + /* + * Validate all of the board objects and add them to the board + * db, replacing any existing entries as we go. + */ + prop_object_iterator_t iter = prop_dictionary_iterator(overlay); + prop_dictionary_keysym_t key; + prop_dictionary_t board; + while ((key = prop_object_iterator_next(iter)) != NULL) { + board = prop_dictionary_get_keysym(overlay, key); + assert(board != NULL); + if (!validate_board_object(board, true)) { + warnx("invalid board object in '%s': '%s'", path, + prop_dictionary_keysym_value(key)); + continue; + } + + /* Add "runtime-u-boot-path". */ + prop_string_t string = + prop_string_create_copy(runtime_uboot_path); + assert(string != NULL); + prop_dictionary_set(board, board_u_boot_path_key, string); + prop_object_release(string); + + /* Insert into board db. */ + prop_dictionary_set_keysym(params->mach_data, key, board); + } + prop_object_iterator_release(iter); + prop_object_release(overlay); +} + +/* + * evb_db_load_overlays -- + * Load the overlays from the search path. + */ +static void +evb_db_load_overlays(ib_params *params) +{ + char overlay_pathbuf[PATH_MAX+1]; + const char *overlay_path; + char **paths; + void *pathsbuf = NULL; + FTS *fts; + FTSENT *chp, *p; + struct stat sb; + + paths = evb_uboot_pkg_paths(params, NULL, &pathsbuf); + if (paths == NULL) { + warnx("No u-boot search path?"); + return; + } + + fts = fts_open(paths, FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR, NULL); + if (fts == NULL || + (chp = fts_children(fts, 0)) == NULL) { + warn("Unable to search u-boot path"); + if (fts != NULL) + fts_close(fts); + return; + } + + chp = fts_children(fts, 0); + + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info != FTS_D) + continue; + overlay_path = make_path(overlay_pathbuf, + sizeof(overlay_pathbuf), "%s/installboot.plist", + p->fts_path); + if (overlay_path == NULL) + continue; + if (stat(overlay_path, &sb) < 0) + continue; + evb_db_load_overlay(params, overlay_path, p->fts_path); + } + + fts_close(fts); + + /* + * If the user specifed a stage1 loader, then consult it last + * for a possible u-boot package location. + */ + if (params->stage1 != NULL) { + overlay_path = make_path(overlay_pathbuf, + sizeof(overlay_pathbuf), "%s/installboot.plist", + params->stage1); + if (overlay_path != NULL) { + if (stat(overlay_path, &sb) == 0) { + evb_db_load_overlay(params, overlay_path, + params->stage1); + } + } + } +} + +/* + * evb_db_load_base -- + * Load the base board db. + */ +static bool +evb_db_load_base(ib_params *params) +{ + char buf[PATH_MAX+1]; + const char *path; + prop_dictionary_t board_db; + struct stat sb; + + path = evb_db_base_path(params, buf, sizeof(buf)); + if (path == NULL) + return false; + + if (params->flags & IB_VERBOSE) + printf("Loading '%s'.\n", path); + + if (stat(path, &sb) < 0) { + if (errno != ENOENT) { + warn("'%s'", path); + return false; + } + board_db = prop_dictionary_create(); + assert(board_db != NULL); + } else { + board_db = prop_dictionary_internalize_from_file(path); + if (board_db == NULL) { + warnx("unable to parse board db '%s'", path); + return false; + } + } + + if (prop_dictionary_count(board_db) == 0) { + /* + * Oh well, maybe we'll load some overlays. + */ + goto done; + } + + /* + * Validate all of the board objects and remove any bad ones. + */ + prop_array_t all_board_keys = prop_dictionary_all_keys(board_db); + prop_object_iterator_t iter = prop_array_iterator(all_board_keys); + prop_dictionary_keysym_t key; + prop_dictionary_t board; + while ((key = prop_object_iterator_next(iter)) != NULL) { + board = prop_dictionary_get_keysym(board_db, key); + assert(board != NULL); + if (!validate_board_object(board, false)) { + warnx("invalid board object in '%s': '%s'", path, + prop_dictionary_keysym_value(key)); + prop_dictionary_remove_keysym(board_db, key); + } + } + prop_object_iterator_release(iter); + prop_object_release(all_board_keys); + + done: + params->mach_data = board_db; + return true; +} + +/* + * evb_db_load -- + * Load the board database. + */ +bool +evb_db_load(ib_params *params) +{ + if (!evb_db_load_base(params)) + return false; + evb_db_load_overlays(params); + + return true; +} + +#if !HAVE_NBTOOL_CONFIG_H +/* + * Native board name guessing methods. + */ + +#ifdef SUPPORT_OPENFIRMWARE +static int +ofw_fd(void) +{ + static const char openfirm_path[] = "/dev/openfirm"; + + return open(openfirm_path, O_RDONLY); +} + +static int +OF_finddevice(const char *name) +{ + struct ofiocdesc ofio = { + .of_name = __UNCONST(name), + .of_namelen = strlen(name), + }; + int fd = ofw_fd(); + + if (fd == -1) + return -1; + + if (ioctl(fd, OFIOCFINDDEVICE, &ofio) < 0) { + if (errno != ENOENT) + warn("OFIOCFINDDEVICE('%s')", name); + ofio.of_nodeid = -1; + } + (void) close(fd); + + return ofio.of_nodeid; +} + +static int +OF_getprop(int phandle, const char *prop, void *buf, size_t buflen) +{ + struct ofiocdesc ofio = { + .of_nodeid = phandle, + .of_name = __UNCONST(prop), + .of_namelen = strlen(prop), + .of_buf = buf, + .of_buflen = buflen, + }; + int fd = ofw_fd(); + + if (fd == -1) + return -1; + + int save_errno = 0; + + if (ioctl(fd, OFIOCGET, &ofio) < 0) { + save_errno = errno; + if (errno != ENOMEM && errno != ENOENT) { + save_errno = errno; + warn("OFIOCGET('%s')", prop); + } + ofio.of_buflen = -1; + } + (void) close(fd); + errno = save_errno; + + return ofio.of_buflen; +} + +static void * +ofw_getprop(int phandle, const char *prop, int *lenp) +{ + size_t buflen = 32; + void *buf = NULL; + int len; + + for (;;) { + void *newbuf = realloc(buf, buflen); + if (newbuf == NULL) { + free(buf); + return NULL; + } + buf = newbuf; + switch (len = OF_getprop(phandle, prop, buf, buflen)) { + case -1: + if (errno != ENOMEM) { + free(buf); + return NULL; + } + buflen *= 2; + break; + + default: + if (lenp) + *lenp = len; + return buf; + } + } +} + +static evb_board +evb_db_get_board_from_ofw(ib_params *params, const char **board_namep) +{ + int phandle; + int compatible_len = 0; + char *compatible_buf; + const char *sp, *nsp; + evb_board board; + + phandle = OF_finddevice("/"); + if (phandle == -1) { + /* No OpenFirmware available. */ + return NULL; + } + + compatible_buf = ofw_getprop(phandle, "compatible", &compatible_len); + + /* + * We just leak compatible_buf on success. Not a big deal since + * we are not a long-running process. + */ + + sp = compatible_buf; + while (compatible_len && + (nsp = memchr(sp, 0, compatible_len)) != NULL) { + if (params->flags & IB_VERBOSE) + printf("Checking OFW compatible string '%s'.\n", sp); + board = prop_dictionary_get(params->mach_data, sp); + if (board != NULL) { + if (board_namep) + *board_namep = sp; + return board; + } + nsp++; /* skip over NUL */ + compatible_len -= (nsp - sp); + sp = nsp; + } + + free(compatible_buf); + return NULL; +} +#endif /* SUPPORT_OPENFIRMWARE */ + +#endif /* ! HAVE_NBTOOL_CONFIG_H */ + +/* + * Host-tool and native board name guessing methods. + */ + +#ifdef SUPPORT_FDT +static void * +load_dtb(ib_params *params) +{ + struct stat sb; + void *buf; + int fd; + + if (stat(params->dtb, &sb) < 0) { + warn("%s", params->dtb); + return NULL; + } + + buf = malloc((size_t)sb.st_size); + assert(buf != NULL); + + if ((fd = open(params->dtb, O_RDONLY)) < 0) { + warn("%s", params->dtb); + free(buf); + return NULL; + } + + if (read(fd, buf, (size_t)sb.st_size) != (ssize_t)sb.st_size) { + warn("read '%s'", params->dtb); + free(buf); + buf = NULL; + } + (void) close(fd); + + return buf; +} + +static evb_board +evb_db_get_board_from_dtb(ib_params *params, const char **board_namep) +{ + evb_board board = NULL; + void *fdt = NULL; + int error; + + fdt = load_dtb(params); + if (fdt == NULL) + return NULL; + + error = fdt_check_header(fdt); + if (error) { + warnx("%s: %s", params->dtb, fdt_strerror(error)); + goto bad; + } + + const int system_root = fdt_path_offset(fdt, "/"); + if (system_root < 0) { + warnx("%s: unable to find node '/'", params->dtb); + goto bad; + } + + const int system_ncompat = fdt_stringlist_count(fdt, system_root, + "compatible"); + if (system_ncompat <= 0) { + warnx("%s: no 'compatible' property on node '/'", params->dtb); + goto bad; + } + + const char *compatible; + int si; + for (si = 0; si < system_ncompat; si++) { + compatible = fdt_stringlist_get(fdt, system_root, + "compatible", si, NULL); + if (compatible == NULL) + continue; + if (params->flags & IB_VERBOSE) + printf("Checking FDT compatible string '%s'.\n", + compatible); + board = prop_dictionary_get(params->mach_data, compatible); + if (board != NULL) { + /* + * We just leak compatible on success. Not a big + * deal since we are not a long-running process. + */ + if (board_namep) { + *board_namep = strdup(compatible); + assert(*board_namep != NULL); + } + free(fdt); + return board; + } + } + + bad: + if (fdt != NULL) + free(fdt); + return NULL; +} +#endif /* SUPPORT_FDT */ + +/* + * evb_db_get_board -- + * Return the specified board object from the database. + */ +evb_board +evb_db_get_board(ib_params *params) +{ + const char *board_name = NULL; + evb_board board = NULL; + +#if !HAVE_NBTOOL_CONFIG_H + /* + * If we're not a host tool, determine if we're running "natively". + */ + bool is_native = false; + struct utsname utsname; + + if (uname(&utsname) < 0) { + warn("uname"); + } else if (strcmp(utsname.machine, params->machine->name) == 0) { + is_native = true; + } +#endif /* ! HAVE_NBTOOL_CONFIG_H */ + + /* + * Logic for determing board type that can be shared by host-tool + * and native builds goes here. + */ + + /* + * Command-line argument trumps all. + */ + if (params->flags & IB_BOARD) { + board_name = params->board; + } + +#ifdef SUPPORT_FDT + if (board_name == NULL && (params->flags & IB_DTB)) { + board = evb_db_get_board_from_dtb(params, &board_name); + if ((params->flags & IB_VERBOSE) && board != NULL) + printf("Found board '%s' from DTB data.\n", board_name); +#if !HAVE_NBTOOL_CONFIG_H + /* + * If the user specified a DTB, then regardless of the + * outcome, this is like specifying the board directly, + * so native checks should be skipped. + */ + is_native = false; +#endif /* ! HAVE_NBTOOL_CONFIG_H */ + } +#endif /* SUPPORT_FDT */ + +#if !HAVE_NBTOOL_CONFIG_H + /* + * Non-host-tool logic for determining the board type goes here. + */ + +#ifdef SUPPORT_OPENFIRMWARE + if (board_name == NULL && is_native) { + board = evb_db_get_board_from_ofw(params, &board_name); + if ((params->flags & IB_VERBOSE) && board != NULL) + printf("Found board '%s' from OFW data.\n", board_name); + } +#endif /* SUPPORT_OPENFIRMWARE */ + + /* Ensure is_native is consumed. */ + if (is_native == false) + is_native = false; + +#endif /* ! HAVE_NBTOOL_CONFIG_H */ + + /* + * If all else fails, we can always rely on the user, right? + */ + if (board_name == NULL) { + if (!(params->flags & IB_BOARD)) { + warnx("Must specify board=..."); + return NULL; + } + board_name = params->board; + } + + assert(board_name != NULL); + + if (board == NULL) + board = prop_dictionary_get(params->mach_data, board_name); + if (board == NULL) + warnx("Unknown board '%s'", board_name); + + /* Ensure params->board is always valid. */ + params->board = board_name; + + if (params->flags & IB_VERBOSE) { + printf("Board: %s\n", evb_board_get_description(params, board)); + } + + return board; +} + +/* + * evb_db_list_boards -- + * Print the list of known boards to the specified output stream. + */ +void +evb_db_list_boards(ib_params *params, FILE *out) +{ + prop_object_iterator_t iter; + prop_dictionary_keysym_t key; + evb_board board; + const char *uboot_pkg; + const char *uboot_path; + + /* + * By default, we only list boards that we have a u-boot + * package installed for, or if we know which package you + * need to install. You get the full monty in verbose mode. + */ + + iter = prop_dictionary_iterator(params->mach_data); + while ((key = prop_object_iterator_next(iter)) != NULL) { + board = prop_dictionary_get_keysym(params->mach_data, key); + assert(board != NULL); + uboot_pkg = evb_board_get_uboot_pkg(params, board); + uboot_path = evb_board_get_uboot_path(params, board); + + if (uboot_pkg == NULL && uboot_path == NULL && + !(params->flags & IB_VERBOSE)) + continue; + + fprintf(out, "%-30s %s\n", + prop_dictionary_keysym_value(key), + evb_board_get_description(params, board)); + + if ((params->flags & IB_VERBOSE) && uboot_path) { + fprintf(out, "\t(u-boot package found at %s)\n", + uboot_path); + } else if ((params->flags & IB_VERBOSE) && uboot_pkg) { + fprintf(out, + "\t(install the sysutils/u-boot-%s package)\n", + uboot_pkg); + } + } + prop_object_iterator_release(iter); +} + +/* + * evb_board_get_description -- + * Return the description for the specified board. + */ +const char * +evb_board_get_description(ib_params *params, evb_board board) +{ + prop_string_t string; + + string = prop_dictionary_get(board, board_description_key); + return prop_string_value(string); +} + +/* + * evb_board_get_uboot_pkg -- + * Return the u-boot package name for the specified board. + */ +const char * +evb_board_get_uboot_pkg(ib_params *params, evb_board board) +{ + prop_string_t string; + + string = prop_dictionary_get(board, board_u_boot_pkg_key); + if (string == NULL) + return NULL; + return prop_string_value(string); +} + +/* + * evb_board_get_uboot_path -- + * Return the u-boot installed package path for the specified board. + */ +const char * +evb_board_get_uboot_path(ib_params *params, evb_board board) +{ + prop_string_t string; + + string = prop_dictionary_get(board, board_u_boot_path_key); + if (string == NULL) + return NULL; + return prop_string_value(string); +} + +/* + * evb_board_get_uboot_install -- + * Return the u-boot install object for the specified board, + * corresponding to the media specified by the user. + */ +evb_ubinstall +evb_board_get_uboot_install(ib_params *params, evb_board board) +{ + evb_ubinstall install; + + install = prop_dictionary_get(board, board_u_boot_install_key); + + if (!(params->flags & IB_MEDIA)) { + if (install == NULL) { + warnx("Must specify media=... for board '%s'", + params->board); + goto list_media; + } + return install; + } + + /* media=... was specified by the user. */ + + if (install) { + warnx("media=... is not a valid option for board '%s'", + params->board); + return NULL; + } + + char install_key[128]; + int n = snprintf(install_key, sizeof(install_key), "%s-%s", + board_u_boot_install_key, params->media); + if (n < 0 || (size_t)n >= sizeof(install_key)) + goto invalid_media; + install = prop_dictionary_get(board, install_key); + if (install != NULL) { + if (prop_object_type(install) == PROP_TYPE_STRING) { + /* + * This is an alias. Fetch the target. We + * have already validated that the target + * exists. + */ + install = prop_dictionary_get(board, + prop_string_value((prop_string_t)install)); + } + return install; + } + invalid_media: + warnx("invalid media specification: '%s'", params->media); + list_media: + fprintf(stderr, "Valid media types:"); + prop_array_t array = evb_board_copy_uboot_media(params, board); + assert(array != NULL); + prop_object_iterator_t iter = prop_array_iterator(array); + prop_string_t string; + while ((string = prop_object_iterator_next(iter)) != NULL) + fprintf(stderr, " %s", prop_string_value(string)); + fprintf(stderr, "\n"); + prop_object_iterator_release(iter); + prop_object_release(array); + + return NULL; +} + +/* + * evb_board_copy_uboot_media -- + * Return the valid media types for the given board as an array + * of strings. + * + * Follows the create rule; caller is responsible for releasing + * the array. + */ +prop_array_t +evb_board_copy_uboot_media(ib_params *params, evb_board board) +{ + prop_array_t array = prop_array_create(); + prop_object_iterator_t iter = prop_dictionary_iterator(board); + prop_string_t string; + prop_dictionary_keysym_t key; + const char *cp; + + assert(array != NULL); + assert(iter != NULL); + + while ((key = prop_object_iterator_next(iter)) != NULL) { + cp = prop_dictionary_keysym_value(key); + if (strcmp(cp, board_u_boot_install_key) == 0 || + strncmp(cp, board_u_boot_install_key, + sizeof(board_u_boot_install_key) - 1) != 0) + continue; + string = prop_string_create_copy(strrchr(cp, '-')+1); + assert(string != NULL); + prop_array_add(array, string); + prop_object_release(string); + } + prop_object_iterator_release(iter); + return array; +} + +/* + * evb_ubinstall_get_steps -- + * Get the install steps for a given install object. + */ +evb_ubsteps +evb_ubinstall_get_steps(ib_params *params, evb_ubinstall install) +{ + return prop_array_iterator(install); +} + +/* + * evb_ubsteps_next_step -- + * Return the next step in the install object. + * + * N.B. The iterator is released upon termination. + */ +evb_ubstep +evb_ubsteps_next_step(ib_params *params, evb_ubsteps steps) +{ + prop_dictionary_t step = prop_object_iterator_next(steps); + + /* If we are out of steps, release the iterator. */ + if (step == NULL) + prop_object_iterator_release(steps); + + return step; +} + +/* + * evb_ubstep_get_file_name -- + * Returns the input file name for the step. + */ +const char * +evb_ubstep_get_file_name(ib_params *params, evb_ubstep step) +{ + prop_string_t string = prop_dictionary_get(step, step_file_name_key); + return prop_string_value(string); +} + +/* + * evb_ubstep_get_file_offset -- + * Returns the input file offset for the step. + */ +uint64_t +evb_ubstep_get_file_offset(ib_params *params, evb_ubstep step) +{ + prop_number_t number = prop_dictionary_get(step, step_file_offset_key); + if (number != NULL) + return prop_number_unsigned_value(number); + return 0; +} + +/* + * evb_ubstep_get_file_size -- + * Returns the size of the input file to copy for this step, or + * zero if the remainder of the file should be copied. + */ +uint64_t +evb_ubstep_get_file_size(ib_params *params, evb_ubstep step) +{ + prop_number_t number = prop_dictionary_get(step, step_file_size_key); + if (number != NULL) + return prop_number_unsigned_value(number); + return 0; +} + +/* + * evb_ubstep_get_image_offset -- + * Returns the offset into the destination image / device to + * copy the input file. + */ +uint64_t +evb_ubstep_get_image_offset(ib_params *params, evb_ubstep step) +{ + prop_number_t number = prop_dictionary_get(step, step_image_offset_key); + if (number != NULL) + return prop_number_unsigned_value(number); + return 0; +} + +/* + * evb_ubstep_get_input_block_size -- + * Returns the input block size to use when reading the boot loader + * file. + */ +uint64_t +evb_ubstep_get_input_block_size(ib_params *params, evb_ubstep step) +{ + prop_number_t number = prop_dictionary_get(step, + step_input_block_size_key); + if (number != NULL) + return prop_number_unsigned_value(number); + return 0; +} + +/* + * evb_ubstep_get_input_pad_size -- + * Returns the input pad size to use when reading the boot loader + * file. + */ +uint64_t +evb_ubstep_get_input_pad_size(ib_params *params, evb_ubstep step) +{ + prop_number_t number = prop_dictionary_get(step, + step_input_pad_size_key); + if (number != NULL) + return prop_number_unsigned_value(number); + return 0; +} + +/* + * evb_ubstep_get_output_size -- + * Returns the total output size that will be written to the + * output device. + */ +uint64_t +evb_ubstep_get_output_size(ib_params *params, evb_ubstep step) +{ + prop_number_t number = prop_dictionary_get(step, step_output_size_key); + if (number != NULL) + return prop_number_unsigned_value(number); + return 0; +} + +/* + * evb_ubstep_get_output_block_size -- + * Returns the block size that must be written to the output device. + */ +uint64_t +evb_ubstep_get_output_block_size(ib_params *params, evb_ubstep step) +{ + prop_number_t number = prop_dictionary_get(step, + step_output_block_size_key); + if (number != NULL) + return prop_number_unsigned_value(number); + return 0; +} + +/* + * evb_ubstep_preserves_partial_block -- + * Returns true if the step preserves a partial block. + */ +bool +evb_ubstep_preserves_partial_block(ib_params *params, evb_ubstep step) +{ + prop_bool_t val = prop_dictionary_get(step, step_preserve_key); + if (val != NULL) + return prop_bool_true(val); + return false; +} + +/* + * evb_uboot_file_path -- + * Build a file path from the u-boot base path in the board object + * and the file name in the step object. + */ +static const char * +evb_uboot_file_path(ib_params *params, evb_board board, evb_ubstep step, + char *buf, size_t bufsize) +{ + const char *base_path = evb_board_get_uboot_path(params, board); + const char *file_name = evb_ubstep_get_file_name(params, step); + + if (base_path == NULL || file_name == NULL) + return NULL; + + return make_path(buf, bufsize, "%s/%s", base_path, file_name); +} + +/* + * evb_uboot_do_step -- + * Given a evb_ubstep, do the deed. + */ +static int +evb_uboot_do_step(ib_params *params, const char *uboot_file, evb_ubstep step) +{ + struct stat sb; + int ifd = -1; + char *blockbuf = NULL; + off_t curoffset; + off_t file_remaining; + bool rv = false; + + uint64_t file_size = evb_ubstep_get_file_size(params, step); + uint64_t file_offset = evb_ubstep_get_file_offset(params, step); + uint64_t image_offset = evb_ubstep_get_image_offset(params, step); + uint64_t output_size = evb_ubstep_get_output_size(params, step); + size_t output_block_size = + (size_t)evb_ubstep_get_output_block_size(params, step); + size_t input_block_size = + (size_t)evb_ubstep_get_input_block_size(params, step); + size_t input_pad_size = + (size_t)evb_ubstep_get_input_pad_size(params, step); + bool preserves_partial_block = + evb_ubstep_preserves_partial_block(params, step); + const char *uboot_file_name = + evb_ubstep_get_file_name(params, step); + + if (input_block_size == 0 && output_block_size == 0) { + if (params->flags & IB_VERBOSE) { + printf("Defaulting input-block-size and " + "output-block-size to sectorsize " + "(%" PRIu32 ")\n", params->sectorsize); + } + input_block_size = output_block_size = params->sectorsize; + } else if (input_block_size != 0 && output_block_size == 0) { + if (params->flags & IB_VERBOSE) { + printf("Defaulting output-block-size to " + "input-block-size (%zu)\n", + input_block_size); + } + output_block_size = input_block_size; + } else if (output_block_size != 0 && input_block_size == 0) { + if (params->flags & IB_VERBOSE) { + printf("Defaulting input-block-size to " + "output-block-size (%zu)\n", + output_block_size); + } + input_block_size = output_block_size; + } + + if (output_block_size % params->sectorsize) { + warnx("output-block-size (%zu) is not a multiple of " + "device sector size (%" PRIu32 ")", + output_block_size, params->sectorsize); + goto out; + } + + if ((input_block_size + input_pad_size) > output_block_size) { + warnx("input-{block+pad}-size (%zu) is larger than " + "output-block-size (%zu)", + input_block_size + input_pad_size, + output_block_size); + goto out; + } + + if (output_block_size % (input_block_size + input_pad_size)) { + warnx("output-block-size (%zu) it not a multiple of " + "input-{block+pad}-size (%zu)", + output_block_size, + input_block_size + input_pad_size); + goto out; + } + + blockbuf = malloc(output_block_size); + if (blockbuf == NULL) + goto out; + + ifd = open(uboot_file, O_RDONLY); + if (ifd < 0) { + warn("open '%s'", uboot_file); + goto out; + } + if (fstat(ifd, &sb) < 0) { + warn("fstat '%s'", uboot_file); + goto out; + } + + if (file_size) + file_remaining = (off_t)file_size; + else + file_remaining = sb.st_size - (off_t)file_offset; + + if (output_size == 0) { + output_size = roundup(file_remaining, output_block_size); + } else if ((uint64_t)file_remaining > output_size) { + warnx("file size (%lld) is larger than output-size (%" PRIu64 + ")", (long long)file_remaining, output_size); + goto out; + } + + if (params->flags & IB_VERBOSE) { + if (file_offset) { + printf("Writing '%s' %lld @ %" PRIu64 + "to '%s' @ %" PRIu64 "\n", + uboot_file_name, (long long)file_remaining, + file_offset, params->filesystem, image_offset); + } else { + printf("Writing '%s' %lld to '%s' @ %" PRIu64 "\n", + uboot_file_name, (long long)file_remaining, + params->filesystem, image_offset); + } + } + + if (lseek(ifd, (off_t)file_offset, SEEK_SET) < 0) { + warn("lseek '%s' @ %" PRIu64, uboot_file, + file_offset); + goto out; + } + + for (curoffset = (off_t)image_offset; + output_size != 0; + curoffset += output_block_size, output_size -= output_block_size) { + + size_t outblock_remaining; + size_t this_inblock; + char *fill; + + /* + * Initialize the output buffer. We're either + * filling it with zeros, or we're preserving + * device contents that we don't overwrite. + */ + memset(blockbuf, 0, output_block_size); + if (preserves_partial_block) { + if (params->flags & IB_VERBOSE) { + printf("(Reading '%s' -- %zu @ %lld)\n", + params->filesystem, + output_block_size, + (long long)curoffset); + } + if (pread(params->fsfd, blockbuf, + output_block_size, curoffset) < 0) { + warn("pread '%s'", params->filesystem); + goto out; + } + } + + /* + * Fill the output buffer with the file contents, + * interleaved with padding as necessary. (If + * there is no file left, we're going to be left + * with padding to cover the output-size.) + */ + for (outblock_remaining = output_block_size, fill = blockbuf; + outblock_remaining != 0; + fill += input_block_size + input_pad_size, + outblock_remaining -= input_block_size + input_pad_size) { + + this_inblock = input_block_size; + if ((off_t)this_inblock > file_remaining) { + this_inblock = file_remaining; + } + + if (this_inblock) { + if (params->flags & IB_VERBOSE) { + printf("(Reading '%s' -- %zu @ %lld)\n", + uboot_file_name, + this_inblock, + (long long)lseek(ifd, 0, + SEEK_CUR)); + } + if (read(ifd, fill, this_inblock) + != (ssize_t)this_inblock) { + warn("read '%s'", uboot_file); + goto out; + } + file_remaining -= this_inblock; + } + } + + if (params->flags & IB_VERBOSE) { + printf("(Writing '%s' -- %zu @ %lld)\n", + params->filesystem, + output_block_size, (long long)curoffset); + } + if (!(params->flags & IB_NOWRITE) && + pwrite(params->fsfd, blockbuf, output_block_size, + curoffset) != (ssize_t)output_block_size) { + warn("pwrite '%s'", params->filesystem); + goto out; + } + } + + /* Success! */ + rv = true; + + out: + if (ifd != -1 && close(ifd) == -1) + warn("close '%s'", uboot_file); + if (blockbuf) + free(blockbuf); + return rv; +} + +int +evb_uboot_setboot(ib_params *params, evb_board board) +{ + char uboot_filebuf[PATH_MAX+1]; + const char *uboot_file; + struct stat sb; + off_t max_offset = 0; + + /* + * If we don't have a u-boot path for this board, it means + * that a u-boot package wasn't found. Prompt the user to + * install it. + */ + if (evb_board_get_uboot_path(params, board) == NULL) { + warnx("No u-boot package found for board '%s'", + params->board); + uboot_file = evb_board_get_uboot_pkg(params, board); + if (uboot_file != NULL) + warnx("Please install the sysutils/u-boot-%s package.", + uboot_file); + return 0; + } + + evb_ubinstall install = evb_board_get_uboot_install(params, board); + evb_ubsteps steps; + evb_ubstep step; + + if (install == NULL) + return 0; + + /* + * First, make sure the files are all there. While we're + * at it, calculate the largest byte offset that we will + * be writing. + */ + steps = evb_ubinstall_get_steps(params, install); + while ((step = evb_ubsteps_next_step(params, steps)) != NULL) { + uint64_t file_offset = evb_ubstep_get_file_offset(params, step); + uint64_t file_size = evb_ubstep_get_file_size(params, step); + uint64_t image_offset = + evb_ubstep_get_image_offset(params, step); + uboot_file = evb_uboot_file_path(params, board, step, + uboot_filebuf, sizeof(uboot_filebuf)); + if (uboot_file == NULL) + return 0; + if (stat(uboot_file, &sb) < 0) { + warn("%s", uboot_file); + return 0; + } + if (!S_ISREG(sb.st_mode)) { + warnx("%s: %s", uboot_file, strerror(EFTYPE)); + return 0; + } + off_t this_max; + if (file_size) + this_max = file_size; + else + this_max = sb.st_size - file_offset; + this_max += image_offset; + if (max_offset < this_max) + max_offset = this_max; + } + + /* + * Ok, we've verified that all of the files are there, and now + * max_offset points to the first byte that's available for a + * partition containing a file system. + */ + + off_t rounded_max_offset = (off_t)(max_offset / params->sectorsize) * + params->sectorsize; + if (rounded_max_offset != max_offset) + rounded_max_offset += params->sectorsize; + + if (params->flags & IB_VERBOSE) { + printf("Max u-boot offset (rounded): %lld (%lld)\n", + (long long)max_offset, (long long)rounded_max_offset); + printf("First free block available for file systems: " + "%lld (0x%llx)\n", + (long long)rounded_max_offset / params->sectorsize, + (long long)rounded_max_offset / params->sectorsize); + } + + /* XXX Check MBR table for overlapping partitions. */ + + /* + * Now write each binary component to the appropriate location + * on disk. + */ + steps = evb_ubinstall_get_steps(params, install); + while ((step = evb_ubsteps_next_step(params, steps)) != NULL) { + uboot_file = evb_uboot_file_path(params, board, step, + uboot_filebuf, sizeof(uboot_filebuf)); + if (uboot_file == NULL) + return 0; + if (!evb_uboot_do_step(params, uboot_file, step)) + return 0; + } + + return 1; +} diff --git a/usr.sbin/installboot/evboards.h b/usr.sbin/installboot/evboards.h new file mode 100644 index 000000000..947e4ef84 --- /dev/null +++ b/usr.sbin/installboot/evboards.h @@ -0,0 +1,69 @@ +/* $NetBSD: evboards.h,v 1.2 2019/09/19 01:25:29 thorpej Exp $ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef installboot_evboards_h_included +#define installboot_evboards_h_included + +#include +#include + +typedef prop_dictionary_t evb_board; +typedef prop_array_t evb_ubinstall; +typedef prop_object_iterator_t evb_ubsteps; +typedef prop_dictionary_t evb_ubstep; + +bool evb_db_load(ib_params *); +evb_board evb_db_get_board(ib_params *); +void evb_db_list_boards(ib_params *, FILE *); + +const char * evb_board_get_description(ib_params *, evb_board); +const char * evb_board_get_uboot_pkg(ib_params *, evb_board); +const char * evb_board_get_uboot_path(ib_params *, evb_board); +evb_ubinstall evb_board_get_uboot_install(ib_params *, evb_board); +prop_array_t evb_board_copy_uboot_media(ib_params *, evb_board); + +evb_ubsteps evb_ubinstall_get_steps(ib_params *, evb_ubinstall); + +evb_ubstep evb_ubsteps_next_step(ib_params *, evb_ubsteps); + +const char * evb_ubstep_get_file_name(ib_params *, evb_ubstep); +uint64_t evb_ubstep_get_file_offset(ib_params *, evb_ubstep); +uint64_t evb_ubstep_get_file_size(ib_params *, evb_ubstep); +uint64_t evb_ubstep_get_image_offset(ib_params *, evb_ubstep); +uint64_t evb_ubstep_get_input_block_size(ib_params *, evb_ubstep); +uint64_t evb_ubstep_get_input_pad_size(ib_params *, evb_ubstep); +uint64_t evb_ubstep_get_output_size(ib_params *, evb_ubstep); +uint64_t evb_ubstep_get_output_block_size(ib_params *, evb_ubstep); +bool evb_ubstep_preserves_partial_block(ib_params *, evb_ubstep); + +int evb_uboot_setboot(ib_params *, evb_board); + +#endif /* installboot_evboards_h_included */ diff --git a/usr.sbin/installboot/installboot_nbsd.8 b/usr.sbin/installboot/installboot.8 similarity index 65% rename from usr.sbin/installboot/installboot_nbsd.8 rename to usr.sbin/installboot/installboot.8 index ec0b6d1cd..bef9d91d4 100644 --- a/usr.sbin/installboot/installboot_nbsd.8 +++ b/usr.sbin/installboot/installboot.8 @@ -1,6 +1,6 @@ -.\" $NetBSD: installboot_nbsd.8,v 1.79 2011/11/03 20:09:18 martin Exp $ +.\" $NetBSD: installboot.8,v 1.101 2021/02/25 03:44:27 rin Exp $ .\" -.\" Copyright (c) 2002-2009 The NetBSD Foundation, Inc. +.\" Copyright (c) 2002-2019 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -27,11 +27,11 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd August 3, 2011 +.Dd February 25, 2021 .Dt INSTALLBOOT 8 .Os .Sh NAME -.Nm installboot_nbsd +.Nm installboot .Nd install disk bootstrap software . .Sh SYNOPSIS @@ -39,6 +39,7 @@ .Op Fl fnv .Op Fl B Ar s2bno .Op Fl b Ar s1bno +.Op Fl m Ar machine .Op Fl o Ar options .Op Fl t Ar fstype .Ar filesystem @@ -47,18 +48,16 @@ .Nm .Fl c .Op Fl fnv +.Op Fl m Ar machine .Op Fl o Ar options .Op Fl t Ar fstype .Ar filesystem .Nm .Fl e .Op Fl fnv +.Op Fl m Ar machine .Op Fl o Ar options .Ar bootstrap -.Nm -.Fl m(aster) -.Ar device -.Ar masterboot . .Sh DESCRIPTION The @@ -105,7 +104,6 @@ Copy the secondary bootstrap (usually or .Pa /usr/mdec/boot ) to the root directory of the target file system. -.Pp . .It Use @@ -132,9 +130,30 @@ single bootstrap file is used. The single bootstrap is installed like the primary bootstrap on other platforms: .Sy next68k . -.Pp .El .Pp +Some platforms, typically embedded system platforms, are umbrella platforms +that support many different individual board types, each with their own +boot loader binary and installation procedure requirements. +On these platforms, it may be necessary to provide specific board type +information to +.Nm . +Information about known boards and their requirements is loaded from a +database at run-time. +Sometimes these platforms also require the use of 3rd-party boot loader +software, such as +.Sy U-boot . +To support these platforms, +.Nm +scans known locations for these 3rd-party boot loader packages for +database overlays that contain additional board-specific boot loader +installation information in a file called +.Sq installboot.plist . +.Pp +The following platforms have this requirement and utilize this database +overlay feature: +.Sy evbarm . +.Pp The options and arguments recognized by .Nm are as follows: @@ -166,6 +185,7 @@ at block number .Ar s1bno instead of the default location for the machine and file system type. .Sy [ alpha , +.Sy i386/amd64 (bootxx_fat16 only) , .Sy pmax , .Sy vax ] . @@ -174,7 +194,7 @@ Clear (remove) any existing bootstrap instead of installing one. . .It Fl e Edit the options of an existing bootstrap. -This can be use to change the options in bootxx_xxxfs files, +This can be used to change the options in bootxx_xxxfs files, raw disk partitions, and the .Pa pxeboot_ia32.bin file. @@ -190,6 +210,40 @@ Forces .Nm to ignore some errors. . +.It Fl m Ar machine +Use +.Ar machine +as the target machine type. +The default machine is determined from +.Xr uname 3 +and then +.Ev MACHINE . +The following machines are currently supported by +.Nm : +.Bd -ragged -offset indent +.Sy alpha , +.Sy amd64 , +.Sy amiga , +.Sy evbarm , +.Sy ews4800mips , +.Sy hp300 , +.Sy hppa , +.Sy i386 , +.Sy landisk , +.Sy macppc , +.Sy news68k , +.Sy newsmips , +.Sy next68k , +.Sy pmax , +.Sy sparc , +.Sy sparc64 , +.Sy sun2 , +.Sy sun3 , +.Sy vax , +.Sy x68k +.Ed +. +. .It Fl n Do not write to .Ar filesystem . @@ -207,7 +261,7 @@ Supported options are (with the machines for they are valid in brackets): .Sy [ alpha ] Recalculate and restore the Alpha checksum. This is the default for -.Nx Ns Tn /alpha . +.Nx Ns /alpha . . .It Sy append .Sy [ alpha , @@ -219,6 +273,15 @@ to the end of .Ar filesystem , which must be a regular file in this case. . +.It Sy board= +.Sy [ evbarm ] +Specify the board type used to determine the correct boot loader image +and installation procedure. +If omitted, +.Nm +will attempt to guess the board type based on system information if run +natively. +. .It Sy bootconf .Sy [ amd64 , .Sy i386 ] @@ -226,27 +289,40 @@ which must be a regular file in this case. .Dq boot.cfg file. . -.It Sy command=\*[Lt]boot command\*[Gt] +.It Sy command= .Sy [ amiga ] Modify the default boot command line. . -.It Sy console=\*[Lt]console name\*[Gt] +.It Sy console= .Sy [ amd64 , .Sy i386 ] -Set the console device, \*[Lt]console name\*[Gt] must be one of: -pc, com0, com1, com2, com3, com0kbd, com1kbd, com2kbd or com3kbd. +Set the console device, must be one of: +pc, com0, com1, com2, com3, com0kbd, com1kbd, com2kbd, com3kbd or auto. . -.It Sy ioaddr=\*[Lt]ioaddr\*[Gt] +.It Sy dtb=/path/to/dtb/file +.Sy [ evbarm ] +Attempt to determine the board type from information in the device tree +blob file at +.Pa /path/to/dtb/file . +If both +.Sy board +and +.Sy dtb +options are specified, +.Sy board +takes precendence. +. +.It Sy ioaddr= .Sy [ amd64 , .Sy i386 ] Set the IO address to be used for the console serial port. Defaults to the IO address used by the system BIOS for the specified port. . -.It Sy keymap=\*[Lt]keymap\*[Gt] +.It Sy keymap= .Sy [ amd64 , .Sy i386 ] Set a boot time keyboard translation map. -Each character in \*[Lt]keymap\*[Gt] will be replaced by the one following it. +Each character in will be replaced by the one following it. For example, an argument of .Dq zyz would swap the lowercase letters @@ -254,12 +330,22 @@ would swap the lowercase letters and .Sq z . . +.It Sy media= +.Sy [ evbarm ] +Some boards require a different boot loader binary and/or installation +procedure depending on what type of media will be used to boot the system. +For such boards, this option is required, and omitting it will display a +usage message that lists the valid media types for the board. +For boards that do not require special media handling, this option is +not allowed. +Common values: sdmmc, emmc, usb. +. .It Sy modules .Sy [ amd64 , .Sy i386 ] (Don't) load kernel modules. . -.It Sy password=\*[Lt]password\*[Gt] +.It Sy password= .Sy [ amd64 , .Sy i386 ] Set the password which must be entered before the boot menu can be accessed. @@ -269,7 +355,7 @@ Set the password which must be entered before the boot menu can be accessed. .Sy i386 ] Reset the video before booting. . -.It Sy speed=\*[Lt]baud rate\*[Gt] +.It Sy speed= .Sy [ amd64 , .Sy i386 ] Set the baud rate for the serial console. @@ -281,14 +367,14 @@ BIOS) will be used. .Sy pmax , .Sy vax ] Recalculate and restore the Sun and -.Nx Ns Tn /sparc +.Nx Ns /sparc compatible checksum. .Em Note : The existing -.Nx Ns Tn /sparc +.Nx Ns /sparc disklabel should use no more than 4 partitions. . -.It Sy timeout=\*[Lt]seconds\*[Gt] +.It Sy timeout= .Sy [ amd64 , .Sy i386 ] Set the timeout before the automatic boot begins to the given number of seconds. @@ -379,7 +465,7 @@ These are: .El .Pp .Nm -exits 0 on success, and \*[Gt]0 if an error occurs. +exits 0 on success, and >0 if an error occurs. . .Sh ENVIRONMENT .Nm @@ -387,6 +473,21 @@ uses the following environment variables: . .Bl -tag -width "MACHINE" . +.It Ev INSTALLBOOT_UBOOT_PATHS +A colon-separated list of search paths to scan for +.Sy U-boot +packages with +.Nm installboot +installation overlays. +If multiple overlays are found, overlays from paths closer to the front +of the list take precedence. +If not specified, the default path is +.Pa /usr/pkg/share/u-boot . +This environment variable is only used on platforms that support +using +.Sy U-boot : +.Sy evbarm . +. .It Ev MACHINE Default value for .Ar machine , @@ -399,7 +500,6 @@ overriding the result from Most .Nx ports will contain variations of the following files: -.Pp .Bl -tag -width /usr/mdec/bootxx_ustarfs . .It Pa /usr/mdec/bootxx_ Ns Sy FSTYPE @@ -409,8 +509,7 @@ Installed into the bootstrap area of the file system by .Nm . . .It Pa /usr/mdec/bootxx_fat16 -Primary bootstrap for -.Tn MS-DOS +Primary bootstrap for MS-DOS .Sy FAT16 file systems. This differs from @@ -421,14 +520,21 @@ any It also uses the information in the .Ql Boot Parameter Block to get the media and filesytem properties. +The +.Ql hidden sectors +field of the BPB must be the offset of the partition in the disk. +This can be set using the +.Fl b Ar s1bno +option. . .It Pa /usr/mdec/bootxx_ffsv1 Primary bootstrap for .Sy FFSv1 file systems -(the "traditional" -.Nx -file system). +(the +.Ql traditional +file system prior to +.Nx 6.0 ) . Use .Xr dumpfs 8 to confirm the file system format is @@ -437,7 +543,8 @@ to confirm the file system format is .It Pa /usr/mdec/bootxx_ffsv2 Primary bootstrap for .Sy FFSv2 -file systems. +file systems (the default file system for some platforms as of +.Nx 6.0 ) . Use .Xr dumpfs 8 to confirm the file system format is @@ -455,8 +562,7 @@ file systems (the default LFS version). . .It Pa /usr/mdec/bootxx_msdos -Primary bootstrap for -.Tn MS-DOS +Primary bootstrap for MS-DOS .Sy FAT file systems. . @@ -489,50 +595,126 @@ is not found. . .El . -.Ss Nx Ns Tn /macppc files +.Ss Nx Ns /evbarm files +The +.Nx Ns /evbarm +platform covers a wide variety of board types, many of which use +.Sy U-boot . +Running +.Nm +with no options will display a list of known boards. +Using the verbose option will also display information about which +.Sy U-boot +package needs to be installed to support that board, and if the required +.Sy U-boot +package is installed, the path at which it is located. +.Bl -tag -width /usr/pkg/share/u-boot +.It Pa /usr/pkg/share/u-boot +The default location scanned for +.Sy U-boot +packages with installation overlays. +.It Pa /usr/share/installboot/evbarm/boards.plist +Base board database, used to provide information about which +.Sy U-boot +package is required for a given board. +.El +. +.Ss Nx Ns /evbmips files +. +The +.Nx Ns /evbmips +bootstrap files currently only apply to the SBMIPS kernels for the +SiByte/Broadcom BCM1250 and BCM1480 CPUs. +.Bl -tag -width /usr/mdec/sbmips/bootxx_cd9660 +. +.It Pa /usr/mdec/sbmips/boot +.Nx Ns /evbmips +secondary bootstrap for +.Sy FFSv1 , +.Sy FFSv2 , +.Sy LFSv1 , +and +.Sy LFSv2 . +.It Pa /usr/mdec/sbmips/bootxx_cd9660 +SBMIPS primary bootstrap for ISO 9660 file system. +.It Pa /usr/mdec/sbmips/bootxx_ffs +SBMIPS primary bootstrap for FFSv1 and FFSv2 file system. +.It Pa /usr/mdec/sbmips/bootxx_lfs +SBMIPS primary bootstrap for LFSv1 and LFSv2 file system. +.It Pa /usr/mdec/sbmips/netboot +SBMIPS primary bootstrap for network root. +.Pp +Note that +.Nm +does not currently support evbmips directly. +. +.El +. +.Ss Nx Ns /hppa files +. +.Bl -tag -width /usr/mdec/bootxx_ustarfs +. +.It Pa /usr/mdec/xxboot +.Nx Ns /hppa +primary bootstrap for +.Sy FFSv1 , +.Sy FFSv2 , +.Sy LFSv1 , +and +.Sy LFSv2 . +.It Pa /usr/mdec/cdboot +.Nx Ns /hppa +primary bootstrap for ISO 9660 file system. +.It Pa /usr/mdec/sdboot +Synonym for +.Pa /usr/mdec/xxboot +. +.El +. +.Ss Nx Ns /macppc files . .Bl -tag -width /usr/mdec/bootxx_ustarfs . .It Pa /usr/mdec/bootxx -.Nx Ns Tn /macppc +.Nx Ns /macppc primary bootstrap. . .It Pa /usr/mdec/ofwboot -.Nx Ns Tn /macppc +.Nx Ns /macppc secondary bootstrap. . .It Pa /ofwboot Installed copy of -.Nx Ns Tn /macppc +.Nx Ns /macppc secondary bootstrap. . .El . -.Ss Nx Ns Tn /next68k files +.Ss Nx Ns /next68k files . .Bl -tag -width /usr/mdec/bootxx_ustarfs . .It Pa /usr/mdec/boot -.Nx Ns Tn /next68k +.Nx Ns /next68k bootstrap. . .El . -.Ss Nx Ns Tn /sparc64 files +.Ss Nx Ns /sparc64 files . .Bl -tag -width /usr/mdec/bootxx_ustarfs . .It Pa /usr/mdec/bootblk -.Nx Ns Tn /sparc64 +.Nx Ns /sparc64 primary bootstrap. . .It Pa /usr/mdec/ofwboot -.Nx Ns Tn /sparc64 +.Nx Ns /sparc64 secondary bootstrap. . .It Pa /ofwboot Installed copy of -.Nx Ns Tn /sparc64 +.Nx Ns /sparc64 secondary bootstrap. . .El @@ -542,7 +724,7 @@ secondary bootstrap. .Ss common Verbosely install the Berkeley Fast File System primary bootstrap on to disk .Sq sd0 : -.Dl Ic installboot_nbsd -v /dev/rsd0c /usr/mdec/bootxx_ffs +.Dl Ic installboot -v /dev/rsd0c /usr/mdec/bootxx_ffs Note: the .Dq whole disk partition (c on some ports, d on others) is used here, since the a partition @@ -554,37 +736,85 @@ would not be able to access it. .Pp Remove the primary bootstrap from disk .Sq sd1 : -.Dl Ic installboot_nbsd -c /dev/rsd1c +.Dl Ic installboot -c /dev/rsd1c . -.Ss Nx Ns Tn /amiga +.Ss Nx Ns /amiga Modify the command line to change the default from "netbsd -ASn2" to "netbsd -S": -.Dl Ic installboot_nbsd -m amiga -o command="netbsd -S" /dev/rsd0a /usr/mdec/bootxx_ffs +.Dl Ic installboot -m amiga -o command="netbsd -S" /dev/rsd0a /usr/mdec/bootxx_ffsv1 . -.Ss Nx Ns Tn /ews4800mips +.Ss Nx Ns /evbarm +Install the +.Sy U-boot +boot loader for a Pinebook into an image that will be written to +an SDMMC card: +.Dl Ic installboot -m evbarm -o board=pine64,pinebook arm64.img +.Pp +Install / update the +.Sy U-boot +boot loader for the current running system on the eMMC device +.Sq ld0 +and display verbose information about the procedure: +.Dl Ic installboot -v /dev/rld0c +.Pp +Install a specific +.Sy U-boot +package for a BeagleBone Black into an image that will be written +to an SDMMC card: +.Dl Ic installboot -m evbarm -o board=ti,am335x-bone-black armv7.img \ + /path/to/experimental/u-boot/package +. +.Ss Nx Ns /ews4800mips Install the System V Boot File System primary bootstrap on to disk .Sq sd0 , with the secondary bootstrap .Sq Pa /boot already present in the SysVBFS partition on the disk: -.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx_bfs -. -.Ss Nx Ns Tn /i386 and Nx Ns Tn /amd64 -Install new boot blocks on an existing mounted root file system on +.Dl Ic installboot /dev/rsd0p /usr/mdec/bootxx_bfs +.Bd -ragged -offset indent-two -compact +.Em Note : +On +.Nx Ns /ews4800mips +the p partition is the +.Dq whole disk +(i.e., raw) partition. +.Ed +.Ss Nx Ns /i386 and Nx Ns /amd64 +Install new boot blocks on an existing +.Sy FFSv2 +mounted root file system on .Sq wd0 , -setting the timeout to five seconds, after copying a new secondary -bootstrap: +setting the timeout to five seconds, after installing an MBR bootcode and +copying a new secondary bootstrap: +.Dl Ic fdisk -c /usr/mdec/mbr /dev/rwd0d +.Bd -ragged -offset indent-two -compact +.Em Note : +See +.Xr fdisk 8 +and +.Xr x86/mbr 8 +for more details. +.Ed .Dl Ic cp /usr/mdec/boot /boot -.Dl Ic installboot_nbsd -v -o timeout=5 /dev/rwd0a /usr/mdec/bootxx_ffsv1 -. +.Dl Ic installboot -v -o timeout=5 /dev/rwd0a /usr/mdec/bootxx_ffsv2 +.Bd -ragged -offset indent-two -compact +.Em Note : +Pre +.Nx 6.0 +systems used +.Sy FFSv1 +file systems on these platforms; double check with +.Xr dumpfs 8 +to be sure to use the correct secondary bootstrap. +.Ed .Pp -Create a bootable CD-ROM with an ISO9660 +Create a bootable CD-ROM with an ISO 9660 file system for an i386 system with a serial console: .Dl Ic mkdir cdrom .Dl Ic cp sys/arch/i386/compile/mykernel/netbsd cdrom/netbsd .Dl Ic cp /usr/mdec/boot cdrom/boot .Dl Ic cp /usr/mdec/bootxx_cd9660 bootxx -.Dl Ic installboot_nbsd -o console=com0,speed=19200 -m i386 -e bootxx +.Dl Ic installboot -o console=com0,speed=19200 -m i386 -e bootxx .Dl Ic makefs -t cd9660 -o 'bootimage=i386;bootxx,no-emul-boot' boot.iso \ cdrom . @@ -602,9 +832,9 @@ which is not a problem for a floppy disk. .Ed .Dl Ic mount /dev/fd0a /mnt .Dl Ic cp /usr/mdec/boot /mnt/boot -.Dl Ic gzip -9 \*[Lt] sys/arch/i386/compile/mykernel/netbsd \*[Gt] /mnt/netbsd.gz +.Dl Ic gzip -9 < sys/arch/i386/compile/mykernel/netbsd > /mnt/netbsd.gz .Dl Ic umount /mnt -.Dl Ic installboot_nbsd -v /dev/rfd0a /usr/mdec/bootxx_ffsv1 +.Dl Ic installboot -v /dev/rfd0a /usr/mdec/bootxx_ffsv1 . .Pp Create a bootable FAT file system on @@ -632,7 +862,7 @@ changed to this value. .Dl Ic cp /usr/mdec/boot /mnt/boot .Dl Ic cp path/to/kernel /mnt/netbsd .Dl Ic umount /mnt -.Dl Ic installboot_nbsd -t raw /dev/rwd1a /usr/mdec/bootxx_msdos +.Dl Ic installboot -t raw /dev/rwd1a /usr/mdec/bootxx_msdos .Pp Make the existing FAT16 filesystem on .Sq sd0e @@ -643,7 +873,7 @@ sectors and that the manufacturer correctly initialised the file system. .Dl Ic cp /usr/mdec/boot /mnt/boot .Dl Ic cp path/to/kernel /mnt/netbsd .Dl Ic umount /mnt -.Dl Ic installboot_nbsd /dev/rsd0e /usr/mdec/bootxx_fat16 +.Dl Ic installboot /dev/rsd0e /usr/mdec/bootxx_fat16 It may also be necessary to use .Nm fdisk to make the device itself bootable. @@ -651,8 +881,8 @@ to make the device itself bootable. .Pp Switch the existing installed bootstrap to use a serial console without reinstalling or altering other options such as timeout. -.Dl Ic installboot_nbsd -e -o console=com0 /dev/rwd0a -.Ss Nx Ns Tn /macppc +.Dl Ic installboot -e -o console=com0 /dev/rwd0a +.Ss Nx Ns /macppc Note the .Nm utility is only required for macppc machines with OpenFirmware version 2 @@ -662,10 +892,10 @@ map. .Pp Install the Berkeley Fast File System primary bootstrap on to disk .Sq wd0 : -.Dl Ic installboot_nbsd /dev/rwd0c /usr/mdec/bootxx /ofwboot +.Dl Ic installboot /dev/rwd0c /usr/mdec/bootxx /ofwboot .Pp The secondary -.Nx Ns Tn /macppc +.Nx Ns /macppc bootstrap is located in .Pa /usr/mdec/ofwboot . .Pp @@ -674,23 +904,22 @@ The primary bootstrap requires the raw for the secondary bootstrap, not .Pa ofwboot.xcf , which is used for the OpenFirmware to load kernels. -.Ss Nx Ns Tn /next68k +.Ss Nx Ns /next68k Install the bootstrap on to disk .Sq sd0 : -.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/boot -.Pp +.Dl Ic installboot /dev/rsd0c /usr/mdec/boot . -.Ss Nx Ns Tn /pmax +.Ss Nx Ns /pmax Install the Berkeley Fast File System primary bootstrap on to disk .Sq sd0 : -.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx_ffs +.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx_ffs .Pp -.Nx Ns Tn /pmax +.Nx Ns /pmax requires that this file system starts at block 0 of the disk. .Pp Install the ISO 9660 primary bootstrap in the file .Pa /tmp/cd-image : -.Dl Ic installboot_nbsd -m pmax /tmp/cd-image /usr/mdec/bootxx_cd9660 +.Dl Ic installboot -m pmax /tmp/cd-image /usr/mdec/bootxx_cd9660 .Pp Make an ISO 9660 filesystem in the file .Pa /tmp/cd-image @@ -704,33 +933,33 @@ and the secondary bootstrap .Dl ... .Dl 48 51 iso-source-dir/bootxx_cd9660 .Dl ... -.Dl Ic installboot_nbsd -b `expr 48 \e* 4` /tmp/cd-image /usr/mdec/bootxx_cd9660 +.Dl Ic installboot -b `expr 48 \e* 4` /tmp/cd-image /usr/mdec/bootxx_cd9660 . -.Ss Nx Ns Tn /sparc +.Ss Nx Ns /sparc Install the Berkeley Fast File System primary bootstrap on to disk .Sq sd0 , with the secondary bootstrap .Sq Pa /boot already present: -.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx /boot +.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx /boot . -.Ss Nx Ns Tn /sparc64 +.Ss Nx Ns /sparc64 Install the primary bootstrap on to disk .Sq sd0 : -.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootblk +.Dl Ic installboot /dev/rsd0c /usr/mdec/bootblk .Pp The secondary -.Nx Ns Tn /sparc64 +.Nx Ns /sparc64 bootstrap is located in .Pa /usr/mdec/ofwboot . . -.Ss Nx Ns Tn /sun2 and Nx Ns Tn /sun3 +.Ss Nx Ns /sun2 and Nx Ns /sun3 Install the Berkeley Fast File System primary bootstrap on to disk .Sq sd0 , with the secondary bootstrap .Sq Pa /boot already present: -.Dl Ic installboot_nbsd /dev/rsd0c /usr/mdec/bootxx /boot +.Dl Ic installboot /dev/rsd0c /usr/mdec/bootxx /boot . .Sh SEE ALSO .Xr uname 3 , @@ -738,7 +967,8 @@ already present: .Xr disklabel 8 , .Xr dumpfs 8 , .Xr fdisk 8 , -.Xr pxeboot 8 +.Xr x86/mbr 8 , +.Xr x86/pxeboot 8 . .Sh HISTORY This implementation of @@ -747,25 +977,40 @@ appeared in .Nx 1.6 . . .Sh AUTHORS +.An -nosplit The machine independent portion of this implementation of .Nm -was written by Luke Mewburn. +was written by +.An Luke Mewburn . The following people contributed to the various machine dependent back-ends: -Simon Burge (pmax), -Chris Demetriou (alpha), -Matthew Fredette (sun2, sun3), -Matthew Green (sparc64), -Ross Harvey (alpha), -Michael Hitch (amiga), -Paul Kranenburg (sparc), -David Laight (i386), -Christian Limpach (next68k), -Luke Mewburn (macppc), -Matt Thomas (vax), -Izumi Tsutsui (news68k, newsmips), +.An Simon Burge +(pmax), +.An Chris Demetriou +(alpha), +.An Matthew Fredette +(sun2, sun3), +.An Matthew Green +(sparc64), +.An Ross Harvey +(alpha), +.An Michael Hitch +(amiga), +.An Paul Kranenburg +(sparc), +.An David Laight +(i386), +.An Christian Limpach +(next68k), +.An Luke Mewburn +(macppc), +.An Matt Thomas +(vax), +.An Izumi Tsutsui +(news68k, newsmips), and -UCHIYAMA Yasushi (ews4800mips). +.An UCHIYAMA Yasushi +(ews4800mips). . .Sh BUGS There are not currently primary bootstraps to support all file systems @@ -784,9 +1029,9 @@ In this case, the .Fl t Ar raid option must be provided. . -.Ss Nx Ns Tn /alpha +.Ss Nx Ns /alpha The -.Nx Ns Tn /alpha +.Nx Ns /alpha primary bootstrap program can only load the secondary bootstrap program from file systems starting at the beginning (block 0) of disks. Similarly, the secondary bootstrap program can only load kernels from @@ -796,11 +1041,11 @@ The size of primary bootstrap programs is restricted to 7.5KB, even though some file systems (e.g., ISO 9660) are able to accommodate larger ones. . -.Ss Nx Ns Tn /hp300 +.Ss Nx Ns /hp300 The disk must have a boot partition large enough to hold the bootstrap code. Currently the primary bootstrap must be a LIF format file. . -.Ss Nx Ns Tn /i386 and Nx Ns Tn /amd64 +.Ss Nx Ns /i386 and Nx Ns /amd64 The bootstrap must be installed in the .Nx partition that starts at the beginning of the mbr partition. @@ -814,7 +1059,7 @@ The size of primary bootstrap programs is restricted to 8KB, even though some file systems (e.g., ISO 9660) are able to accommodate larger ones. . -.Ss Nx Ns Tn /macppc +.Ss Nx Ns /macppc Due to restrictions in .Nm and the secondary bootstrap implementation, file systems where kernels exist @@ -826,17 +1071,17 @@ doesn't recognize an existing Apple partition map on the disk and always writes a faked map to make disks bootable. .Pp The -.Nx Ns Tn /macppc +.Nx Ns /macppc bootstrap program can't load kernels from .Sy FFSv2 partitions. -.Ss Nx Ns Tn /next68k +.Ss Nx Ns /next68k The size of bootstrap programs is restricted to the free space before the file system at the beginning of the disk minus 8KB. . -.Ss Nx Ns Tn /pmax +.Ss Nx Ns /pmax The -.Nx Ns Tn /pmax +.Nx Ns /pmax secondary bootstrap program can only load kernels from file systems starting at the beginning of disks. .Pp @@ -844,17 +1089,17 @@ The size of primary bootstrap programs is restricted to 7.5KB, even though some file systems (e.g., ISO 9660) are able to accommodate larger ones. . -.Ss Nx Ns Tn /sun2 and Nx Ns Tn /sun3 +.Ss Nx Ns /sun2 and Nx Ns /sun3 The -.Nx Ns Tn /sun2 +.Nx Ns /sun2 and -.Nx Ns Tn /sun3 +.Nx Ns /sun3 secondary bootstrap program can only load kernels from file systems starting at the beginning of disks. . -.Ss Nx Ns Tn /vax +.Ss Nx Ns /vax The -.Nx Ns Tn /vax +.Nx Ns /vax secondary bootstrap program can only load kernels from file systems starting at the beginning of disks. .Pp diff --git a/usr.sbin/installboot/installboot.c b/usr.sbin/installboot/installboot.c index 76b114f99..734b0c627 100644 --- a/usr.sbin/installboot/installboot.c +++ b/usr.sbin/installboot/installboot.c @@ -1,4 +1,4 @@ -/* $NetBSD: installboot.c,v 1.39 2015/07/25 10:37:22 mlelstv Exp $ */ +/* $NetBSD: installboot.c,v 1.40 2019/05/07 05:02:42 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: installboot.c,v 1.39 2015/07/25 10:37:22 mlelstv Exp $"); +__RCSID("$NetBSD: installboot.c,v 1.40 2019/05/07 05:02:42 thorpej Exp $"); #endif /* !__lint */ #include @@ -56,6 +56,7 @@ __RCSID("$NetBSD: installboot.c,v 1.39 2015/07/25 10:37:22 mlelstv Exp $"); #endif #include "installboot.h" +#include "evboards.h" static void getmachine(ib_params *, const char *, const char *); static void getfstype(ib_params *, const char *, const char *); @@ -92,6 +93,9 @@ const struct option { { "timeout", IB_TIMEOUT, OPT_INT, OFFSET(timeout) }, { "modules", IB_MODULES, OPT_BOOL, 0 }, { "bootconf", IB_BOOTCONF, OPT_BOOL, 0 }, + { "board", IB_BOARD, OPT_STRING, OFFSET(board) }, + { "dtb", IB_DTB, OPT_STRING, OFFSET(dtb) }, + { "media", IB_MEDIA, OPT_WORD, OFFSET(media) }, { .name = NULL }, }; #undef OFFSET @@ -302,16 +306,32 @@ main(int argc, char *argv[]) } } + assert(params->machine != NULL); + if (argc >= 2) { if ((params->s1fd = open(argv[1], O_RDONLY, 0600)) == -1) err(1, "Opening primary bootstrap `%s'", argv[1]); if (fstat(params->s1fd, ¶ms->s1stat) == -1) err(1, "Examining primary bootstrap `%s'", argv[1]); - if (!S_ISREG(params->s1stat.st_mode)) - errx(1, "`%s' must be a regular file", argv[1]); + if (!S_ISREG(params->s1stat.st_mode)) { + /* + * If the platform uses u-boot, then the stage1 + * spec might be the directory where the u-boot + * binaries for the system are located. + */ + if (params->machine->mach_flags & MF_UBOOT) { + if (!S_ISDIR(params->s1stat.st_mode)) { + errx(1, "`%s' must be a regular file " + "or a directory", argv[1]); + } + (void) close(params->s1fd); + params->s1fd = -1; + } else { + errx(1, "`%s' must be a regular file", argv[1]); + } + } params->stage1 = argv[1]; } - assert(params->machine != NULL); if (params->flags & IB_VERBOSE) { printf("File system: %s\n", params->filesystem); @@ -321,9 +341,11 @@ main(int argc, char *argv[]) params->fstype->name, params->fstype->blocksize, params->fstype->needswap); if (!(params->flags & IB_EDIT)) - printf("Primary bootstrap: %s\n", + printf("Primary bootstrap: %s%s\n", (params->flags & IB_CLEAR) ? "(to be cleared)" - : params->stage1 ? params->stage1 : "(none)" ); + : params->stage1 ? params->stage1 : "(none)", + S_ISDIR(params->s1stat.st_mode) ? " (directory)" + : ""); if (params->stage2 != NULL) printf("Secondary bootstrap: %s\n", params->stage2); } @@ -335,9 +357,18 @@ main(int argc, char *argv[]) op = "Clear"; rv = params->machine->clearboot(params); } else { - if (argc < 2) - errx(EXIT_FAILURE, "Please specify the primary " - "bootstrap file"); + if (argc < 2) { + /* + * If the platform uses u-boot, then the stage1 spec is + * optional iff they specified a board (because we can + * infer a default location for u-boot binaries if the + * board type is given). + */ + if (!(params->machine->mach_flags & MF_UBOOT)) { + errx(EXIT_FAILURE, + "Please specify the primary bootstrap file"); + } + } op = "Set"; rv = params->machine->setboot(params); } @@ -354,7 +385,7 @@ main(int argc, char *argv[]) } if (close(params->fsfd) == -1) err(1, "Closing file system `%s'", params->filesystem); - if (argc == 2) + if (params->s1fd != -1) if (close(params->s1fd) == -1) err(1, "Closing primary bootstrap `%s'", params->stage1); @@ -607,5 +638,8 @@ usage(void) machine_usage(); fstype_usage(); options_usage(); + if (installboot_params.machine != NULL && + installboot_params.machine->usage != NULL) + installboot_params.machine->usage(&installboot_params); exit(1); } diff --git a/usr.sbin/installboot/installboot.h b/usr.sbin/installboot/installboot.h index fdcc7fc98..62fdf1153 100644 --- a/usr.sbin/installboot/installboot.h +++ b/usr.sbin/installboot/installboot.h @@ -1,4 +1,4 @@ -/* $NetBSD: installboot.h,v 1.39 2014/02/24 07:23:44 skrll Exp $ */ +/* $NetBSD: installboot.h,v 1.42 2020/06/21 17:17:02 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -67,8 +67,19 @@ typedef enum { IB_CONSADDR = 1<<20, /* i386 console io address */ IB_MODULES = 1<<21, /* i386: load modules */ IB_BOOTCONF = 1<<22, /* i386: read boot.conf */ + + IB_BOARD = 1<<23, /* evb*: board specification */ + IB_DTB= 1<<24, /* evb*: device tree blob */ + + /* IB_MEDIA is required for some evb*, but not all. */ + IB_MEDIA = 1<<25, /* evb*: boot media type */ } ib_flags; +typedef enum { + + MF_UBOOT = 1<<0, /* platform (maybe) uses u-boot */ +} m_flags; + typedef struct { ib_flags flags; /* flags (see above) */ struct ib_mach *machine; /* machine details (see below) */ @@ -91,6 +102,12 @@ typedef struct { const char *password; /* boot password */ int timeout; /* interactive boot timeout */ const char *keymap; /* keyboard translations */ + const char *board; /* board specification */ + const char *dtb; /* dtb specification */ + const char *media; /* boot media type */ + + /* temporary working data */ + void *mach_data; /* platform-specific data */ } ib_params; typedef struct { @@ -103,7 +120,9 @@ struct ib_mach { int (*setboot) (ib_params *); int (*clearboot) (ib_params *); int (*editboot) (ib_params *); + void (*usage) (ib_params *); ib_flags valid_flags; + m_flags mach_flags; }; struct ib_fs { @@ -166,14 +185,17 @@ void install_master(const char *device, char *masterboot, char **guide); int isoption(const char *option, const char *test); /* minixfs3.c */ -int minixfs3_is_minix_partition(ib_params *params); -int minixfs3_has_bootblock_space(ib_params *params); - +int minixfs3_is_minix_partition(ib_params *params); +int minixfs3_has_bootblock_space(ib_params *params); /* machines.c */ +#if !defined(__minix) extern struct ib_mach ib_mach_alpha; extern struct ib_mach ib_mach_amd64; extern struct ib_mach ib_mach_amiga; +extern struct ib_mach ib_mach_emips; +extern struct ib_mach ib_mach_evbarm; +extern struct ib_mach ib_mach_evbmips; extern struct ib_mach ib_mach_ews4800mips; extern struct ib_mach ib_mach_hp300; extern struct ib_mach ib_mach_hppa; @@ -190,5 +212,9 @@ extern struct ib_mach ib_mach_sun2; extern struct ib_mach ib_mach_sun3; extern struct ib_mach ib_mach_vax; extern struct ib_mach ib_mach_x68k; +#else +extern struct ib_mach ib_mach_amd64; +extern struct ib_mach ib_mach_i386; +#endif /* !defined(__minix) */ #endif /* _INSTALLBOOT_H */ diff --git a/usr.sbin/installboot/machines.c b/usr.sbin/installboot/machines.c index 357652b83..bca78e4d9 100644 --- a/usr.sbin/installboot/machines.c +++ b/usr.sbin/installboot/machines.c @@ -1,4 +1,4 @@ -/* $NetBSD: machines.c,v 1.39 2014/02/24 07:23:44 skrll Exp $ */ +/* $NetBSD: machines.c,v 1.43 2020/06/21 17:17:02 thorpej Exp $ */ /*- * Copyright (c) 2002-2005 The NetBSD Foundation, Inc. @@ -35,60 +35,40 @@ #include #if !defined(__lint) -__RCSID("$NetBSD: machines.c,v 1.39 2014/02/24 07:23:44 skrll Exp $"); +__RCSID("$NetBSD: machines.c,v 1.43 2020/06/21 17:17:02 thorpej Exp $"); #endif /* !__lint */ #include #include "installboot.h" -/* - * Define these here so they end up as zero-filled bss if installboot - * isn't built with all the architectures defined. - * A lot simpler that conditionally including the definitions themselves. - */ -struct ib_mach - ib_mach_alpha, - ib_mach_amd64, - ib_mach_amiga, - ib_mach_emips, - ib_mach_ews4800mips, - ib_mach_hp300, - ib_mach_hppa, - ib_mach_i386, - ib_mach_landisk, - ib_mach_macppc, - ib_mach_news68k, - ib_mach_newsmips, - ib_mach_next68k, - ib_mach_pmax, - ib_mach_sparc, - ib_mach_sparc64, - ib_mach_sun2, - ib_mach_sun3, - ib_mach_vax, - ib_mach_x68k; - struct ib_mach * const machines[] = { - &ib_mach_alpha, +#ifdef SINGLE_ARCH + &SINGLE_ARCH, +#else +//__MINIX +// &ib_mach_alpha, &ib_mach_amd64, - &ib_mach_amiga, - &ib_mach_emips, - &ib_mach_ews4800mips, - &ib_mach_hp300, - &ib_mach_hppa, +// &ib_mach_amiga, +// &ib_mach_emips, +// &ib_mach_evbarm, +// &ib_mach_evbmips, +// &ib_mach_ews4800mips, +// &ib_mach_hp300, +// &ib_mach_hppa, &ib_mach_i386, - &ib_mach_landisk, - &ib_mach_macppc, - &ib_mach_news68k, - &ib_mach_newsmips, - &ib_mach_next68k, - &ib_mach_pmax, - &ib_mach_sparc, - &ib_mach_sparc64, - &ib_mach_sun2, - &ib_mach_sun3, - &ib_mach_vax, - &ib_mach_x68k, +// &ib_mach_landisk, +// &ib_mach_macppc, +// &ib_mach_news68k, +// &ib_mach_newsmips, +// &ib_mach_next68k, +// &ib_mach_pmax, +// &ib_mach_sparc, +// &ib_mach_sparc64, +// &ib_mach_sun2, +// &ib_mach_sun3, +// &ib_mach_vax, +// &ib_mach_x68k, +#endif NULL };