pmb.parse.bootimg: detect mediatek header (MR 1955)

Some Mediatek devices have a special 512-byte header around the zImage
which must be generated so the device boots.

Support for that exists for a while in postmarketOS but detection was
missing. Add that.
This commit is contained in:
Luca Weiss 2020-07-05 21:42:54 +02:00
parent 9718fd294a
commit 86d61b8012
No known key found for this signature in database
GPG Key ID: 72D843B89D4DD756
7 changed files with 47 additions and 1 deletions

View File

@ -107,6 +107,7 @@ def generate_deviceinfo_fastboot_content(args, bootimg=None):
if bootimg is None:
bootimg = {"cmdline": "",
"qcdt": "false",
"mtk_mkimage": "false",
"dtb_second": "false",
"base": "",
"kernel_offset": "",
@ -118,6 +119,7 @@ def generate_deviceinfo_fastboot_content(args, bootimg=None):
deviceinfo_kernel_cmdline="{bootimg["cmdline"]}"
deviceinfo_generate_bootimg="true"
deviceinfo_bootimg_qcdt="{bootimg["qcdt"]}"
deviceinfo_bootimg_mtk_mkimage="{bootimg["mtk_mkimage"]}"
deviceinfo_bootimg_dtb_second="{bootimg["dtb_second"]}"
deviceinfo_flash_offset_base="{bootimg["base"]}"
deviceinfo_flash_offset_kernel="{bootimg["kernel_offset"]}"

View File

@ -28,7 +28,7 @@ def kernel_flavors_installed(args, suffix, autoinstall=True):
ret = []
for file in glob.glob(pattern):
flavor = os.path.basename(file)[prefix_len:]
if flavor[-4:] == "-dtb":
if flavor[-4:] == "-dtb" or flavor[-4:] == "-mtk":
flavor = flavor[:-4]
ret.append(flavor)

View File

@ -342,6 +342,7 @@ deviceinfo_attributes = [
"kernel_cmdline",
"generate_bootimg",
"bootimg_qcdt",
"bootimg_mtk_mkimage",
"bootimg_dtb_second",
"flash_offset_base",
"flash_offset_kernel",

View File

@ -13,6 +13,25 @@ def is_dtb(path):
return f.read(4) == b'\xd0\x0d\xfe\xed'
def has_mtk_header(path, supported_label):
with open(path, 'rb') as f:
# Check Mediatek header (0x88168858)
if not f.read(4) == b'\x88\x16\x88\x58':
return False
f.seek(8)
label = f.read(32).decode("utf-8").rstrip('\0')
# We only support hardcoded labels for now as the known devices only
# use KERNEL & ROOTFS for kernel and ramdisk respectively. To change
# this, deviceinfo would need to store the label and
# postmarketos-mkinitfs would need to use that label.
if label != supported_label:
raise RuntimeError(f"Only '{supported_label}' is supported as label,"
f" but your device has '{label}'. Please create"
f" an issue and attach your boot.img:"
f" https://postmarketos.org/issues")
return True
def bootimg(args, path):
if not os.path.exists(path):
raise RuntimeError("Could not find file '" + path + "'")
@ -70,8 +89,13 @@ def bootimg(args, path):
output["cmdline"] = f.read().replace('\n', '')
output["qcdt"] = ("true" if os.path.isfile(bootimg_path + "-dt") and
os.path.getsize(bootimg_path + "-dt") > 0 else "false")
output["mtk_mkimage"] = ("true" if has_mtk_header(bootimg_path + "-zImage", "KERNEL") else "false")
output["dtb_second"] = ("true" if is_dtb(bootimg_path + "-second") else "false")
# Mediatek: Check that the ramdisk also has a known-good label
# We don't care about the return value, just whether it throws an exception or not.
has_mtk_header(bootimg_path + "-ramdisk.gz", "ROOTFS")
# Cleanup
pmb.chroot.root(args, ["rm", "-r", temp_path])

View File

@ -51,6 +51,7 @@ def test_bootimg_normal(args):
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "false",
"mtk_mkimage": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
@ -65,6 +66,22 @@ def test_bootimg_qcdt(args):
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "true",
"mtk_mkimage": "false",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
def test_bootimg_mtk_mkimage(args):
path = pmb_test.const.testdata + "/bootimg/mtk_mkimage-boot.img"
output = {"base": "0x80000000",
"kernel_offset": "0x00008000",
"ramdisk_offset": "0x04000000",
"second_offset": "0x00f00000",
"tags_offset": "0x0e000000",
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "false",
"mtk_mkimage": "true",
"dtb_second": "false"}
assert pmb.parse.bootimg(args, path) == output
@ -79,5 +96,6 @@ def test_bootimg_dtb_second(args):
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "false",
"mtk_mkimage": "false",
"dtb_second": "true"}
assert pmb.parse.bootimg(args, path) == output

View File

@ -98,6 +98,7 @@ def test_questions_bootimg(args, monkeypatch):
"pagesize": "2048",
"cmdline": "bootopt=64S3,32S1,32S1",
"qcdt": "false",
"mtk_mkimage": "false",
"dtb_second": "false"}
assert func(args) == output

Binary file not shown.