NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: port-hp300/54455 (hp300 ISO should be encapsulated in LIF to be bootable)



I've managed to get working hp300 installcd.

I wrote:
> Synopsis: hp300 ISO should be encapsulated in LIF to be bootable
 :
> - concept confirmed (using a different approach from OpenBSD/hp300)
>   https://www.youtube.com/watch?v=seHEeoup6P0
>  - prepare a new uboot binary without LIF volume but only LIF file header
>    (four bytes entry address and four bytes file size at the top)

This is not necessary, we can just add size of LIF volume and directory
(8192 bytes) to a block number in LIF directory entry as extra offset.

>  - put the uboot binary for CD on in a boot ISO by makefs(8)
>   - in ISO9660 all blocks for each file are contiguously allocated
>     so we can directly specify it in the LIF directory entry
>     without a boot partition

See attached diffs below.

>  - prepare LIF volume and directory entry in the boot ISO
>  - write a block number of the uboot in the ISO image to
>    a directory entry in the LIF header

It turns out current installboot(8) already has these support.

> - needs to implement host tools to prepare necessary data in a boot ISO
>  - hp300/stand/mkboot option to add only LIF file header (no LIF volume)

This is not necessary, as noted above.

>  - installboot support to detect block and length of a file in ISO9660 fs
>    as src/distrib/cdrom/macppc_installboot does

See the attached diffs.

I've also pushed all commits with full logs to my github:
 https://github.com/tsutsui/netbsd-src/compare/689d5906...tsutsui:netbsd-src:tsutsui-hp300-cdboot-rebase

- sys/arch/hp300/stand/mkboot/Makefile
 - enable SUPPORT_CD

- sys/fs/cd9660
 - make cd9660_util.c usable with cd9660_extern.h from userland

- tools/Makefile.nbincludes
 - install cd9660 sys headers for tools installboot build
   (XXX: should we install these ones into /usr/include/fs ?)

- usr.sbin/installboot
 - add cd9660 support to -t option
 - make arch/hp300.c use it to make CD ISO bootable

- distrib/hp300/cdroms/installcd/Makefile
 - install RAMDISK kernel and bootloader for hp300 installcd

- distrib/cdrom/macppc_installboot
 - sync with usr.sbin/installboot/cd9660.c, for future merge

---
diff --git a/distrib/cdrom/macppc_installboot/Makefile b/distrib/cdrom/macppc_installboot/Makefile
index dcc9df2aa9c5..4bb078685c9d 100644
--- a/distrib/cdrom/macppc_installboot/Makefile
+++ b/distrib/cdrom/macppc_installboot/Makefile
@@ -16,6 +16,7 @@ HOST_CPPFLAGS+=	-I. -I${.CURDIR}
 	${HOST_INSTALL_DIR} fs/cd9660
 	${HOST_LN} -s ${NETBSDSRCDIR}/sys/fs/unicode.h fs
 	${HOST_LN} -s ${NETBSDSRCDIR}/sys/fs/cd9660/iso.h fs/cd9660
+	${HOST_LN} -s ${NETBSDSRCDIR}/sys/fs/cd9660/cd9660_extern.h fs/cd9660
 .endif
 
 cleandir distclean: cleaninc
diff --git a/distrib/cdrom/macppc_installboot/cd9660.c b/distrib/cdrom/macppc_installboot/cd9660.c
index 02d1c9232a6e..008a5cec1822 100644
--- a/distrib/cdrom/macppc_installboot/cd9660.c
+++ b/distrib/cdrom/macppc_installboot/cd9660.c
@@ -51,6 +51,7 @@ __RCSID("$NetBSD: cd9660.c,v 1.4 2014/09/27 15:21:40 tsutsui Exp $");
 #include <dirent.h>
 
 #include <fs/cd9660/iso.h>
+#include <fs/cd9660/cd9660_extern.h>
 
 #include "installboot.h"
 
@@ -87,7 +88,7 @@ cd9660_match(ib_params *params)
 		return 0;
 	}
 
