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, ¶ms->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