summaryrefslogtreecommitdiff
path: root/gptcl.cc
diff options
context:
space:
mode:
authorGeoff Williams <geoff@declarativesystems.com>2019-09-22 17:04:42 +1000
committerGeoff Williams <geoff@declarativesystems.com>2019-09-22 22:00:51 +1000
commitd4e560771b8a0fc72538d50b4510a31ab1e00a64 (patch)
tree89d20a07ed995cb5fd50d22485b8b4c8600801c8 /gptcl.cc
parent53710d8b51904bd34298ff987b0cbbd89a394b4d (diff)
downloadsgdisk-d4e560771b8a0fc72538d50b4510a31ab1e00a64.tar.gz
Support placing GPT last when for hybrid MBR
Some hardware (notably Raspberry PI) requires a small FAT partition be listed as the first MBR partition to boot. At the moment hybrid MBR disks allowing this can only be made using the interactive `gdisk` program by choosing `h` from the recovery menu and answering `N` when asked: ``` Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? ``` This commit brings feature parity to `sgdisk` by changing `-h` to support an optional final partition `EE` indicating that the GPT partition should be listed last in the MBR instead of first. **Examples**: GPT first (current behaviour) ```shell sgdisk -h 1:2 sdcard.img ``` GPT last ```shell sgdisk -h 1:2:EE sdcard.img ```
Diffstat (limited to 'gptcl.cc')
-rw-r--r--gptcl.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/gptcl.cc b/gptcl.cc
index 6c36738..70c3352 100644
--- a/gptcl.cc
+++ b/gptcl.cc
@@ -86,7 +86,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
{"first-aligned-in-largest", 'F', POPT_ARG_NONE, NULL, 'F', "show start of the largest free block, aligned", ""},
{"mbrtogpt", 'g', POPT_ARG_NONE, NULL, 'g', "convert MBR to GPT", ""},
{"randomize-guids", 'G', POPT_ARG_NONE, NULL, 'G', "randomize disk and partition GUIDs", ""},
- {"hybrid", 'h', POPT_ARG_STRING, &hybrids, 'h', "create hybrid MBR", "partnum[:partnum...]"},
+ {"hybrid", 'h', POPT_ARG_STRING, &hybrids, 'h', "create hybrid MBR", "partnum[:partnum...][:EE]"},
{"info", 'i', POPT_ARG_INT, &infoPartNum, 'i', "show detailed information on partition", "partnum"},
{"move-main-table", 'j', POPT_ARG_INT, &mainTableLBA, 'j', "adjust the location of the main partition table", "sector"},
{"load-backup", 'l', POPT_ARG_STRING, &backupFile, 'l', "load GPT backup from file", "file"},
@@ -490,33 +490,47 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
// Create a hybrid or regular MBR from GPT data structures
int GPTDataCL::BuildMBR(char* argument, int isHybrid) {
int numParts, allOK = 1, i, origPartNum;
+ int eeLast, mbrNum = 0;
MBRPart newPart;
BasicMBRData newMBR;
if (argument != NULL) {
numParts = CountColons(argument) + 1;
+ if (isHybrid) {
+ eeLast = GetString(argument, numParts) == "EE";
+ if (eeLast) {
+ numParts--;
+ }
+ }
+
if (numParts <= (4 - isHybrid)) {
newMBR.SetDisk(GetDisk());
for (i = 0; i < numParts; i++) {
origPartNum = GetInt(argument, i + 1) - 1;
if (IsUsedPartNum(origPartNum) && (partitions[origPartNum].IsSizedForMBR() == MBR_SIZED_GOOD)) {
+ mbrNum = i + (isHybrid && ! eeLast);
newPart.SetInclusion(PRIMARY);
newPart.SetLocation(operator[](origPartNum).GetFirstLBA(),
operator[](origPartNum).GetLengthLBA());
newPart.SetStatus(0);
newPart.SetType((uint8_t)(operator[](origPartNum).GetHexType() / 0x0100));
- newMBR.AddPart(i + isHybrid, newPart);
+ newMBR.AddPart(mbrNum, newPart);
} else {
cerr << "Original partition " << origPartNum + 1 << " does not exist or is too big! Aborting operation!\n";
allOK = 0;
} // if/else
} // for
if (isHybrid) {
+ if (eeLast) {
+ mbrNum = i;
+ } else {
+ mbrNum = 0;
+ }
newPart.SetInclusion(PRIMARY);
newPart.SetLocation(1, newMBR.FindLastInFree(1));
newPart.SetStatus(0);
newPart.SetType(0xEE);
- newMBR.AddPart(0, newPart);
+ newMBR.AddPart(mbrNum, newPart);
} // if
if (allOK)
SetProtectiveMBR(newMBR);