Module Name: src Committed By: jakllsch Date: Wed Aug 17 00:04:42 UTC 2011
Modified Files: src/sbin/gpt: biosboot.c Log Message: Switch 'gpt biosboot' to support T13 EDD-4 annex A GPT hybrid MBR instead of a home-grown MBR/VBR hand off protocol. 'biosboot' now will set the legacy BIOS boot flag instead of patching a GUID into the MBR. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sbin/gpt/biosboot.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/gpt/biosboot.c diff -u src/sbin/gpt/biosboot.c:1.1 src/sbin/gpt/biosboot.c:1.2 --- src/sbin/gpt/biosboot.c:1.1 Thu Jan 6 01:08:48 2011 +++ src/sbin/gpt/biosboot.c Wed Aug 17 00:04:41 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: biosboot.c,v 1.1 2011/01/06 01:08:48 jakllsch Exp $ */ +/* $NetBSD: biosboot.c,v 1.2 2011/08/17 00:04:41 jakllsch Exp $ */ /* * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #include <sys/cdefs.h> #ifdef __RCSID -__RCSID("$NetBSD: biosboot.c,v 1.1 2011/01/06 01:08:48 jakllsch Exp $"); +__RCSID("$NetBSD: biosboot.c,v 1.2 2011/08/17 00:04:41 jakllsch Exp $"); #endif #include <sys/stat.h> @@ -66,8 +66,6 @@ static char *bootpath; static unsigned int entry; -const uuid_t uuid_mbr_guid_default = MBR_GPT_GUID_DEFAULT; - const char biosbootmsg[] = "biosboot [-c bootcode] [-i index] device ..."; static void @@ -83,7 +81,6 @@ int bfd, ret = 0; struct mbr *buf; struct stat st; - uuid_t uuid_patch_magic; /* XXX how to do the following better? */ if (bootpath == NULL) { @@ -109,34 +106,17 @@ goto fail; } - if (st.st_size != secsz) { - warnx("%s: the bootcode does not match '%s' sector size", - bootpath, device_name); + if (st.st_size != MBR_DSN_OFFSET) { + warnx("%s: the bootcode does not match expected size", + bootpath); goto fail; } - if (read(bfd, buf, secsz) != st.st_size) { + if (read(bfd, buf, st.st_size) != st.st_size) { warn("%s", bootpath); goto fail; } - if (le32toh(buf->mbr_sig) != MBR_SIG) { - warnx("%s: invalid MBR magic", bootpath); - goto fail; - } - - uuid_dec_le(&buf->mbr_code[MBR_GPT_GUID_OFFSET], &uuid_patch_magic); - - /* - * The loader have to contain some magic in patchable area, - * such we can be sure that we won't trash something important - */ - if (!uuid_equal(&uuid_patch_magic, &uuid_mbr_guid_default, NULL)) { - warnx("%s: the bootcode does not support required options", - bootpath); - goto fail; - } - ret++; fail: @@ -156,8 +136,9 @@ map_t *tbl, *lbt; map_t *mbrmap, *m; struct mbr *mbr, *bootcode; - struct gpt_ent *pp; - uuid_t buuid; + struct gpt_hdr *hdr; + struct gpt_ent *ent; + int i; /* * Parse and validate partition maps @@ -209,7 +190,7 @@ if (m->map_type != MAP_TYPE_GPT_PART || m->map_index < 1) continue; - pp = m->map_data; + ent = m->map_data; /* first, prefer user selection */ if (entry > 0 && m->map_index == entry) @@ -224,23 +205,49 @@ if (m == NULL) { warnx("error: no bootable partition"); return; - } else - uuid_dec_le(pp->ent_guid, &buuid); + } + + i = m->map_index - 1; -#if 1 - { - char *p; - - uuid_to_string(&buuid, &p, NULL); - printf("Boot device: %s\n", device_name); - printf("Partition GUID: %s\n", p); - printf("Boot code: %s\n", bootpath); - free(p); + hdr = gpt->map_data; + + for (int j = 0; j < le32toh(hdr->hdr_entries); j++) { + ent = (void*)((char*)tbl->map_data + j * le32toh(hdr->hdr_entsz)); + ent->ent_attr &= ~GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE; } -#endif - uuid_enc_le(&mbr->mbr_code[MBR_GPT_GUID_OFFSET], &buuid); + ent = (void*)((char*)tbl->map_data + i * le32toh(hdr->hdr_entsz)); + ent->ent_attr |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE; + + hdr->hdr_crc_table = htole32(crc32(tbl->map_data, + le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz))); + hdr->hdr_crc_self = 0; + hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size))); + + gpt_write(fd, gpt); + gpt_write(fd, tbl); + + + hdr = tpg->map_data; + + for (int j = 0; j < le32toh(hdr->hdr_entries); j++) { + ent = (void*)((char*)lbt->map_data + j * le32toh(hdr->hdr_entsz)); + ent->ent_attr &= ~GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE; + } + + ent = (void*)((char*)lbt->map_data + i * le32toh(hdr->hdr_entsz)); + ent->ent_attr |= GPT_ENT_ATTR_LEGACY_BIOS_BOOTABLE; + + hdr->hdr_crc_table = htole32(crc32(lbt->map_data, + le32toh(hdr->hdr_entries) * le32toh(hdr->hdr_entsz))); + hdr->hdr_crc_self = 0; + hdr->hdr_crc_self = htole32(crc32(hdr, le32toh(hdr->hdr_size))); + + gpt_write(fd, lbt); + gpt_write(fd, tpg); + + if (gpt_write(fd, mbrmap) == -1) { warnx("error: cannot update Protective MBR"); return;