builder: disk: layout: gpt: add initial hybrid support

Signed-off-by: BigfootACA <bigfoot@classfun.cn>
This commit is contained in:
BigfootACA 2024-05-21 11:21:48 +08:00
parent 085715236f
commit 4ebe85afb6
2 changed files with 32 additions and 1 deletions

View File

@ -100,6 +100,10 @@ class DiskLayoutGPT(DiskLayout):
puuid = UUID(config["puuid"]) if "puuid" in config else None puuid = UUID(config["puuid"]) if "puuid" in config else None
part = self.add_partition(ptype, area=area, name=pname, uuid=puuid) part = self.add_partition(ptype, area=area, name=pname, uuid=puuid)
if part: if part:
if "hybrid" in config:
part.hybrid = True
if "bootable" in config:
part.bootable = True
if "attributes" in config: if "attributes" in config:
part.attributes = config["attributes"] part.attributes = config["attributes"]
return part return part
@ -248,13 +252,20 @@ class DiskLayoutGPT(DiskLayout):
size = MasterBootRecord.boot_code.size size = MasterBootRecord.boot_code.size
code = bytes_pad(self.boot_code, size, trunc=True) code = bytes_pad(self.boot_code, size, trunc=True)
ctypes.memmove(new_pmbr.boot_code, code, size) ctypes.memmove(new_pmbr.boot_code, code, size)
idx = 0
for part in self.partitions:
if not part.hybrid: continue
if idx >= 3: raise RuntimeError("Hybrid partition to many")
ppart = part.to_mbr_entry()
new_pmbr.partitions[idx] = ppart
idx += 1
ppart = MbrPartEntry() ppart = MbrPartEntry()
ppart.start_lba = 1 ppart.start_lba = 1
ppart.size_lba = self.total_lba - 1 ppart.size_lba = self.total_lba - 1
ppart.start_head, ppart.start_track, ppart.start_sector = 0, 0, 2 ppart.start_head, ppart.start_track, ppart.start_sector = 0, 0, 2
ppart.end_head, ppart.end_track, ppart.end_sector = 255, 255, 255 ppart.end_head, ppart.end_track, ppart.end_sector = 255, 255, 255
ppart.set_type("gpt") ppart.set_type("gpt")
new_pmbr.partitions[0] = ppart new_pmbr.partitions[idx] = ppart
return new_pmbr return new_pmbr
def create_gpt_entries(self) -> bytes: def create_gpt_entries(self) -> bytes:

View File

@ -2,15 +2,20 @@ from uuid import UUID
from logging import getLogger from logging import getLogger
from builder.disk.layout.layout import DiskLayout, DiskPart from builder.disk.layout.layout import DiskLayout, DiskPart
from builder.disk.layout.gpt.struct import EfiPartEntry from builder.disk.layout.gpt.struct import EfiPartEntry
from builder.disk.layout.mbr.struct import MbrPartEntry
from builder.disk.layout.gpt.types import DiskTypesGPT from builder.disk.layout.gpt.types import DiskTypesGPT
from builder.disk.layout.mbr.types import DiskTypesMBR
from builder.disk.layout.gpt.uefi import EfiGUID from builder.disk.layout.gpt.uefi import EfiGUID
log = getLogger(__name__) log = getLogger(__name__)
class DiskPartGPT(DiskPart): class DiskPartGPT(DiskPart):
layout: DiskLayout layout: DiskLayout
mbr_type: int
type_uuid: UUID type_uuid: UUID
bootable: bool
uuid: UUID uuid: UUID
hybrid: bool
idx: int idx: int
_part_name: str _part_name: str
_attributes: int _attributes: int
@ -40,6 +45,10 @@ class DiskPartGPT(DiskPart):
tid = DiskTypesGPT.lookup_one_uuid(val) tid = DiskTypesGPT.lookup_one_uuid(val)
if tid is None: raise ValueError(f"unknown type {val}") if tid is None: raise ValueError(f"unknown type {val}")
self.type_uuid = tid self.type_uuid = tid
if self.hybrid:
tid = DiskTypesMBR.lookup_one_id(val)
if tid is None: raise ValueError(f"unknown type {val}")
self.mbr_type = tid
@property @property
def start_lba(self) -> int: def start_lba(self) -> int:
@ -99,6 +108,14 @@ class DiskPartGPT(DiskPart):
part.set_part_name(self.part_name) part.set_part_name(self.part_name)
return part return part
def to_mbr_entry(self) -> MbrPartEntry:
part = MbrPartEntry()
part.set_bootable(self.bootable)
part.set_type(self.mbr_type)
part.set_start_lba(self.start_lba)
part.set_size_lba(self.size_lba)
return part
def __init__( def __init__(
self, self,
layout: DiskLayout, layout: DiskLayout,
@ -108,7 +125,10 @@ class DiskPartGPT(DiskPart):
super().__init__() super().__init__()
self.layout = layout self.layout = layout
self.idx = idx self.idx = idx
self.hybrid = False
self.bootable = False
self.part_name = None self.part_name = None
self.mbr_type = 0
self.start_lba = 0 self.start_lba = 0
self.end_lba = 0 self.end_lba = 0
self.attributes = 0 self.attributes = 0