Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Jul 2026 16:15:27 +0000
From:      Jose Luis Duran <jlduran@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 4007d914e797 - main - boot0cfg: Also allow a file as a trailing argument
Message-ID:  <6a6a271f.31de2.451b1c75@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by jlduran:

URL: https://cgit.FreeBSD.org/src/commit/?id=4007d914e7973bca8ac488ab50aca56964eed90f

commit 4007d914e7973bca8ac488ab50aca56964eed90f
Author:     Jose Luis Duran <jlduran@FreeBSD.org>
AuthorDate: 2026-07-29 16:11:53 +0000
Commit:     Jose Luis Duran <jlduran@FreeBSD.org>
CommitDate: 2026-07-29 16:15:15 +0000

    boot0cfg: Also allow a file as a trailing argument
    
    Modify the disk check to allow arbitrary files as the trailing argument
    instead of requiring a live GEOM disk provider.
    
    This enables modifying a boot0 binary file in-place before flashing it
    to a disk via gpart bootcode, or using it directly as an argument to
    mkimg's partition specification, as these tools cannot directly adjust
    the parameters of the boot0 boot manager.
    
    Reviewed by:    imp, jhb
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D57310
---
 usr.sbin/boot0cfg/boot0cfg.8 | 32 ++++++++++++++++++++++++++------
 usr.sbin/boot0cfg/boot0cfg.c | 40 ++++++++++++++++++++++++++++++++++------
 2 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/usr.sbin/boot0cfg/boot0cfg.8 b/usr.sbin/boot0cfg/boot0cfg.8
index d2e01ada3552..6688d97c65fb 100644
--- a/usr.sbin/boot0cfg/boot0cfg.8
+++ b/usr.sbin/boot0cfg/boot0cfg.8
@@ -22,7 +22,7 @@
 .\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 .\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd October 1, 2013
+.Dd July 29, 2026
 .Dt BOOT0CFG 8
 .Os
 .Sh NAME
@@ -40,7 +40,7 @@
 .Op Fl o Ar options
 .Op Fl s Ar slice
 .Op Fl t Ar ticks
-.Ar disk
+.Ar disk | file
 .Sh DESCRIPTION
 The
 .Fx
@@ -62,9 +62,15 @@ The
 utility optionally installs the
 .Sq boot0
 boot manager on the specified
-.Ar disk ;
+.Ar disk
+or
+.Ar file ;
 and allows various operational parameters to be configured.
 .Pp
+If a file is specified as the target argument, all operations are
+performed entirely in-place.
+This allows for offline payload preparation.
+.Pp
 On PCs, a boot manager typically occupies sector 0 of a disk, which is
 known as the Master Boot Record (MBR).
 The MBR contains both code (to which control is passed by the PC BIOS)
@@ -104,8 +110,10 @@ Specify that a backup copy of the preexisting MBR should be written to
 This file is created if it does not exist, and replaced if it does.
 .It Fl i Ar volume-id
 Specifies a volume-id (in the form XXXX-XXXX) to be saved at location
-0x1b8 in the MBR. This information is sometimes used by NT, XP and Vista
-to identify the disk drive. The option is only compatible with version 2.00
+0x1b8 in the MBR.
+This information is sometimes used by NT, XP and Vista to identify the
+disk drive.
+The option is only compatible with version 2.00
 of the 512-byte boot block.
 .It Fl m Ar mask
 Specify slices to be enabled/disabled, where
@@ -177,6 +185,17 @@ To enable just slices 1 and 3 in the menu:
 .Pp
 .Dl "boot0cfg -m 0x5 ada0"
 .Pp
+Create a copy of
+.Sq boot0
+with only slices 1 and 3 enabled in the menu and install that onto a disk using
+.Xr gpart 8 :
+.Pp
+.Bd -literal -offset indent -compact
+cp /boot/boot0 /boot/boot0.custom
+boot0cfg -m 0x5 /boot/boot0.custom
+gpart bootcode -b /boot/boot0.custom ada0
+.Ed
+.Pp
 To go back to non-interactive booting, use
 .Xr gpart 8
 to install the default MBR:
@@ -199,4 +218,5 @@ Use of the
 .Sq setdrv
 option with an incorrect -d operand may cause the boot0 code
 to write the MBR to the wrong disk, thus trashing its previous
-content.  Be careful.
+content.
+Be careful.
diff --git a/usr.sbin/boot0cfg/boot0cfg.c b/usr.sbin/boot0cfg/boot0cfg.c
index 2a919f0b2f2e..172281172908 100644
--- a/usr.sbin/boot0cfg/boot0cfg.c
+++ b/usr.sbin/boot0cfg/boot0cfg.c
@@ -115,6 +115,7 @@ static int v_flag;
 int
 main(int argc, char *argv[])
 {
+    struct stat sb;
     u_int8_t *mbr, *boot0;
     int boot0_size, mbr_size;
     const char *bpath, *fpath;
@@ -183,9 +184,15 @@ main(int argc, char *argv[])
     argv += optind;
     if (argc != 1)
         usage();
-    disk = g_device_path(*argv);
-    if (disk == NULL)
-        errx(1, "Unable to get providername for %s\n", *argv);
+    if (stat(*argv, &sb) == 0 && S_ISREG(sb.st_mode)) {
+        disk = strdup(*argv);
+        if (disk == NULL)
+            err(1, "strdup");
+    } else {
+        disk = g_device_path(*argv);
+        if (disk == NULL)
+            errx(1, "Unable to get providername for %s\n", *argv);
+    }
     up = B_flag || d_arg != -1 || m_arg != -1 || o_flag || s_arg != -1
 	|| t_arg != -1;
 
@@ -373,6 +380,7 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size,
     int disable_dsn)
 {
 	struct gctl_req *grq;
+	struct stat sb;
 	const char *errmsg;
 	char *pname;
 	ssize_t n;
@@ -394,20 +402,40 @@ write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size,
 	if (flags != 0)
 		err(1, "can't open file %s to write backup", fname);
 
-	/* Try open it read only. */
+	/*
+	 * Try to open it read only to pass to GEOM,
+	 * or inspect if it's a regular file.
+	 */
 	fd = open(fname, O_RDONLY);
 	if (fd == -1) {
 		warn("error opening %s", fname);
 		return;
 	}
 
+	/*
+	 * If name is a regular file, re-open it in write-only mode
+	 * and write the MBR straight to it.
+	 */
+	if (fstat(fd, &sb) == 0 && S_ISREG(sb.st_mode)) {
+		close(fd);
+		fd = open(fname, O_WRONLY);
+		if (fd == -1)
+			err(1, "can't open %s for writing", fname);
+		n = write(fd, mbr, mbr_size);
+		close(fd);
+		if (n != mbr_size)
+			errx(1, "%s: short write", fname);
+		return;
+	}
+
 	pname = g_providername(fd);
+	close(fd);
 	if (pname == NULL) {
 		warn("error getting providername for %s", fname);
 		return;
 	}
 
-	/* First check that GEOM_PART is available */
+	/* Check that GEOM_PART is available */
 	if (geom_class_available("PART") != 0) {
 		grq = gctl_get_handle();
 		gctl_ro_param(grq, "class", -1, "PART");
@@ -594,6 +622,6 @@ usage(void)
 {
     fprintf(stderr, "%s\n%s\n",
     "usage: boot0cfg [-Bv] [-b boot0] [-d drive] [-f file] [-m mask]",
-    "                [-o options] [-s slice] [-t ticks] disk");
+    "                [-o options] [-s slice] [-t ticks] disk | file");
     exit(1);
 }


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6a271f.31de2.451b1c75>