From nobody Wed Jul 29 16:15:27 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h9HVm13BGz6mSvy for ; Wed, 29 Jul 2026 16:15:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h9HVm03V4z3Sdg for ; Wed, 29 Jul 2026 16:15:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785341728; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=RyhBraBiVk47YlUJLge+pP7sWC7TWJ8qMGJBwzoq1Ts=; b=hC6rlgM7LlX2SDI4yjbisBQCixBIrv3TOLoezXp5apgdBWsHv6aI+rOIrGD3CYMsubcLkz T8ARs/cDnB5ffY1qybnwLE3Mxv0VSg1DcqIp/N00zvEZVOFEs+SrXJ0hdsb1S+tZRbqC9d U1hO/5hkrb2YtNT0N/ydFD5AMzcnmH6SBakyXVVq6WqS7nio1gimBZnFy/gcVFZ86uOiVJ EAh7IvIP2fJIhRgJiE2hmwIMbK3w47CiVo0A/bz//XwPx/QwlTYd8wST7i3APOFH+htZma f1OPFDspk+59kcoG032KZQIsU6zONNBpTIH/jSc5SkLNhtP0JXl1vlqLmHAzIw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785341728; a=rsa-sha256; cv=none; b=MFk4u6FkDB28aJo9E4ytFelrai6IMQFb6Hy9hIsL1rPoW6qRkKQsJiwTbUvfLCrtBJAAmA DcT+rEa2KWqVc8IoM7+ub99kzxbRfBU08cICWp4jJxNc2rOQAsYwfi9Fa0EXjS7DodpqqW oUSFJrxRh1UHatZLQ1ayCR/e65J8MduomS3103aza4I+SR/svQhiOweLAH4UUxcUdUSJTT aZWkA/o0/2TIWsEcA+GoV7ggyeaSV/HB6rtuffHjsTkIB1NGe2E1+REvDfgj8Q0T1d2l37 zNrWP0sh8swy9LLcWmDaVpYL8u9MsaOjk139KjIC9RZFjrWjKbJux23QLZeVdA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785341728; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=RyhBraBiVk47YlUJLge+pP7sWC7TWJ8qMGJBwzoq1Ts=; b=xRD/Fapox+tqUV7QwiKHI8NfBDWXWTzgs2iVoVQUdfPxpzdAolLYe7YGYJJuiqcvedGtnS 6N5udKnaVHTIjRuB8sEiY7L3s+WOG5guO/CMKCyahEyBcUUzUALXeSbrdVwMhr5vF74KV7 GIFPLIF5Ib/KPsgFtaJy6dDcjtQk7eXqzRk0Nd5PrVvS7Pu1JcU8ulRl0Hy18hir0lhDpx XMtse+i+E/5ZYMNUNEBXUROaiDGo2R6TF37pY0DokR94y2y/5h2jIMwyVWMCt5WSGfIs9h IbREbGWdB8FKnNQkHHzCr//1W5HeQzKk33YAkSAMdufVTYjAQ+sAYMicey46cw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h9HVl5j7PzZXC for ; Wed, 29 Jul 2026 16:15:27 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 31de2 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 29 Jul 2026 16:15:27 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Jose Luis Duran Subject: git: 4007d914e797 - main - boot0cfg: Also allow a file as a trailing argument List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jlduran X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 4007d914e7973bca8ac488ab50aca56964eed90f Auto-Submitted: auto-generated Date: Wed, 29 Jul 2026 16:15:27 +0000 Message-Id: <6a6a271f.31de2.451b1c75@gitrepo.freebsd.org> The branch main has been updated by jlduran: URL: https://cgit.FreeBSD.org/src/commit/?id=4007d914e7973bca8ac488ab50aca56964eed90f commit 4007d914e7973bca8ac488ab50aca56964eed90f Author: Jose Luis Duran AuthorDate: 2026-07-29 16:11:53 +0000 Commit: Jose Luis Duran 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); }