Add support for generation 1
On generation 1 (ME version <= 5), Intel ME can be disabled completely by: * Wiping its firmware * Disabling the corresponding region * Setting the meDisable bits in ICHSTRP0 and MCHSTRP0 Optionally, with the usual -d flag, me_cleaner can remove the ME's RW permissions to the other regions (but it probably has no effect, Intel ME is disabled anyways). Based on ich9deblob from the libreboot project.
This commit is contained in:
parent
d5b0806cdf
commit
57b3fc765e
2 changed files with 198 additions and 133 deletions
21
README.md
21
README.md
|
@ -56,16 +56,19 @@ SPI programmer.
|
||||||
|
|
||||||
## Results
|
## Results
|
||||||
|
|
||||||
For pre-Skylake firmware (ME version < 11) this tool removes almost everything,
|
For generation 1 (before Nehalem, ME version <= 5) this tool removes the whole
|
||||||
leaving only the two fundamental modules needed for the correct boot, `ROMP` and
|
ME firmware and disables it completely.
|
||||||
`BUP`. The code size is reduced from 1.5 MB (non-AMT firmware) or 5 MB (AMT
|
|
||||||
firmware) to ~90 kB of compressed code.
|
|
||||||
|
|
||||||
Starting from Skylake (ME version >= 11) the ME subsystem and the firmware
|
For generation 2 (Nehalem-Broadwell, ME version between 6 and 10) this tool
|
||||||
structure have changed, requiring substantial changes in _me\_cleaner_.
|
removes almost everything, leaving only the two fundamental modules needed for
|
||||||
The fundamental modules required for the correct boot are now four (`rbe`,
|
the correct boot, `ROMP` and `BUP`. The firmware size is reduced from 1.5 MB
|
||||||
`kernel`, `syslib` and `bup`) and the minimum code size is ~300 kB of compressed
|
(non-AMT firmware) or 5 MB (AMT firmware) to ~90 kB.
|
||||||
code (from the 2 MB of the non-AMT firmware and the 7 MB of the AMT one).
|
|
||||||
|
For generation 3 (from Skylake onwards, ME version >= 11) the ME subsystem and
|
||||||
|
the firmware structure have changed, requiring substantial changes
|
||||||
|
in _me\_cleaner_. The fundamental modules required for the correct boot are now
|
||||||
|
four (`rbe`, `kernel`, `syslib` and `bup`) and the minimum firmware size is
|
||||||
|
~300 kB (from the 2 MB of the non-AMT firmware and the 7 MB of the AMT one).
|
||||||
|
|
||||||
On some boards the OEM firmware fails to boot without a valid Intel ME firmware;
|
On some boards the OEM firmware fails to boot without a valid Intel ME firmware;
|
||||||
in the other cases the system should work with minor inconveniences (like longer
|
in the other cases the system should work with minor inconveniences (like longer
|
||||||
|
|
166
me_cleaner.py
166
me_cleaner.py
|
@ -28,10 +28,16 @@ from struct import pack, unpack
|
||||||
min_ftpr_offset = 0x400
|
min_ftpr_offset = 0x400
|
||||||
spared_blocks = 4
|
spared_blocks = 4
|
||||||
unremovable_modules = ("ROMP", "BUP")
|
unremovable_modules = ("ROMP", "BUP")
|
||||||
unremovable_modules_me11 = ("rbe", "kernel", "syslib", "bup")
|
unremovable_modules_gen3 = ("rbe", "kernel", "syslib", "bup")
|
||||||
unremovable_partitions = ("FTPR",)
|
unremovable_partitions = ("FTPR",)
|
||||||
|
|
||||||
pubkeys_md5 = {
|
pubkeys_md5 = {
|
||||||
|
"8431285d43b0f2a2f520d7cab3d34178": ("ME", ("2.0.x.x", "2.1.x.x",
|
||||||
|
"2.2.x.x")),
|
||||||
|
"4c00dd06c28119b5c1e5bb8eb6f30596": ("ME", ("2.5.x.x", "2.6.x.x")),
|
||||||
|
"9c24077a7f7490967855e9c4c16c6b9e": ("ME", ("3.x.x.x",)),
|
||||||
|
"bf41464be736f5520d80c67f6789020e": ("ME", ("4.x.x.x",)),
|
||||||
|
"5c7169b7e7065323fb7b3b5657b4d57a": ("ME", ("5.x.x.x",)),
|
||||||
"763e59ebe235e45a197a5b1a378dfa04": ("ME", ("6.x.x.x",)),
|
"763e59ebe235e45a197a5b1a378dfa04": ("ME", ("6.x.x.x",)),
|
||||||
"3a98c847d609c253e145bd36512629cb": ("ME", ("6.0.50.x",)),
|
"3a98c847d609c253e145bd36512629cb": ("ME", ("6.0.50.x",)),
|
||||||
"0903fc25b0f6bed8c4ed724aca02124c": ("ME", ("7.x.x.x", "8.x.x.x")),
|
"0903fc25b0f6bed8c4ed724aca02124c": ("ME", ("7.x.x.x", "8.x.x.x")),
|
||||||
|
@ -384,7 +390,7 @@ def check_and_remove_modules(f, me_end, offset, min_offset,
|
||||||
return -1, offset
|
return -1, offset
|
||||||
|
|
||||||
|
|
||||||
def check_and_remove_modules_me11(f, me_end, partition_offset,
|
def check_and_remove_modules_gen3(f, me_end, partition_offset,
|
||||||
partition_length, min_offset, relocate,
|
partition_length, min_offset, relocate,
|
||||||
keep_modules):
|
keep_modules):
|
||||||
|
|
||||||
|
@ -431,7 +437,7 @@ def check_and_remove_modules_me11(f, me_end, partition_offset,
|
||||||
print("NOT removed, partition manif.")
|
print("NOT removed, partition manif.")
|
||||||
elif name.endswith(".met"):
|
elif name.endswith(".met"):
|
||||||
print("NOT removed, module metadata")
|
print("NOT removed, module metadata")
|
||||||
elif any(name.startswith(m) for m in unremovable_modules_me11):
|
elif any(name.startswith(m) for m in unremovable_modules_gen3):
|
||||||
print("NOT removed, essential")
|
print("NOT removed, essential")
|
||||||
else:
|
else:
|
||||||
removed = True
|
removed = True
|
||||||
|
@ -449,10 +455,11 @@ def check_and_remove_modules_me11(f, me_end, partition_offset,
|
||||||
return end_data, partition_offset
|
return end_data, partition_offset
|
||||||
|
|
||||||
|
|
||||||
def check_mn2_tag(f, offset):
|
def check_mn2_tag(f, offset, gen):
|
||||||
f.seek(offset + 0x1c)
|
f.seek(offset + 0x1c)
|
||||||
tag = f.read(4)
|
tag = f.read(4)
|
||||||
if tag != b"$MN2":
|
expected_tag = b"$MAN" if gen == 1 else b"$MN2"
|
||||||
|
if tag != expected_tag:
|
||||||
sys.exit("Wrong FTPR manifest tag ({}), this image may be corrupted"
|
sys.exit("Wrong FTPR manifest tag ({}), this image may be corrupted"
|
||||||
.format(tag))
|
.format(tag))
|
||||||
|
|
||||||
|
@ -536,11 +543,14 @@ if __name__ == "__main__":
|
||||||
sys.exit("Relocation is not yet supported with custom whitelist or "
|
sys.exit("Relocation is not yet supported with custom whitelist or "
|
||||||
"blacklist")
|
"blacklist")
|
||||||
|
|
||||||
f = open(args.file, "rb" if args.check or args.output else "r+b")
|
gen = None
|
||||||
f.seek(0x10)
|
|
||||||
magic = f.read(4)
|
|
||||||
|
|
||||||
if magic == b"$FPT":
|
f = open(args.file, "rb" if args.check or args.output else "r+b")
|
||||||
|
magic0 = f.read(4)
|
||||||
|
f.seek(0x10)
|
||||||
|
magic10 = f.read(4)
|
||||||
|
|
||||||
|
if b"$FPT" in {magic0, magic10}:
|
||||||
print("ME/TXE image detected")
|
print("ME/TXE image detected")
|
||||||
|
|
||||||
if args.descriptor or args.extract_descriptor or args.extract_me or \
|
if args.descriptor or args.extract_descriptor or args.extract_me or \
|
||||||
|
@ -552,17 +562,20 @@ if __name__ == "__main__":
|
||||||
me_end = f.tell()
|
me_end = f.tell()
|
||||||
mef = RegionFile(f, me_start, me_end)
|
mef = RegionFile(f, me_start, me_end)
|
||||||
|
|
||||||
elif magic == b"\x5a\xa5\xf0\x0f":
|
elif b"\x5a\xa5\xf0\x0f" in {magic0, magic10}:
|
||||||
print("Full image detected")
|
print("Full image detected")
|
||||||
|
|
||||||
if args.truncate and not args.extract_me:
|
f.seek(0x4 if magic0 == b"\x5a\xa5\xf0\x0f" else 0x14)
|
||||||
sys.exit("-t requires a separated ME/TXE image (or --extract-me)")
|
flmap0, flmap1, flmap2 = unpack("<III", f.read(0xc))
|
||||||
|
|
||||||
f.seek(0x14)
|
|
||||||
flmap0, flmap1 = unpack("<II", f.read(8))
|
|
||||||
frba = flmap0 >> 12 & 0xff0
|
frba = flmap0 >> 12 & 0xff0
|
||||||
fmba = (flmap1 & 0xff) << 4
|
fmba = (flmap1 & 0xff) << 4
|
||||||
fpsba = flmap1 >> 12 & 0xff0
|
|
||||||
|
# Generation 1
|
||||||
|
fisba = flmap1 >> 12 & 0xff0
|
||||||
|
fmsba = (flmap2 & 0xff) << 4
|
||||||
|
|
||||||
|
# Generation 2-3
|
||||||
|
fpsba = fisba
|
||||||
|
|
||||||
f.seek(frba)
|
f.seek(frba)
|
||||||
flreg = unpack("<III", f.read(12))
|
flreg = unpack("<III", f.read(12))
|
||||||
|
@ -572,39 +585,59 @@ if __name__ == "__main__":
|
||||||
me_start, me_end = flreg_to_start_end(flreg[2])
|
me_start, me_end = flreg_to_start_end(flreg[2])
|
||||||
|
|
||||||
if me_start >= me_end:
|
if me_start >= me_end:
|
||||||
sys.exit("The ME/TXE region in this image has been disabled")
|
print("The ME region in this image has already been disabled")
|
||||||
|
else:
|
||||||
mef = RegionFile(f, me_start, me_end)
|
mef = RegionFile(f, me_start, me_end)
|
||||||
|
|
||||||
mef.seek(0x10)
|
if magic0 == b"\x5a\xa5\xf0\x0f":
|
||||||
if mef.read(4) != b"$FPT":
|
gen = 1
|
||||||
sys.exit("The ME/TXE region is corrupted or missing")
|
|
||||||
|
|
||||||
print("The ME/TXE region goes from {:#x} to {:#x}"
|
|
||||||
.format(me_start, me_end))
|
|
||||||
else:
|
else:
|
||||||
sys.exit("Unknown image")
|
sys.exit("Unknown image")
|
||||||
|
|
||||||
|
if me_start < me_end:
|
||||||
|
mef.seek(0)
|
||||||
|
if mef.read(4) == b"$FPT":
|
||||||
|
fpt_offset = 0
|
||||||
|
else:
|
||||||
|
mef.seek(0x10)
|
||||||
|
if mef.read(4) == b"$FPT":
|
||||||
|
fpt_offset = 0x10
|
||||||
|
else:
|
||||||
|
if me_start > 0:
|
||||||
|
sys.exit("The ME/TXE region is valid but the firmware is "
|
||||||
|
"corrupted or missing")
|
||||||
|
else:
|
||||||
|
sys.exit("Unknown error")
|
||||||
|
|
||||||
|
if gen == 1:
|
||||||
|
end_addr = 0
|
||||||
|
else:
|
||||||
end_addr = me_end
|
end_addr = me_end
|
||||||
|
|
||||||
print("Found FPT header at {:#x}".format(mef.region_start + 0x10))
|
if me_start < me_end:
|
||||||
|
print("Found FPT header at {:#x}".format(mef.region_start + fpt_offset))
|
||||||
|
|
||||||
mef.seek(0x14)
|
mef.seek(fpt_offset + 0x4)
|
||||||
entries = unpack("<I", mef.read(4))[0]
|
entries = unpack("<I", mef.read(4))[0]
|
||||||
print("Found {} partition(s)".format(entries))
|
print("Found {} partition(s)".format(entries))
|
||||||
|
|
||||||
mef.seek(0x30)
|
mef.seek(fpt_offset + 0x20)
|
||||||
partitions = mef.read(entries * 0x20)
|
partitions = mef.read(entries * 0x20)
|
||||||
|
|
||||||
ftpr_header = b""
|
ftpr_header = b""
|
||||||
|
|
||||||
for i in range(entries):
|
for i in range(entries):
|
||||||
if partitions[i * 0x20:(i * 0x20) + 4] == b"FTPR":
|
if partitions[i * 0x20:(i * 0x20) + 4] in {b"CODE", b"FTPR"}:
|
||||||
ftpr_header = partitions[i * 0x20:(i + 1) * 0x20]
|
ftpr_header = partitions[i * 0x20:(i + 1) * 0x20]
|
||||||
break
|
break
|
||||||
|
|
||||||
if ftpr_header == b"":
|
if ftpr_header == b"":
|
||||||
sys.exit("FTPR header not found, this image doesn't seem to be valid")
|
sys.exit("FTPR header not found, this image doesn't seem to be "
|
||||||
|
"valid")
|
||||||
|
|
||||||
|
if ftpr_header[0x0:0x4] == b"CODE":
|
||||||
|
gen = 1
|
||||||
|
|
||||||
ftpr_offset, ftpr_length = unpack("<II", ftpr_header[0x08:0x10])
|
ftpr_offset, ftpr_length = unpack("<II", ftpr_header[0x08:0x10])
|
||||||
print("Found FTPR header: FTPR partition spans from {:#x} to {:#x}"
|
print("Found FTPR header: FTPR partition spans from {:#x} to {:#x}"
|
||||||
|
@ -612,7 +645,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
mef.seek(ftpr_offset)
|
mef.seek(ftpr_offset)
|
||||||
if mef.read(4) == b"$CPD":
|
if mef.read(4) == b"$CPD":
|
||||||
me11 = True
|
gen = 3
|
||||||
num_entries = unpack("<I", mef.read(4))[0]
|
num_entries = unpack("<I", mef.read(4))[0]
|
||||||
|
|
||||||
mef.seek(ftpr_offset + 0x10)
|
mef.seek(ftpr_offset + 0x10)
|
||||||
|
@ -628,21 +661,22 @@ if __name__ == "__main__":
|
||||||
break
|
break
|
||||||
|
|
||||||
if ftpr_mn2_offset >= 0:
|
if ftpr_mn2_offset >= 0:
|
||||||
check_mn2_tag(mef, ftpr_offset + ftpr_mn2_offset)
|
check_mn2_tag(mef, ftpr_offset + ftpr_mn2_offset, gen)
|
||||||
print("Found FTPR manifest at {:#x}"
|
print("Found FTPR manifest at {:#x}"
|
||||||
.format(ftpr_offset + ftpr_mn2_offset))
|
.format(ftpr_offset + ftpr_mn2_offset))
|
||||||
else:
|
else:
|
||||||
sys.exit("Can't find the manifest of the FTPR partition")
|
sys.exit("Can't find the manifest of the FTPR partition")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
check_mn2_tag(mef, ftpr_offset)
|
check_mn2_tag(mef, ftpr_offset, gen)
|
||||||
me11 = False
|
|
||||||
ftpr_mn2_offset = 0
|
ftpr_mn2_offset = 0
|
||||||
|
if not gen:
|
||||||
|
gen = 2
|
||||||
|
|
||||||
mef.seek(ftpr_offset + ftpr_mn2_offset + 0x24)
|
mef.seek(ftpr_offset + ftpr_mn2_offset + 0x24)
|
||||||
version = unpack("<HHHH", mef.read(0x08))
|
version = unpack("<HHHH", mef.read(0x08))
|
||||||
print("ME/TXE firmware version {}"
|
print("ME/TXE firmware version {} (generation {})"
|
||||||
.format('.'.join(str(i) for i in version)))
|
.format('.'.join(str(i) for i in version), gen))
|
||||||
|
|
||||||
mef.seek(ftpr_offset + ftpr_mn2_offset + 0x80)
|
mef.seek(ftpr_offset + ftpr_mn2_offset + 0x80)
|
||||||
pubkey_md5 = hashlib.md5(mef.read(0x104)).hexdigest()
|
pubkey_md5 = hashlib.md5(mef.read(0x104)).hexdigest()
|
||||||
|
@ -658,7 +692,8 @@ if __name__ == "__main__":
|
||||||
variant = "TXE"
|
variant = "TXE"
|
||||||
print("WARNING Unknown public key {}\n"
|
print("WARNING Unknown public key {}\n"
|
||||||
" Assuming Intel {}\n"
|
" Assuming Intel {}\n"
|
||||||
" Please report this warning to the project's maintainer!"
|
" Please report this warning to the project's "
|
||||||
|
"maintainer!"
|
||||||
.format(pubkey_md5, variant))
|
.format(pubkey_md5, variant))
|
||||||
|
|
||||||
if not args.check and args.output:
|
if not args.check and args.output:
|
||||||
|
@ -666,25 +701,46 @@ if __name__ == "__main__":
|
||||||
shutil.copy(args.file, args.output)
|
shutil.copy(args.file, args.output)
|
||||||
f = open(args.output, "r+b")
|
f = open(args.output, "r+b")
|
||||||
|
|
||||||
|
if me_start < me_end:
|
||||||
mef = RegionFile(f, me_start, me_end)
|
mef = RegionFile(f, me_start, me_end)
|
||||||
|
|
||||||
if me_start > 0:
|
if me_start > 0:
|
||||||
fdf = RegionFile(f, fd_start, fd_end)
|
fdf = RegionFile(f, fd_start, fd_end)
|
||||||
|
|
||||||
if me11:
|
if gen == 1:
|
||||||
fdf.seek(fpsba)
|
for (ba, name) in ((fisba, "ICHSTRP0"), (fmsba, "MCHSTRP0")):
|
||||||
pchstrp0 = unpack("<I", fdf.read(4))[0]
|
fdf.seek(ba)
|
||||||
print("The HAP bit is " +
|
strp = unpack("<I", fdf.read(4))[0]
|
||||||
("SET" if pchstrp0 & 1 << 16 else "NOT SET"))
|
print("The meDisable bit in " + name + " is ", end="")
|
||||||
|
if strp & 1:
|
||||||
|
print("SET")
|
||||||
else:
|
else:
|
||||||
|
print("NOT SET, setting it now...")
|
||||||
|
fdf.write_to(ba, pack("<I", strp | 1))
|
||||||
|
elif gen == 2:
|
||||||
fdf.seek(fpsba + 0x28)
|
fdf.seek(fpsba + 0x28)
|
||||||
pchstrp10 = unpack("<I", fdf.read(4))[0]
|
pchstrp10 = unpack("<I", fdf.read(4))[0]
|
||||||
print("The AltMeDisable bit is " +
|
print("The AltMeDisable bit is " +
|
||||||
("SET" if pchstrp10 & 1 << 7 else "NOT SET"))
|
("SET" if pchstrp10 & 1 << 7 else "NOT SET"))
|
||||||
|
else:
|
||||||
|
fdf.seek(fpsba)
|
||||||
|
pchstrp0 = unpack("<I", fdf.read(4))[0]
|
||||||
|
print("The HAP bit is " +
|
||||||
|
("SET" if pchstrp0 & 1 << 16 else "NOT SET"))
|
||||||
|
|
||||||
|
# Generation 1: wipe everything and disable the ME region
|
||||||
|
if gen == 1 and me_start < me_end:
|
||||||
|
print("Disabling the ME region...")
|
||||||
|
f.seek(frba + 0x8)
|
||||||
|
f.write(pack("<I", 0x1fff))
|
||||||
|
|
||||||
|
print("Wiping the ME region...")
|
||||||
|
mef = RegionFile(f, me_start, me_end)
|
||||||
|
mef.fill_all("\xff")
|
||||||
|
|
||||||
# ME 6 Ignition: wipe everything
|
# ME 6 Ignition: wipe everything
|
||||||
me6_ignition = False
|
me6_ignition = False
|
||||||
if not args.check and not args.soft_disable_only and \
|
if gen == 2 and not args.check and not args.soft_disable_only and \
|
||||||
variant == "ME" and version[0] == 6:
|
variant == "ME" and version[0] == 6:
|
||||||
mef.seek(ftpr_offset + 0x20)
|
mef.seek(ftpr_offset + 0x20)
|
||||||
num_modules = unpack("<I", mef.read(4))[0]
|
num_modules = unpack("<I", mef.read(4))[0]
|
||||||
|
@ -696,7 +752,7 @@ if __name__ == "__main__":
|
||||||
mef.fill_all(b"\xff")
|
mef.fill_all(b"\xff")
|
||||||
me6_ignition = True
|
me6_ignition = True
|
||||||
|
|
||||||
if not args.check:
|
if gen != 1 and not args.check:
|
||||||
if not args.soft_disable_only and not me6_ignition:
|
if not args.soft_disable_only and not me6_ignition:
|
||||||
print("Reading partitions list...")
|
print("Reading partitions list...")
|
||||||
unremovable_part_fpt = b""
|
unremovable_part_fpt = b""
|
||||||
|
@ -769,7 +825,7 @@ if __name__ == "__main__":
|
||||||
flags &= ~(0x00000001)
|
flags &= ~(0x00000001)
|
||||||
mef.write_to(0x24, pack("<I", flags))
|
mef.write_to(0x24, pack("<I", flags))
|
||||||
|
|
||||||
if me11:
|
if gen == 3:
|
||||||
mef.seek(0x10)
|
mef.seek(0x10)
|
||||||
header = bytearray(mef.read(0x20))
|
header = bytearray(mef.read(0x20))
|
||||||
header[0x0b] = 0x00
|
header[0x0b] = 0x00
|
||||||
|
@ -787,9 +843,9 @@ if __name__ == "__main__":
|
||||||
mef.write_to(0x1b, pack("B", checksum))
|
mef.write_to(0x1b, pack("B", checksum))
|
||||||
|
|
||||||
print("Reading FTPR modules list...")
|
print("Reading FTPR modules list...")
|
||||||
if me11:
|
if gen == 3:
|
||||||
end_addr, ftpr_offset = \
|
end_addr, ftpr_offset = \
|
||||||
check_and_remove_modules_me11(mef, me_end,
|
check_and_remove_modules_gen3(mef, me_end,
|
||||||
ftpr_offset, ftpr_length,
|
ftpr_offset, ftpr_length,
|
||||||
min_ftpr_offset,
|
min_ftpr_offset,
|
||||||
args.relocate,
|
args.relocate,
|
||||||
|
@ -817,7 +873,7 @@ if __name__ == "__main__":
|
||||||
f.truncate(end_addr)
|
f.truncate(end_addr)
|
||||||
|
|
||||||
if args.soft_disable or args.soft_disable_only:
|
if args.soft_disable or args.soft_disable_only:
|
||||||
if me11:
|
if gen == 3:
|
||||||
print("Setting the HAP bit in PCHSTRP0 to disable Intel ME...")
|
print("Setting the HAP bit in PCHSTRP0 to disable Intel ME...")
|
||||||
pchstrp0 |= (1 << 16)
|
pchstrp0 |= (1 << 16)
|
||||||
fdf.write_to(fpsba, pack("<I", pchstrp0))
|
fdf.write_to(fpsba, pack("<I", pchstrp0))
|
||||||
|
@ -829,7 +885,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
if args.descriptor:
|
if args.descriptor:
|
||||||
print("Removing ME/TXE R/W access to the other flash regions...")
|
print("Removing ME/TXE R/W access to the other flash regions...")
|
||||||
if me11:
|
if gen == 3:
|
||||||
flmstr2 = 0x00400500
|
flmstr2 = 0x00400500
|
||||||
else:
|
else:
|
||||||
fdf.seek(fmba + 0x4)
|
fdf.seek(fmba + 0x4)
|
||||||
|
@ -853,15 +909,20 @@ if __name__ == "__main__":
|
||||||
me_start + end_addr, bios_end - 1))
|
me_start + end_addr, bios_end - 1))
|
||||||
|
|
||||||
flreg1 = start_end_to_flreg(me_start + end_addr, bios_end)
|
flreg1 = start_end_to_flreg(me_start + end_addr, bios_end)
|
||||||
|
if gen != 1:
|
||||||
flreg2 = start_end_to_flreg(me_start, me_start + end_addr)
|
flreg2 = start_end_to_flreg(me_start, me_start + end_addr)
|
||||||
|
|
||||||
fdf_copy.seek(frba + 0x4)
|
fdf_copy.seek(frba + 0x4)
|
||||||
fdf_copy.write(pack("<II", flreg1, flreg2))
|
fdf_copy.write(pack("<I", flreg1))
|
||||||
|
if gen != 1:
|
||||||
|
fdf_copy.write(pack("<I", flreg2))
|
||||||
else:
|
else:
|
||||||
print("\nWARNING:\n The start address of the BIOS region "
|
print("\nWARNING:\n"
|
||||||
"isn't equal to the end address of the ME\n region: if "
|
"The start address of the BIOS region (0x{:08x}) isn't "
|
||||||
"you want to recover the space from the ME region you "
|
"equal to the end address\nof the ME region (0x{:08x}): "
|
||||||
"have to\n manually modify the descriptor.\n")
|
"if you want to recover the space from the ME \nregion "
|
||||||
|
"you have to manually modify the descriptor.\n"
|
||||||
|
.format(bios_start, me_end))
|
||||||
else:
|
else:
|
||||||
print("Extracting the descriptor to \"{}\"..."
|
print("Extracting the descriptor to \"{}\"..."
|
||||||
.format(args.extract_descriptor))
|
.format(args.extract_descriptor))
|
||||||
|
@ -869,6 +930,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
fdf_copy.close()
|
fdf_copy.close()
|
||||||
|
|
||||||
|
if gen != 1:
|
||||||
if args.extract_me:
|
if args.extract_me:
|
||||||
if args.truncate:
|
if args.truncate:
|
||||||
print("Extracting and truncating the ME image to \"{}\"..."
|
print("Extracting and truncating the ME image to \"{}\"..."
|
||||||
|
|
Loading…
Reference in a new issue