mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
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
This commit is contained in:
2 files changed
+60
-12
No files matched your search
@@ -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.
|
||||
@@ -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);
|
||||
}
|
||||
Reference in new issue
Block a user