diff options
author | Geoff Williams <geoff@declarativesystems.com> | 2019-09-22 17:04:42 +1000 |
---|---|---|
committer | Geoff Williams <geoff@declarativesystems.com> | 2019-09-22 22:00:51 +1000 |
commit | d4e560771b8a0fc72538d50b4510a31ab1e00a64 (patch) | |
tree | 89d20a07ed995cb5fd50d22485b8b4c8600801c8 /gptcl.cc | |
parent | 53710d8b51904bd34298ff987b0cbbd89a394b4d (diff) | |
download | sgdisk-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.cc | 20 |
1 files changed, 17 insertions, 3 deletions
@@ -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); |