Merge pull request #513 from bongbui321/fix_setactiveslot

Fix setactiveslot by sending multiple patch chunks
This commit is contained in:
Bjoern Kerler 2024-03-06 08:30:48 +01:00 committed by GitHub
commit 3bfb87f663
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 26 deletions

View file

@ -1303,6 +1303,26 @@ class firehose(metaclass=LogBase):
return None return None
def cmd_setactiveslot(self, slot: str): def cmd_setactiveslot(self, slot: str):
def cmd_patch_multiple(lun, start_sector_patch, byte_offset_patch, headeroffset, pdata, header):
offset = 0
header_size = len(header)
size_each_patch = 4
write_size = len(pdata)
for i in range(0, write_size, size_each_patch):
pdata_subset = int(unpack("<I", pdata[offset:offset+size_each_patch])[0])
self.cmd_patch( lun, start_sector_patch, \
byte_offset_patch + offset, \
pdata_subset, \
size_each_patch, True)
if i < header_size:
header_subset = int(unpack("<I", header[offset:offset+size_each_patch])[0])
self.cmd_patch( lun, headeroffset, \
offset, \
header_subset, \
size_each_patch, True)
offset += size_each_patch
return True
if slot.lower() not in ["a", "b"]: if slot.lower() not in ["a", "b"]:
self.error("Only slots a or b are accepted. Aborting.") self.error("Only slots a or b are accepted. Aborting.")
return False return False
@ -1314,30 +1334,34 @@ class firehose(metaclass=LogBase):
partslots["_a"] = False partslots["_a"] = False
partslots["_b"] = True partslots["_b"] = True
fpartitions = {} fpartitions = {}
for lun in self.luns: try:
lunname = "Lun" + str(lun) for lun in self.luns:
fpartitions[lunname] = [] lunname = "Lun" + str(lun)
data, guid_gpt = self.get_gpt(lun, int(0), int(0), int(0)) fpartitions[lunname] = []
if guid_gpt is None: data, guid_gpt = self.get_gpt(lun, int(0), int(0), int(0))
break if guid_gpt is None:
else: break
for partitionname in guid_gpt.partentries: else:
gp = gpt() for partitionname in guid_gpt.partentries:
slot = partitionname.lower()[-2:] gp = gpt()
if "_a" in slot or "_b" in slot: slot = partitionname.lower()[-2:]
pdata, poffset = gp.patch(data, partitionname, active=partslots[slot]) if "_a" in slot or "_b" in slot:
data[poffset:poffset + len(pdata)] = pdata pdata, poffset = gp.patch(data, partitionname, active=partslots[slot])
wdata = gp.fix_gpt_crc(data) data[poffset:poffset + len(pdata)] = pdata
if wdata is not None: wdata = gp.fix_gpt_crc(data)
start_sector_patch = poffset // self.cfg.SECTOR_SIZE_IN_BYTES if wdata is not None:
byte_offset_patch = poffset % self.cfg.SECTOR_SIZE_IN_BYTES start_sector_patch = poffset // self.cfg.SECTOR_SIZE_IN_BYTES
headeroffset = gp.header.current_lba * gp.sectorsize byte_offset_patch = poffset % self.cfg.SECTOR_SIZE_IN_BYTES
start_sector_hdr = headeroffset // self.cfg.SECTOR_SIZE_IN_BYTES headeroffset = gp.header.current_lba * gp.sectorsize
header = wdata[start_sector_hdr:start_sector_hdr + gp.header.header_size] start_sector_hdr = headeroffset // self.cfg.SECTOR_SIZE_IN_BYTES
self.cmd_patch(lun, start_sector_patch, byte_offset_patch, pdata, len(pdata), True) header = wdata[start_sector_hdr:start_sector_hdr + gp.header.header_size]
self.cmd_patch(lun, headeroffset, 0, header, len(pdata), True) cmd_patch_multiple(lun, start_sector_patch, byte_offset_patch, headeroffset, pdata, header)
return True except Exception as err:
return False self.error(str(err))
return False
return True
def cmd_test(self, cmd): def cmd_test(self, cmd):
token = "1234" token = "1234"

View file

@ -224,7 +224,7 @@ class gpt(metaclass=LogBase):
self.name = sh.string(72) self.name = sh.string(72)
def create(self): def create(self):
val = pack("16s16sQQQ72s", self.type, self.unique, self.first_lba, self.last_lba, self.flags, self.name) val = pack("<16s16sQQQ72s", self.type, self.unique, self.first_lba, self.last_lba, self.flags, self.name)
return val return val
class efi_type(Enum): class efi_type(Enum):
@ -498,7 +498,7 @@ class gpt(metaclass=LogBase):
if active: if active:
flags |= AB_PARTITION_ATTR_SLOT_ACTIVE << (AB_FLAG_OFFSET*8) flags |= AB_PARTITION_ATTR_SLOT_ACTIVE << (AB_FLAG_OFFSET*8)
else: else:
flags |= AB_PARTITION_ATTR_UNBOOTABLE << (AB_FLAG_OFFSET*8) flags &= AB_PARTITION_ATTR_UNBOOTABLE << (AB_FLAG_OFFSET*8)
partentry.flags = flags partentry.flags = flags
pdata = partentry.create() pdata = partentry.create()
return pdata, partition.entryoffset return pdata, partition.entryoffset