-	blocksize = isonum_723((char *)ipd.logical_block_size);
+	blocksize = isonum_723((u_char *)ipd.logical_block_size);
 	if (blocksize != ISO_DEFAULT_BLOCK_SIZE) {
 		warnx("Invalid blocksize %d in `%s'",
 		    blocksize, params->filesystem);
@@ -104,10 +105,11 @@ int
 cd9660_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
 {
 	uint8_t buf[ISO_DEFAULT_BLOCK_SIZE];
-	char name[MAXNAMLEN];
-	char *ofwboot;
+	char name[ISO_MAXNAMLEN];
+	char *stage2;
 	off_t loc;
-	int rv, blocksize, found, i;
+	int rv, blocksize, found;
+	u_int i;
 	struct iso_primary_descriptor ipd;
 	struct iso_directory_record *idr;
 
@@ -122,20 +124,20 @@ cd9660_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
 #endif
 
 	/* The secondary bootstrap must be clearly in /. */
-	strlcpy(name, params->stage2, MAXNAMLEN);
-	ofwboot = name;
-	if (ofwboot[0] == '/')
-		ofwboot++;
-	if (strchr(ofwboot, '/') != NULL) {
+	strlcpy(name, params->stage2, ISO_MAXNAMLEN);
+	stage2 = name;
+	if (stage2[0] == '/')
+		stage2++;
+	if (strchr(stage2, '/') != NULL) {
 		warnx("The secondary bootstrap `%s' must be in / "
 		    "on filesystem `%s'", params->stage2, params->filesystem);
 		return 0;
 	}
-	if (strchr(ofwboot, '.') == NULL) {
+	if (strchr(stage2, '.') == NULL) {
 		/*
 		 * XXX should fix isofncmp()?
 		 */
-		strlcat(ofwboot, ".", MAXNAMLEN);
+		strlcat(name, ".", ISO_MAXNAMLEN);
 	}
 
 	rv = pread(params->fsfd, &ipd, sizeof(ipd),
@@ -148,7 +150,7 @@ cd9660_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
 		   params->filesystem);
 		return 0;
 	}
-	blocksize = isonum_723((char *)ipd.logical_block_size);
+	blocksize = isonum_723((u_char *)ipd.logical_block_size);
 
 	idr = (void *)ipd.root_directory_record;
 	loc = (off_t)isonum_733(idr->extent) * blocksize;
@@ -205,13 +207,12 @@ cd9660_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
 			printf("\n");
 		}
 #endif
-		if (isofncmp(ofwboot, strlen(ofwboot),
-		    idr->name, isonum_711(idr->name_len), 0) == 0) {
+		if (isofncmp((u_char *)stage2, strlen(stage2),
+		    (u_char *)idr->name,
+		    isonum_711((u_char *)idr->name_len), 0) == 0) {
 			found = 1;
 			/* ISO filesystem always has contiguous file blocks */
 			blocks[0].block = (int64_t)isonum_733(idr->extent);
-			/* XXX bootxx assumes blocksize is 512 */
-			blocks[0].block *= blocksize / 512;
 			blocks[0].blocksize =
 			    roundup(isonum_733(idr->size), blocksize);
 			*maxblk = 1;
diff --git a/distrib/cdrom/macppc_installboot/installboot.c b/distrib/cdrom/macppc_installboot/installboot.c
index e3af92bb8988..56da84961b8b 100644
--- a/distrib/cdrom/macppc_installboot/installboot.c
+++ b/distrib/cdrom/macppc_installboot/installboot.c
@@ -47,6 +47,12 @@ static	void usage(void);
 
 static	ib_params	installboot_params;
 
+static	struct ib_fs cd9660_fstype = {
+	.name = "cd9660",
+	.match = cd9660_match,
+	.findstage2 = cd9660_findstage2
+};
+
 int
 main(int argc, char **argv)
 {
@@ -59,6 +65,7 @@ main(int argc, char **argv)
 	uint32_t nblk, maxblk, blk_i;
 	int rv;
 	ib_block *blocks;
+	uint64_t block;
 
 	setprogname(argv[0]);
 	params = &installboot_params;
@@ -70,11 +77,16 @@ main(int argc, char **argv)
 		usage();
 
 	params->filesystem = argv[1];
+	params->fstype = &cd9660_fstype;
 
 	if ((params->fsfd = open(params->filesystem, O_RDWR, 0600)) == -1)
 		err(1, "Opening file system `%s' read", params->filesystem);
 	if (fstat(params->fsfd, &params->fsstat) == -1)
 		err(1, "Examining file system `%s'", params->filesystem);
+	if (!params->fstype->match(params))
+		errx(1, "File system `%s' is not of type %s",
+		    params->filesystem, params->fstype->name);
+
 #ifdef DEBUG
 	printf("file system: %s, %ld bytes\n",
 	    params->filesystem, (long)params->fsstat.st_size);
@@ -87,7 +99,7 @@ main(int argc, char **argv)
 	if (pread(params->fsfd, &pme, sizeof pme, BSIZE * 2) != sizeof(pme))
 		err(1, "read pme from file system `%s'", params->filesystem);
 
-	if (strcmp(pme.pmPartName, "NetBSD_BootBlock"))
+	if (strcmp((char *)pme.pmPartName, "NetBSD_BootBlock"))
 		err(1, "invalid partition map in file system `%s'",
 		    params->filesystem);
 
@@ -167,14 +179,16 @@ main(int argc, char **argv)
 	}
 
 	nblk = maxblk;
-	if (!cd9660_findstage2(params, &nblk, blocks)) {
+	if (!params->fstype->findstage2(params, &nblk, blocks)) {
 		exit(1);
 	}
 
 	bbinfop->bbi_block_count = htobe32(nblk);
 	bbinfop->bbi_block_size = htobe32(blocks[0].blocksize);
 	for (blk_i = 0; blk_i < nblk; blk_i++) {
-		bbinfop->bbi_block_table[blk_i] = htobe32(blocks[blk_i].block);
+		/* XXX bootxx assumes blocksize is 512 */
+		block = blocks[blk_i].block * (params->fstype->blocksize / 512);
+		bbinfop->bbi_block_table[blk_i] = htobe32(block);
 		if (blocks[blk_i].blocksize < blocks[0].blocksize &&
 		    blk_i + 1 != nblk) {
 			warnx("Secondary bootstrap `%s' blocks do not have "
diff --git a/distrib/cdrom/macppc_installboot/installboot.h b/distrib/cdrom/macppc_installboot/installboot.h
index 1875e300cc04..57d8ae09502f 100644
--- a/distrib/cdrom/macppc_installboot/installboot.h
+++ b/distrib/cdrom/macppc_installboot/installboot.h
@@ -43,10 +43,6 @@
 #include <sys/stat.h>
 #include <stdint.h>
 
-#ifndef MAXNAMLEN
-#define MAXNAMLEN	511
-#endif
-
 typedef enum {
 				/* flags from global options */
 	IB_VERBOSE =	1<<0,		/* verbose operation */
@@ -135,7 +131,4 @@ struct bbinfo_params {
 int		cd9660_match(ib_params *);
 int		cd9660_findstage2(ib_params *, uint32_t *, ib_block *);
 
-int isofncmp(const u_char *, size_t, const u_char *, size_t, int);
-void isofntrans(const u_char *, int, u_char *, u_short *, int, int, int, int);
-
 #endif	/* _INSTALLBOOT_H */
diff --git a/distrib/hp300/cdroms/installcd/Makefile b/distrib/hp300/cdroms/installcd/Makefile
index 96c9b1dfd1ec..7417897242a5 100644
--- a/distrib/hp300/cdroms/installcd/Makefile
+++ b/distrib/hp300/cdroms/installcd/Makefile
@@ -3,4 +3,18 @@ CDBASE=		hp300cd			# gives ${CDBASE}.iso
 CDRELEASE=	true			# include $RELEASEDIR/$RELEASEMACHINEDIR
 CDRELEASE_NODEBUG=	true
 
+CDKERNELS=	netbsd-RAMDISK.gz netbsd
+CDINSTKERNEL=	../../instkernel
+
+SYS_UBOOT=	SYS_UBOOT
+BOOTDIR=	${DESTDIR}/usr/mdec/rbootd
+
+# make the CD bootable
+prepare_md_post:
+	${INSTALL} ${COPY} -m 0644 ${BOOTDIR}/${SYS_UBOOT} cdrom
+
+image_md_post:
+	${TOOL_INSTALLBOOT} -m ${MACHINE} \
+	    ${CDIMAGE} ${BOOTDIR}/${SYS_UBOOT} /${SYS_UBOOT}
+
 .include "${.CURDIR}/../../../common/Makefile.bootcd"
diff --git a/sys/arch/hp300/stand/uboot/Makefile b/sys/arch/hp300/stand/uboot/Makefile
index 6d0a833e2b77..3fe3a8882e39 100644
--- a/sys/arch/hp300/stand/uboot/Makefile
+++ b/sys/arch/hp300/stand/uboot/Makefile
@@ -6,6 +6,7 @@ NEWVERSWHAT=	"Primary Boot"
 
 CPPFLAGS+=	-DSUPPORT_ETHERNET -DSUPPORT_TAPE -DSUPPORT_DISK
 CPPFLAGS+=	-DSUPPORT_UFS2
+CPPFLAGS+=	-DSUPPORT_CD
 
 LINKS=	${BINDIR}/${PROG} ${BINDIR}/rdboot
 LINKS+=	${BINDIR}/${PROG} ${BINDIR}/bootrd
diff --git a/sys/fs/cd9660/cd9660_extern.h b/sys/fs/cd9660/cd9660_extern.h
index f58436bdb322..1276eac9a587 100644
--- a/sys/fs/cd9660/cd9660_extern.h
+++ b/sys/fs/cd9660/cd9660_extern.h
@@ -105,10 +105,11 @@ extern int (**cd9660_vnodeop_p)(void *);
 extern int (**cd9660_specop_p)(void *);
 extern int (**cd9660_fifoop_p)(void *);
 
+ino_t isodirino(struct iso_directory_record *, struct iso_mnt *);
+#endif /* _KERNEL */
+
 int isochar(const u_char *, const u_char *, int, u_int16_t *);
 int isofncmp(const u_char *, size_t, const u_char *, size_t, int);
 void isofntrans(const u_char *, int, u_char *, u_short *, int, int, int, int);
-ino_t isodirino(struct iso_directory_record *, struct iso_mnt *);
-#endif /* _KERNEL */
 
 #endif /* _ISOFS_CD9660_CD9660_EXTERN_H_ */
diff --git a/sys/fs/cd9660/cd9660_util.c b/sys/fs/cd9660/cd9660_util.c
index 3915ab1409bb..3d827e390926 100644
--- a/sys/fs/cd9660/cd9660_util.c
+++ b/sys/fs/cd9660/cd9660_util.c
@@ -66,11 +66,7 @@ __KERNEL_RCSID(0, "$NetBSD: cd9660_util.c,v 1.14 2016/03/09 20:18:17 christos Ex
 #endif
 
 #include <fs/cd9660/iso.h>
-#ifdef _KERNEL
 #include <fs/cd9660/cd9660_extern.h>
-#else
-static int isochar(const u_char *, const u_char *, int, uint16_t *);
-#endif
 
 #include <fs/unicode.h>
 
diff --git a/tools/Makefile.nbincludes b/tools/Makefile.nbincludes
index efff65fe8411..71d4e8baa8ab 100644
--- a/tools/Makefile.nbincludes
+++ b/tools/Makefile.nbincludes
@@ -6,12 +6,15 @@ _ARCHDIR:=	${.PARSEDIR}/../sys/arch
 _INCDIR:=	${.PARSEDIR}/../include
 _SYSDIR:=	${.PARSEDIR}/../sys/sys
 _UFSDIR:=	${.PARSEDIR}/../sys/ufs
+_FSDIR:=	${.PARSEDIR}/../sys/fs
 _SUBDIR!=	cd ${_ARCHDIR} && ${MAKE} -V SUBDIR
 
 .if make(depend) || make(all) || make(dependall) || make(install)
 # There's no need to run these commands for "make cleandir" or "make obj",
 # and TOOL_SED will not yet have been built.
 _UFS_INCS!=	cd ${_UFSDIR} && find ffs ufs -name '*.h'
+_FS_INCS!=	cd ${_FSDIR} && find cd9660 -name '*.h'
+_FS_INCS+=	unicode.h
 _ARCH_INCS!=	${TOOL_SED} -e 's/^\#.*//' ${.PARSEDIR}/headerlist
 .endif
 
@@ -34,6 +37,8 @@ beforedepend:
 	${HOST_INSTALL_DIR} ${TOOLDIR}/include/nbinclude
 	${HOST_INSTALL_DIR} ${TOOLDIR}/include/nbinclude/sys
 	${HOST_INSTALL_DIR} ${TOOLDIR}/include/nbinclude/ufs
+	${HOST_INSTALL_DIR} ${TOOLDIR}/include/nbinclude/fs
+	${HOST_INSTALL_DIR} ${TOOLDIR}/include/nbinclude/fs/cd9660
 	cd ${_ARCHDIR} && \
 	    ${TOOL_PAX} -s /include\\/// -rw ${_ARCH_INCS} \
 	    ${TOOLDIR}/include/nbinclude
@@ -43,5 +48,7 @@ beforedepend:
 	    ${TOOL_PAX} -rw ${_SYSINCS} ${TOOLDIR}/include/nbinclude/sys
 	cd ${_UFSDIR} && \
 	    ${TOOL_PAX} -rw ${_UFS_INCS} ${TOOLDIR}/include/nbinclude/ufs
+	cd ${_FSDIR} && \
+	    ${TOOL_PAX} -rw ${_FS_INCS} ${TOOLDIR}/include/nbinclude/fs
 	cd ${TOOLDIR}/include/nbinclude && rm -f machine && \
 	    ${HOST_INSTALL_SYMLINK} ${MACHINE} machine
diff --git a/usr.sbin/installboot/Makefile b/usr.sbin/installboot/Makefile
index e31285b7776a..324ae24bddb9 100644
--- a/usr.sbin/installboot/Makefile
+++ b/usr.sbin/installboot/Makefile
@@ -69,9 +69,29 @@ SRCS+= ffs_bswap.c
 #SRCS+= ext2fs.c ext2fs_bswap.c
 .endif
 
+.if !empty(ARCH_FILES:C/(hp300|macppc)/cd9660/:Mcd9660.c)
+SRCS+= cd9660.c cd9660_util.c
+
+.if !make(obj) && !make(clean) && !make(cleandir)
+.BEGIN:
+	-rm -rf fs
+	${HOST_INSTALL_DIR} fs
+	${HOST_INSTALL_DIR} fs/cd9660
+	${HOST_LN} -s ${NETBSDSRCDIR}/sys/fs/unicode.h fs
+	${HOST_LN} -s ${NETBSDSRCDIR}/sys/fs/cd9660/iso.h fs/cd9660
+	${HOST_LN} -s ${NETBSDSRCDIR}/sys/fs/cd9660/cd9660_extern.h fs/cd9660
+.endif
+
+cleandir distclean: cleaninc
+
+cleaninc:
+	-rm -rf fs
+.endif
+
 UFSSRC=		${NETBSDSRCDIR}/sys/ufs
+CD9660SRC=	${NETBSDSRCDIR}/sys/fs/cd9660
 CPPFLAGS+=	-I${.CURDIR} -I.
-.PATH:		${.CURDIR}/arch ${UFSSRC}/ffs ${UFSSRC}/ext2fs
+.PATH:		${.CURDIR}/arch ${UFSSRC}/ffs ${UFSSRC}/ext2fs ${CD9660SRC}
 
 .if !defined(HOSTPROGNAME)
 .for f in i386 macppc
diff --git a/usr.sbin/installboot/arch/hp300.c b/usr.sbin/installboot/arch/hp300.c
index 118caa2c78c9..56cf9de18f07 100644
--- a/usr.sbin/installboot/arch/hp300.c
+++ b/usr.sbin/installboot/arch/hp300.c
@@ -62,6 +62,9 @@ __RCSID("$NetBSD: hp300.c,v 1.18 2024/05/11 22:10:27 tsutsui Exp $");
 
 #include "installboot.h"
 
+#define HP300_MAXBLOCKS	1	/* Only contiguous blocks are expected. */
+#define LIF_VOLDIRSIZE	1024	/* size of LIF volume header and directory */
+
 static int hp300_setboot(ib_params *);
 
 struct ib_mach ib_mach_hp300 = {
@@ -77,6 +80,7 @@ hp300_setboot(ib_params *params)
 {
 	int		retval;
 	uint8_t		*bootstrap;
+	size_t		bootstrap_size;
 	ssize_t		rv;
 	struct partition *boot;
 	struct hp300_lifdir *lifdir;
@@ -84,6 +88,8 @@ hp300_setboot(ib_params *params)
 	int		i;
 	unsigned int	secsize = HP300_SECTSIZE;
 	uint64_t	boot_size, boot_offset;
+	uint32_t	nblk;
+	ib_block	*blocks;
 	struct disklabel *label;
 
 	assert(params != NULL);
@@ -101,7 +107,62 @@ hp300_setboot(ib_params *params)
 		goto done;
 	}
 
-	if (params->flags & IB_APPEND) {
+	if (params->stage2 != NULL) {
+		/*
+		 * Use contiguous blocks of SYS_BOOT in the target filesystem
+		 * (assuming ISO9660) for a LIF directory entry used
+		 * by BOOTROM on bootstrap.
+		 */
+		if (strcmp(params->fstype->name, "cd9660") != 0) {
+			warn("Target filesystem `%s' is unexpected",
+			    params->fstype->name);
+		}
+
+		if (S_ISREG(params->fsstat.st_mode)) {
+			if (fsync(params->fsfd) == -1)
+				warn("Synchronising file system `%s'",
+				    params->filesystem);
+		} else {
+			/* Don't allow real file systems for sanity */
+			warnx("`%s' must be a regular file to append "
+			    "a bootstrap", params->filesystem);
+			goto done;
+		}
+
+		/* Allocate space for our block list. */
+		nblk = HP300_MAXBLOCKS;
+		blocks = malloc(sizeof(*blocks) * nblk);
+		if (blocks == NULL) {
+			warn("Allocating %lu bytes for block list",
+			    (unsigned long)sizeof(*blocks) * nblk);
+			goto done;
+		}
+
+		/* Check the block of for the SYS_UBOOT in the target fs */
+		if (!params->fstype->findstage2(params, &nblk, blocks))
+			goto done;
+
+		if (nblk == 0) {
+			warnx("Secondary bootstrap `%s' is empty",
+			    params->stage2);
+			goto done;
+		} else if (nblk > 1) {
+			warnx("Secondary bootstrap `%s' doesn't have "
+			    "contiguous blocks", params->stage2);
+			goto done;
+		}
+
+		boot_offset = blocks[0].block * params->fstype->blocksize;
+		/* need to read only LIF volume and directories */
+		bootstrap_size = LIF_VOLDIRSIZE;
+
+		if ((params->flags & IB_VERBOSE) != 0) {
+			printf("Bootstrap `%s' found at offset %lu in `%s'\n",
+			    params->stage2, (unsigned long)boot_offset,
+			    params->filesystem);
+		}
+
+	} else if (params->flags & IB_APPEND) {
 		if (!S_ISREG(params->fsstat.st_mode)) {
 			warnx(
 		    "`%s' must be a regular file to append a bootstrap",
@@ -157,11 +218,24 @@ hp300_setboot(ib_params *params)
 		}
 	}
 
-	bootstrap = mmap(NULL, params->s1stat.st_size, PROT_READ | PROT_WRITE,
-			    MAP_PRIVATE, params->s1fd, 0);
-	if (bootstrap == MAP_FAILED) {
-		warn("mmapping `%s'", params->stage1);
-		goto done;
+	if (params->stage2 != NULL) {
+		/* Use bootstrap file in the target filesystem. */
+		bootstrap = mmap(NULL, bootstrap_size,
+		    PROT_READ | PROT_WRITE, MAP_PRIVATE, params->fsfd,
+		    boot_offset);
+		if (bootstrap == MAP_FAILED) {
+			warn("mmapping `%s'", params->filesystem);
+			goto done;
+		}
+	} else {
+		/* Use bootstrap specified as stage1. */
+		bootstrap_size = params->s1stat.st_size;
+		bootstrap = mmap(NULL, bootstrap_size,
+		    PROT_READ | PROT_WRITE, MAP_PRIVATE, params->s1fd, 0);
+		if (bootstrap == MAP_FAILED) {
+			warn("mmapping `%s'", params->stage1);
+			goto done;
+		}
 	}
 
 	/* Relocate files, sanity check LIF directory on the way */
@@ -187,8 +261,8 @@ hp300_setboot(ib_params *params)
 	}
 
 	/* Write LIF volume header and directory to sectors 0 and 1 */
-	rv = pwrite(params->fsfd, bootstrap, 1024, 0);
-	if (rv != 1024) {
+	rv = pwrite(params->fsfd, bootstrap, LIF_VOLDIRSIZE, 0);
+	if (rv != LIF_VOLDIRSIZE) {
 		if (rv == -1)
 			warn("Writing `%s'", params->filesystem);
 		else
@@ -196,6 +270,15 @@ hp300_setboot(ib_params *params)
 		goto done;
 	}
 
+	if (params->stage2 != NULL) {
+		/*
+		 * Bootstrap in the target filesystem is used.
+		 * No need to write bootstrap to BOOT partition.
+		 */
+		retval = 1;
+		goto done;
+	}
+
 	/* Write files to BOOT partition */
 	offset = boot_offset <= HP300_SECTSIZE * 16 ? HP300_SECTSIZE * 16 : 0;
 	i = roundup(params->s1stat.st_size, secsize) - offset;
@@ -216,6 +299,6 @@ hp300_setboot(ib_params *params)
 	if (label != NULL)
 		free(label);
 	if (bootstrap != MAP_FAILED)
-		munmap(bootstrap, params->s1stat.st_size);
+		munmap(bootstrap, bootstrap_size);
 	return retval;
 }
diff --git a/usr.sbin/installboot/cd9660.c b/usr.sbin/installboot/cd9660.c
new file mode 100644
index 000000000000..6cb682d1c5e2
--- /dev/null
+++ b/usr.sbin/installboot/cd9660.c
@@ -0,0 +1,234 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2005 Izumi Tsutsui.  All rights reserved.
+ *
+ * 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 AUTHOR ``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 AUTHOR 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 <sys/cdefs.h>
+#if defined(__RCSID) && !defined(__lint)
+__RCSID("$NetBSD$");
+#endif	/* !__lint */
+
+#include <sys/param.h>
+
+#if !HAVE_NBTOOL_CONFIG_H
+#include <sys/mount.h>
+#endif
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <fs/cd9660/iso.h>
+#include <fs/cd9660/cd9660_extern.h>
+
+#include "installboot.h"
+
+#define roundup(x, y)	((((x)+((y)-1))/(y))*(y))
+#define MAXLEN		16
+
+
+int
+cd9660_match(ib_params *params)
+{
+	int rv, blocksize;
+	struct iso_primary_descriptor ipd;
+
+	assert(params != NULL);
+	assert(params->fstype != NULL);
+	assert(params->fsfd != -1);
+
+	rv = pread(params->fsfd, &ipd, sizeof(ipd),
+	    ISO_DEFAULT_BLOCK_SIZE * 16);
+	if (rv == -1) {
+		warn("Reading primary descriptor in `%s'", params->filesystem);
+		return 0;
+	} else if (rv != sizeof(ipd)) {
+		warnx("Reading primary descriptor in `%s': short read",
+		   params->filesystem);
+		return 0;
+	}
+
+	if (ipd.type[0] != ISO_VD_PRIMARY ||
+	    strncmp(ipd.id, ISO_STANDARD_ID, sizeof(ipd.id)) != 0 ||
+	    ipd.version[0] != 1) {
+		warnx("Filesystem `%s' is not ISO9660 format",
+		   params->filesystem);
+		return 0;
+	}
+
+	blocksize = isonum_723((u_char *)ipd.logical_block_size);
+	if (blocksize != ISO_DEFAULT_BLOCK_SIZE) {
+		warnx("Invalid blocksize %d in `%s'",
+		    blocksize, params->filesystem);
+		return 0;
+	}
+
+	params->fstype->blocksize = blocksize;
+	params->fstype->needswap = 0;
+
+	return 1;
+}
+
+int
+cd9660_findstage2(ib_params *params, uint32_t *maxblk, ib_block *blocks)
+{
+	uint8_t buf[ISO_DEFAULT_BLOCK_SIZE];
+	char name[ISO_MAXNAMLEN];
+	char *stage2;
+	off_t loc;
+	int rv, blocksize, found;
+	u_int i;
+	struct iso_primary_descriptor ipd;
+	struct iso_directory_record *idr;
+
+	assert(params != NULL);
+	assert(params->stage2 != NULL);
+	assert(maxblk != NULL);
+	assert(blocks != NULL);
+
+#if 0
+	if (params->flags & IB_STAGE2START)
+		return hardcode_stage2(params, maxblk, blocks);
+#endif
+
+	/* The secondary bootstrap must be clearly in /. */
+	strlcpy(name, params->stage2, ISO_MAXNAMLEN);
+	stage2 = name;
+	if (stage2[0] == '/')
+		stage2++;
+	if (strchr(stage2, '/') != NULL) {
+		warnx("The secondary bootstrap `%s' must be in / "
+		    "on filesystem `%s'", params->stage2, params->filesystem);
+		return 0;
+	}
+	if (strchr(stage2, '.') == NULL) {
+		/*
+		 * XXX should fix isofncmp()?
+		 */
+		strlcat(name, ".", ISO_MAXNAMLEN);
+	}
+
+	rv = pread(params->fsfd, &ipd, sizeof(ipd),
+	    ISO_DEFAULT_BLOCK_SIZE * 16);
+	if (rv == -1) {
+		warn("Reading primary descriptor in `%s'", params->filesystem);
+		return 0;
+	} else if (rv != sizeof(ipd)) {
+		warnx("Reading primary descriptor in `%s': short read",
+		   params->filesystem);
+		return 0;
+	}
+	blocksize = isonum_723((u_char *)ipd.logical_block_size);
+
+	idr = (void *)ipd.root_directory_record;
+	loc = (off_t)isonum_733(idr->extent) * blocksize;
+	rv = pread(params->fsfd, buf, blocksize, loc);
+	if (rv == -1) {
+		warn("Reading root directory record in `%s'",
+		    params->filesystem);
+		return 0;
+	} else if (rv != sizeof(ipd)) {
+		warnx("Reading root directory record in `%s': short read",
+		   params->filesystem);
+		return 0;
+	}
+
+	found = 0;
+	for (i = 0; i < blocksize - sizeof(struct iso_directory_record);
+	    i += (u_char)idr->length[0]) {
+		idr = (void *)&buf[i];
+
+#ifdef DEBUG
+		printf("i = %d, idr->length[0] = %3d\n",
+		    i, (u_char)idr->length[0]);
+#endif
+		/* check end of entries */
+		if (idr->length[0] == 0) {
+#ifdef DEBUG
+		printf("end of entries\n");
+#endif
+			break;
+		}
+
+		if (idr->flags[0] & 2) {
+			/* skip directory entries */
+#ifdef DEBUG
+			printf("skip directory entry\n");
+#endif
+			continue;
+		}
+		if (idr->name_len[0] == 1 &&
+		    (idr->name[0] == 0 || idr->name[0] == 1)) {
+			/* skip "." and ".." */
+#ifdef DEBUG
+			printf("skip dot dot\n");
+#endif
+			continue;
+		}
+#ifdef DEBUG
+		{
+			int j;
+
+			printf("filename:");
+			for (j = 0; j < isonum_711(idr->name_len); j++)
+				printf("%c", idr->name[j]);
+			printf("\n");
+		}
+#endif
+		if (isofncmp((u_char *)stage2, strlen(stage2),
+		    (u_char *)idr->name,
+		    isonum_711((u_char *)idr->name_len), 0) == 0) {
+			found = 1;
+			/* ISO filesystem always has contiguous file blocks */
+			blocks[0].block = (int64_t)isonum_733(idr->extent);
+			blocks[0].blocksize =
+			    roundup(isonum_733(idr->size), blocksize);
+			*maxblk = 1;
+#ifdef DEBUG
+			printf("block = %ld, blocksize = %ld\n",
+			    (long)blocks[0].block, blocks[0].blocksize);
+#endif
+			break;
+		}
+	}
+
+	if (found == 0) {
+		warnx("Can't find secondary bootstrap `%s' in filesystem `%s'",
+		    params->stage2, params->filesystem);
+		return 0;
+	}
+
+	return 1;
+}
diff --git a/usr.sbin/installboot/fstypes.c b/usr.sbin/installboot/fstypes.c
index 1b77f974fc5d..4bb720be6b5a 100644
--- a/usr.sbin/installboot/fstypes.c
+++ b/usr.sbin/installboot/fstypes.c
@@ -48,11 +48,31 @@ __RCSID("$NetBSD: fstypes.c,v 1.13 2010/01/14 16:27:49 tsutsui Exp $");
 
 struct ib_fs fstypes[] = {
 #ifndef NO_STAGE2
-	{ .name = "ffs",  .match = ffs_match,	.findstage2 = ffs_findstage2	},
-	{ .name = "raid", .match = raid_match,	.findstage2 = ffs_findstage2	},
-	{ .name = "raw",  .match = raw_match,	.findstage2 = raw_findstage2	},
+	{
+		.name = "ffs",
+		.match = ffs_match,
+		.findstage2 = ffs_findstage2
+	},
+	{
+		.name = "raid",
+		.match = raid_match,
+		.findstage2 = ffs_findstage2
+	},
+	{
+		.name = "cd9660",
+		.match = cd9660_match,
+		.findstage2 = cd9660_findstage2
+	},
+	/* raw_match() always matches, so raw should be at the end. */
+	{
+		.name = "raw",
+		.match = raw_match,
+		.findstage2 = raw_findstage2
+	},
 #endif
-	{ .name = NULL, }
+	{
+		.name = NULL
+	}
 };
 
 #ifndef NO_STAGE2
diff --git a/usr.sbin/installboot/installboot.8 b/usr.sbin/installboot/installboot.8
index b6eaf75fc974..71a4871eae1c 100644
--- a/usr.sbin/installboot/installboot.8
+++ b/usr.sbin/installboot/installboot.8
@@ -32,7 +32,7 @@
 .\" Usage: \*(UB
 .ds UB U\(hyBoot
 .
-.Dd December 25, 2023
+.Dd May 12, 2024
 .Dt INSTALLBOOT 8
 .Os
 .Sh NAME
@@ -479,6 +479,9 @@ Fast File System.
 .It Ic raid
 Mirrored RAIDframe File System.
 .
+.It Ic cd9660
+ISO 9660 File System.
+.
 .It Ic raw
 .Dq Raw
 image.
diff --git a/usr.sbin/installboot/installboot.h b/usr.sbin/installboot/installboot.h
index 468670c6fb14..b9e65b9a1660 100644
--- a/usr.sbin/installboot/installboot.h
+++ b/usr.sbin/installboot/installboot.h
@@ -171,15 +171,23 @@ int		shared_bbinfo_clearboot(ib_params *, struct bbinfo_params *,
 int		shared_bbinfo_setboot(ib_params *, struct bbinfo_params *,
 		    int (*)(ib_params *, struct bbinfo_params *, uint8_t *));
 
-	/* fstypes.c */
-int		hardcode_stage2(ib_params *, uint32_t *, ib_block *);
+	/* cd9660.c */
+int		cd9660_match(ib_params *);
+int		cd9660_findstage2(ib_params *, uint32_t *, ib_block *);
+
+	/* ext2fs.c */
+int		ext2fs_match(ib_params *);
+int		ext2fs_findstage2(ib_params *, uint32_t *, ib_block *);
+
+	/* ffs.c */
 int		ffs_match(ib_params *);
 int		ffs_findstage2(ib_params *, uint32_t *, ib_block *);
 int		raid_match(ib_params *);
+
+	/* fstypes.c */
+int		hardcode_stage2(ib_params *, uint32_t *, ib_block *);
 int		raw_match(ib_params *);
 int		raw_findstage2(ib_params *, uint32_t *, ib_block *);
-int		ext2fs_match(ib_params *);
-int		ext2fs_findstage2(ib_params *, uint32_t *, ib_block *);
 
 	/* machines.c */
 extern struct ib_mach ib_mach_alpha;


---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index