git: 4007d914e797 - main - boot0cfg: Also allow a file as a trailing argument
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 29 Jul 2026 16:15:27 UTC
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);
}