Index: head/lib/geom/part/geom_part.c =================================================================== --- head/lib/geom/part/geom_part.c +++ head/lib/geom/part/geom_part.c @@ -72,6 +72,7 @@ #define GPART_PARAM_BOOTCODE "bootcode" #define GPART_PARAM_INDEX "index" #define GPART_PARAM_PARTCODE "partcode" +#define GPART_PARAM_SKIP_DSN "skip_dsn" static struct gclass *find_class(struct gmesh *, const char *); static struct ggeom * find_geom(struct gclass *, const char *); @@ -115,8 +116,9 @@ { 'p', GPART_PARAM_PARTCODE, G_VAL_OPTIONAL, G_TYPE_STRING }, { 'i', GPART_PARAM_INDEX, G_VAL_OPTIONAL, G_TYPE_NUMBER }, { 'f', "flags", GPART_FLAGS, G_TYPE_STRING }, + { 'N', GPART_PARAM_SKIP_DSN, NULL, G_TYPE_BOOL }, G_OPT_SENTINEL }, - "[-b bootcode] [-p partcode -i index] [-f flags] geom" + "[-N] [-b bootcode] [-p partcode -i index] [-f flags] geom" }, { "commit", 0, gpart_issue, G_NULL_OPTS, "geom" Index: head/lib/geom/part/gpart.8 =================================================================== --- head/lib/geom/part/gpart.8 +++ head/lib/geom/part/gpart.8 @@ -49,6 +49,7 @@ .\" ==== BOOTCODE ==== .Nm .Cm bootcode +.Op Fl N .Op Fl b Ar bootcode .Op Fl p Ar partcode Fl i Ar index .Op Fl f Ar flags @@ -214,6 +215,14 @@ .Cm bootcode command accepts these options: .Bl -tag -width 10n +.It Fl N +Don't preserve the Volume Serial Number for MBR. +MBR bootcode contains Volume Serial Number by default, and +.Nm +tries to preserve it when installing new bootstrap code. +This option allows to skip the preservation to help with some versions of +.Xr boot0 8 +that don't support Volume Serial Number. .It Fl b Ar bootcode Embed bootstrap code from the file .Ar bootcode Index: head/sys/geom/part/g_part.h =================================================================== --- head/sys/geom/part/g_part.h +++ head/sys/geom/part/g_part.h @@ -202,6 +202,7 @@ #define G_PART_PARM_BOOTCODE 0x1000 #define G_PART_PARM_ATTRIB 0x2000 #define G_PART_PARM_FORCE 0x4000 +#define G_PART_PARM_SKIP_DSN 0x8000 struct g_part_parms { unsigned int gpp_parms; @@ -220,6 +221,7 @@ unsigned int gpp_codesize; const char *gpp_attrib; unsigned int gpp_force; + unsigned int gpp_skip_dsn; }; void g_part_geometry_heads(off_t, u_int, off_t *, u_int *); Index: head/sys/geom/part/g_part.c =================================================================== --- head/sys/geom/part/g_part.c +++ head/sys/geom/part/g_part.c @@ -1627,6 +1627,7 @@ if (!strcmp(verb, "bootcode")) { ctlreq = G_PART_CTL_BOOTCODE; mparms |= G_PART_PARM_GEOM | G_PART_PARM_BOOTCODE; + oparms |= G_PART_PARM_SKIP_DSN; } break; case 'c': @@ -1744,6 +1745,8 @@ parm = G_PART_PARM_SIZE; else if (!strcmp(ap->name, "start")) parm = G_PART_PARM_START; + else if (!strcmp(ap->name, "skip_dsn")) + parm = G_PART_PARM_SKIP_DSN; break; case 't': if (!strcmp(ap->name, "type")) @@ -1803,6 +1806,10 @@ break; case G_PART_PARM_SIZE: error = g_part_parm_quad(req, ap->name, &gpp.gpp_size); + break; + case G_PART_PARM_SKIP_DSN: + error = g_part_parm_uint32(req, ap->name, + &gpp.gpp_skip_dsn); break; case G_PART_PARM_START: error = g_part_parm_quad(req, ap->name, Index: head/sys/geom/part/g_part_mbr.c =================================================================== --- head/sys/geom/part/g_part_mbr.c +++ head/sys/geom/part/g_part_mbr.c @@ -274,7 +274,7 @@ table = (struct g_part_mbr_table *)basetable; dsn = *(uint32_t *)(table->mbr + DOSDSNOFF); bcopy(gpp->gpp_codeptr, table->mbr, DOSPARTOFF); - if (dsn != 0) + if (dsn != 0 && !gpp->gpp_skip_dsn) *(uint32_t *)(table->mbr + DOSDSNOFF) = dsn; return (0); } Index: head/usr.sbin/boot0cfg/boot0cfg.c =================================================================== --- head/usr.sbin/boot0cfg/boot0cfg.c +++ head/usr.sbin/boot0cfg/boot0cfg.c @@ -100,7 +100,7 @@ static int geom_class_available(const char *); static int read_mbr(const char *, u_int8_t **, int); -static void write_mbr(const char *, int, u_int8_t *, int); +static void write_mbr(const char *, int, u_int8_t *, int, int); static void display_mbr(u_int8_t *); static int boot0version(const u_int8_t *); static int boot0bs(const u_int8_t *); @@ -200,7 +200,7 @@ /* save the existing MBR if we are asked to do so */ if (fpath) - write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size); + write_mbr(fpath, O_CREAT | O_TRUNC, mbr, mbr_size, 0); /* * If we are installing the boot loader, read it from disk and copy the @@ -256,7 +256,7 @@ } /* write the MBR back to disk */ if (up) - write_mbr(disk, 0, boot0, boot0_size); + write_mbr(disk, 0, boot0, boot0_size, vol_id[4] || b0_ver == 1); /* display the MBR */ if (v_flag) @@ -372,7 +372,8 @@ * Write out the mbr to the specified file. */ static void -write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size) +write_mbr(const char *fname, int flags, u_int8_t *mbr, int mbr_size, + int disable_dsn) { struct gctl_req *grq; const char *errmsg; @@ -417,6 +418,9 @@ gctl_ro_param(grq, "verb", -1, "bootcode"); gctl_ro_param(grq, "bootcode", mbr_size, mbr); gctl_ro_param(grq, "flags", -1, "C"); + if (disable_dsn) + gctl_ro_param(grq, "skip_dsn", sizeof(int), + &disable_dsn); errmsg = gctl_issue(grq); if (errmsg != NULL && errmsg[0] != '\0') errx(1, "GEOM_PART: write bootcode to %s failed: %s",