[Gptfdisk-general] [PATCH] Support padding between Partition Header(LBA1) and Entries(LBA2)
Brought to you by:
srs5694
From: Tzu-Jung L. <roy...@cu...> - 2016-03-22 05:41:17
|
These patch add support to using alternative starting LBA for the Partition Table Entries (default: LBA2). SoC tends to have their constraints on where to load its bootcode. In some cases, those fixed location might conflict with the default layout of GPT (LBA 0/1/2...). I'm not sure if we support "optional" argument. So in order to maintain UI compatibility, we pick currently unused option letters. So current user of option 'o' won't break for the required argument. Signed-off-by: Tzu-Jung Lee <roy...@cu...> diff --git a/gpt.cc b/gpt.cc index d0a46c6..9cb8e7a 100644 --- a/gpt.cc +++ b/gpt.cc @@ -552,7 +552,9 @@ void GPTData::RebuildMainHeader(void) { mainHeader.firstUsableLBA = secondHeader.firstUsableLBA; mainHeader.lastUsableLBA = secondHeader.lastUsableLBA; mainHeader.diskGUID = secondHeader.diskGUID; - mainHeader.partitionEntriesLBA = UINT64_C(2); + mainHeader.partitionEntriesLBA = secondHeader.firstUsableLBA - + ((secondHeader.numParts * GPT_SIZE) / blockSize) - + (((secondHeader.numParts * GPT_SIZE) % blockSize) != 0); mainHeader.numParts = secondHeader.numParts; mainHeader.sizeOfPartitionEntries = secondHeader.sizeOfPartitionEntries; mainHeader.partitionEntriesCRC = secondHeader.partitionEntriesCRC; @@ -773,7 +775,7 @@ int GPTData::LoadPartitions(const string & deviceFilename) { case use_bsd: bsdDisklabel.ReadBSDData(&myDisk, 0, diskSize - 1); // bsdDisklabel.DisplayBSDData(); - ClearGPTData(); + ClearGPTData(GPT_PTE_LBA); protectiveMBR.MakeProtectiveMBR(1); // clear boot area (option 1) XFormDisklabel(&bsdDisklabel); break; @@ -783,7 +785,7 @@ int GPTData::LoadPartitions(const string & deviceFilename) { protectiveMBR.MakeProtectiveMBR(); break; case use_new: - ClearGPTData(); + ClearGPTData(GPT_PTE_LBA); protectiveMBR.MakeProtectiveMBR(); break; case use_abort: @@ -1312,7 +1314,7 @@ int GPTData::LoadGPTBackup(const string & filename) { // Something went badly wrong, so blank out partitions if (allOK == 0) { cerr << "Improper backup file! Clearing all partition data!\n"; - ClearGPTData(); + ClearGPTData(GPT_PTE_LBA); protectiveMBR.MakeProtectiveMBR(); } // if } else { @@ -1336,7 +1338,7 @@ int GPTData::DestroyGPT(void) { uint8_t* emptyTable; memset(blankSector, 0, sizeof(blankSector)); - ClearGPTData(); + ClearGPTData(GPT_PTE_LBA); if (myDisk.OpenForWrite()) { if (!myDisk.Seek(mainHeader.currentLBA)) @@ -1549,7 +1551,7 @@ void GPTData::XFormPartitions(void) { uint8_t origType; // Clear out old data & prepare basics.... - ClearGPTData(); + ClearGPTData(GPT_PTE_LBA); // Convert the smaller of the # of GPT or MBR partitions if (numParts > MAX_MBR_PARTS) @@ -1732,7 +1734,9 @@ int GPTData::SetGPTSize(uint32_t numEntries, int fillGPTSectors) { partitions = newParts; } // if/else existing partitions numParts = numEntries; - mainHeader.firstUsableLBA = ((numEntries * GPT_SIZE) / blockSize) + (((numEntries * GPT_SIZE) % blockSize) != 0) + 2 ; + mainHeader.firstUsableLBA = ((numEntries * GPT_SIZE) / blockSize) + + (((numEntries * GPT_SIZE) % blockSize) != 0) + + mainHeader.partitionEntriesLBA; secondHeader.firstUsableLBA = mainHeader.firstUsableLBA; MoveSecondHeaderToEnd(); if (diskSize > 0) @@ -1836,12 +1840,13 @@ int GPTData::SwapPartitions(uint32_t partNum1, uint32_t partNum2) { // structure, since it may hold the original MBR partitions if the // program was launched on an MBR disk, and those may need to be // converted to GPT format. -int GPTData::ClearGPTData(void) { +int GPTData::ClearGPTData(uint64_t pteSector) { int goOn = 1, i; // Set up the partition table.... delete[] partitions; partitions = NULL; + mainHeader.partitionEntriesLBA = pteSector; SetGPTSize(NUM_GPT_ENTRIES); // Now initialize a bunch of stuff that's static.... @@ -1850,7 +1855,6 @@ int GPTData::ClearGPTData(void) { mainHeader.headerSize = HEADER_SIZE; mainHeader.reserved = 0; mainHeader.currentLBA = UINT64_C(1); - mainHeader.partitionEntriesLBA = (uint64_t) 2; mainHeader.sizeOfPartitionEntries = GPT_SIZE; for (i = 0; i < GPT_RESERVED; i++) { mainHeader.reserved2[i] = '\0'; diff --git a/gpt.h b/gpt.h index e9afd06..8b61536 100644 --- a/gpt.h +++ b/gpt.h @@ -145,7 +145,7 @@ public: uint32_t CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector); void SortGPT(void); int SwapPartitions(uint32_t partNum1, uint32_t partNum2); - int ClearGPTData(void); + int ClearGPTData(uint64_t pteSector); void MoveSecondHeaderToEnd(); int SetName(uint32_t partNum, const UnicodeString & theName); void SetDiskGUID(GUIDData newGUID); diff --git a/gptcl.cc b/gptcl.cc index 7c1d5cf..f5e6340 100644 --- a/gptcl.cc +++ b/gptcl.cc @@ -29,6 +29,7 @@ GPTDataCL::GPTDataCL(void) { attributeOperation = backupFile = partName = hybrids = newPartInfo = NULL; mbrParts = twoParts = outDevice = typeCode = partGUID = diskGUID = NULL; + newHeaderInfo = NULL; alignment = DEFAULT_ALIGNMENT; deletePartNum = infoPartNum = largestPartNum = bsdPartNum = 0; tableSize = GPT_SIZE; @@ -64,7 +65,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { GPTData secondDevice; int opt, numOptions = 0, saveData = 0, neverSaveData = 0; int partNum = 0, newPartNum = -1, saveNonGPT = 1, retval = 0, pretend = 0; - uint64_t low, high, startSector, endSector, sSize; + uint64_t low, high, pteSector, startSector, endSector, sSize; uint64_t temp; // temporary variable; free to use in any case char *device; string cmd, typeGUID, name; @@ -88,6 +89,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { {"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...]"}, {"info", 'i', POPT_ARG_INT, &infoPartNum, 'i', "show detailed information on partition", "partnum"}, + {"init", 'I', POPT_ARG_STRING, &newHeaderInfo, 'I', "init partition table", "[pte_lba]"}, {"load-backup", 'l', POPT_ARG_STRING, &backupFile, 'l', "load GPT backup from file", "file"}, {"list-types", 'L', POPT_ARG_NONE, NULL, 'L', "list known partition types", ""}, {"gpttombr", 'm', POPT_ARG_STRING, &mbrParts, 'm', "convert GPT to MBR", "partnum[:partnum...]"}, @@ -263,6 +265,12 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { case 'i': ShowPartDetails(infoPartNum - 1); break; + case 'I': + JustLooking(0); + pteSector = IeeeToInt(GetString(newHeaderInfo, 1), GetBlockSize(), GPT_PTE_LBA, diskSize, GPT_PTE_LBA); + ClearGPTData(pteSector); + saveData = 1; + break; case 'l': LoadBackupFile(backupFile, saveData, neverSaveData); free(backupFile); @@ -319,7 +327,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { break; case 'o': JustLooking(0); - ClearGPTData(); + ClearGPTData(GPT_PTE_LBA); saveData = 1; break; case 'O': @@ -426,6 +434,14 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { // Do a few types of operations even if there are problems.... while ((opt = poptGetNextOpt(poptCon)) > 0) { switch (opt) { + case 'I': + JustLooking(0); + pteSector = IeeeToInt(GetString(newHeaderInfo, 1), GetBlockSize(), GPT_PTE_LBA, diskSize, GPT_PTE_LBA); + ClearGPTData(pteSector); + saveData = 1; + cout << "Information: Creating fresh partition table; will override earlier problems!\n"; + retval = 0; + break; case 'l': LoadBackupFile(backupFile, saveData, neverSaveData); cout << "Information: Loading backup partition table; will override earlier problems!\n"; @@ -434,7 +450,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { break; case 'o': JustLooking(0); - ClearGPTData(); + ClearGPTData(GPT_PTE_LBA); saveData = 1; cout << "Information: Creating fresh partition table; will override earlier problems!\n"; retval = 0; diff --git a/gptcl.h b/gptcl.h index 610ca5f..f519936 100644 --- a/gptcl.h +++ b/gptcl.h @@ -32,7 +32,7 @@ class GPTDataCL : public GPTData { // Following are variables associated with popt parameters.... char *attributeOperation, *backupFile, *partName, *hybrids; char *newPartInfo, *mbrParts, *twoParts, *outDevice, *typeCode; - char *partGUID, *diskGUID; + char *partGUID, *diskGUID, *newHeaderInfo; int alignment, deletePartNum, infoPartNum, largestPartNum, bsdPartNum; uint32_t tableSize; poptContext poptCon; diff --git a/gpttext.cc b/gpttext.cc index 718b99b..1da4307 100644 --- a/gpttext.cc +++ b/gpttext.cc @@ -579,7 +579,10 @@ void GPTDataTextUI::MainMenu(string filename) { cout << "This option deletes all partitions and creates a new protective MBR.\n" << "Proceed? "; if (GetYN() == 'Y') { - ClearGPTData(); + ostringstream prompt; + prompt << "First sector (" << GPT_PTE_LBA << "-" << diskSize << ", default = " + << GPT_PTE_LBA << ") or {+-}size{KMGTP}: "; + ClearGPTData(GetSectorNum(GPT_PTE_LBA, diskSize, GPT_PTE_LBA, GetBlockSize(), prompt.str())); MakeProtectiveMBR(); } // if break; @@ -811,6 +814,17 @@ void GPTDataTextUI::ExpertsMenu(string filename) { case 'i': case 'I': ShowDetails(); break; + case 'j': case 'J': + cout << "This option deletes all partitions and creates a new protective MBR.\n" + << "Proceed? "; + if (GetYN() == 'Y') { + ostringstream prompt; + prompt << "First sector (" << GPT_PTE_LBA << "-" << diskSize << ", default = " + << GPT_PTE_LBA << ") or {+-}size{KMGTP}: "; + ClearGPTData(GetSectorNum(GPT_PTE_LBA, diskSize, GPT_PTE_LBA, GetBlockSize(), prompt.str())); + MakeProtectiveMBR(); + } // if + break; case 'l': case 'L': prompt.seekp(0); prompt << "Enter the sector alignment value (1-" << MAX_ALIGNMENT << ", default = " @@ -881,6 +895,7 @@ void GPTDataTextUI::ShowExpertCommands(void) { cout << "g\tchange disk GUID\n"; cout << "h\trecompute CHS values in protective/hybrid MBR\n"; cout << "i\tshow detailed information on a partition\n"; + cout << "j\tcreate a new empty GUID partition table (GPT)\n"; cout << "l\tset the sector alignment value\n"; cout << "m\treturn to main menu\n"; cout << "n\tcreate a new protective MBR\n"; diff --git a/support.h b/support.h index b888d92..9714c44 100644 --- a/support.h +++ b/support.h @@ -65,6 +65,7 @@ // Number and size of GPT entries... #define NUM_GPT_ENTRIES 128 #define GPT_SIZE 128 +#define GPT_PTE_LBA 2 #define HEADER_SIZE UINT32_C(92) #define GPT_RESERVED 420 #define NAME_SIZE 36 // GPT allows 36 UTF-16LE code units for a name in a 128 byte partition entry -- 2.7.3 |