forked from Mirror/pmbootstrap
parse.bootimg: Separate kernel and ramdisk MediaTek headers
Currently, pmbootstrap checks if either the kernel or the ramdisk in a boot.img contains the MediaTek header, and if one does, it assumes both do. It hardcodes the label KERNEL for the kernel and ROOTFS for the ramdisk. My Amazon Echo Dot (gen 2) has a boot.img where only the kernel has the header, but not the ramdisk. These changes (as well as those in my new boot-deploy MR) account for that situation (and any possible label an image has) by splitting bootimg_mtk_mkimage into two variables for the kernel and the ramdisk labels. Reviewed-by: Oliver Smith <ollieparanoid@postmarketos.org> Link: https://lists.sr.ht/~postmarketos/pmbootstrap-devel/patches/46351
This commit is contained in:
parent
41daa850d7
commit
c10a3ce73b
8 changed files with 63 additions and 67 deletions
|
@ -121,24 +121,33 @@ def generate_deviceinfo_fastboot_content(bootimg=None):
|
||||||
if bootimg is None:
|
if bootimg is None:
|
||||||
bootimg = {"cmdline": "",
|
bootimg = {"cmdline": "",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "false",
|
|
||||||
"dtb_second": "false",
|
"dtb_second": "false",
|
||||||
"base": "",
|
"base": "",
|
||||||
"kernel_offset": "",
|
"kernel_offset": "",
|
||||||
"ramdisk_offset": "",
|
"ramdisk_offset": "",
|
||||||
"second_offset": "",
|
"second_offset": "",
|
||||||
"tags_offset": "",
|
"tags_offset": "",
|
||||||
"pagesize": "2048"}
|
"pagesize": "2048",
|
||||||
|
"mtk_label_kernel": "",
|
||||||
|
"mtk_label_ramdisk": ""}
|
||||||
|
|
||||||
content = f"""\
|
content = f"""\
|
||||||
deviceinfo_kernel_cmdline="{bootimg["cmdline"]}"
|
deviceinfo_kernel_cmdline="{bootimg["cmdline"]}"
|
||||||
deviceinfo_generate_bootimg="true"
|
deviceinfo_generate_bootimg="true"
|
||||||
deviceinfo_bootimg_qcdt="{bootimg["qcdt"]}"
|
deviceinfo_bootimg_qcdt="{bootimg["qcdt"]}"
|
||||||
deviceinfo_bootimg_mtk_mkimage="{bootimg["mtk_mkimage"]}"
|
|
||||||
deviceinfo_bootimg_dtb_second="{bootimg["dtb_second"]}"
|
deviceinfo_bootimg_dtb_second="{bootimg["dtb_second"]}"
|
||||||
deviceinfo_flash_pagesize="{bootimg["pagesize"]}"
|
deviceinfo_flash_pagesize="{bootimg["pagesize"]}"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if "mtk_label_kernel" in bootimg.keys():
|
||||||
|
content += f"""\
|
||||||
|
deviceinfo_mtk_label_kernel="{bootimg["mtk_label_kernel"]}"
|
||||||
|
"""
|
||||||
|
if "mtk_label_ramdisk" in bootimg.keys():
|
||||||
|
content += f"""\
|
||||||
|
deviceinfo_mtk_label_ramdisk="{bootimg["mtk_label_ramdisk"]}"
|
||||||
|
"""
|
||||||
|
|
||||||
if "header_version" in bootimg.keys():
|
if "header_version" in bootimg.keys():
|
||||||
content += f"""\
|
content += f"""\
|
||||||
deviceinfo_header_version="{bootimg["header_version"]}"
|
deviceinfo_header_version="{bootimg["header_version"]}"
|
||||||
|
|
|
@ -823,7 +823,9 @@ deviceinfo_attributes = [
|
||||||
"generate_bootimg",
|
"generate_bootimg",
|
||||||
"header_version",
|
"header_version",
|
||||||
"bootimg_qcdt",
|
"bootimg_qcdt",
|
||||||
"bootimg_mtk_mkimage",
|
"bootimg_mtk_mkimage", # deprecated
|
||||||
|
"bootimg_mtk_label_kernel",
|
||||||
|
"bootimg_mtk_label_ramdisk",
|
||||||
"bootimg_dtb_second",
|
"bootimg_dtb_second",
|
||||||
"bootimg_custom_args",
|
"bootimg_custom_args",
|
||||||
"flash_offset_base",
|
"flash_offset_base",
|
||||||
|
|
|
@ -14,12 +14,11 @@ def is_dtb(path):
|
||||||
|
|
||||||
|
|
||||||
def get_mtk_label(path):
|
def get_mtk_label(path):
|
||||||
""" Read the label of a mediatek header of kernel or ramdisk inside an
|
""" Read the label from the MediaTek header of the kernel or ramdisk inside
|
||||||
extracted boot.img.
|
an extracted boot.img.
|
||||||
:param path: to either the kernel or ramdisk file extracted from
|
:param path: to either the kernel or ramdisk extracted from boot.img
|
||||||
boot.img
|
:returns: * None: file does not exist or does not have MediaTek header
|
||||||
:returns: * None: file does not exist or does not have Mediatek header
|
* Label string (e.g. "ROOTFS", "KERNEL") """
|
||||||
* Label string (e.g. "ROOTFS", "RECOVERY", "KERNEL") """
|
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -29,50 +28,20 @@ def get_mtk_label(path):
|
||||||
return None
|
return None
|
||||||
f.seek(8)
|
f.seek(8)
|
||||||
label = f.read(32).decode("utf-8").rstrip('\0')
|
label = f.read(32).decode("utf-8").rstrip('\0')
|
||||||
return label
|
|
||||||
|
|
||||||
|
if label == "RECOVERY":
|
||||||
def check_mtk_bootimg(bootimg_path):
|
|
||||||
""" Check if a boot.img contains a kernel and ramdisk with Mediatek
|
|
||||||
headers, and verify that these headers have labels we expect in
|
|
||||||
boot-deploy.
|
|
||||||
:param bootimg_path: path to boot.img, with extracted files in the same
|
|
||||||
directory
|
|
||||||
:returns: * True: has Mediatek headers
|
|
||||||
* False: has no Mediatek headers """
|
|
||||||
label_kernel = get_mtk_label(f"{bootimg_path}-kernel")
|
|
||||||
label_ramdisk = get_mtk_label(f"{bootimg_path}-ramdisk")
|
|
||||||
|
|
||||||
# Doesn't have Mediatek headers
|
|
||||||
if label_kernel is None and label_ramdisk is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Verify that the kernel and ramdisk have the labels we expect and have
|
|
||||||
# hardcoded in boot-deploy.git's add_mtk_header() function. We don't know
|
|
||||||
# if there are devices out there with different labels, but if there are,
|
|
||||||
# our code in boot-deploy needs to be adjusted to use the proper labels
|
|
||||||
# (store the label in deviceinfo and use it).
|
|
||||||
err_start = "This boot.img has Mediatek headers."
|
|
||||||
err_end = ("Please create an issue and attach your boot.img:"
|
|
||||||
" https://postmarketos.org/issues")
|
|
||||||
if label_kernel != "KERNEL":
|
|
||||||
raise RuntimeError(f"{err_start} Expected the kernel inside the"
|
|
||||||
" boot.img to have a 'KERNEL' label instead of"
|
|
||||||
f" '{label_kernel}'. {err_end}")
|
|
||||||
if label_ramdisk == "RECOVERY":
|
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"WARNING: {err_start} But since you apparently passed a recovery"
|
"WARNING: This boot.img has MediaTek headers. Since you passed a"
|
||||||
" image instead of a regular boot.img, we can't tell if it has the"
|
" recovery image instead of a regular boot.img, we can't tell what"
|
||||||
" expected label 'ROOTFS' inside the ramdisk (found 'RECOVERY')."
|
" the ramdisk signature label is supposed to be, so we assume that"
|
||||||
" So there is a slight chance that it may not boot, in that case"
|
" it's the most common value, ROOTFS. There is a chance that this"
|
||||||
" run bootimg_analyze again with a regular boot.img. It will fail"
|
" is wrong and it may not boot; in that case, run bootimg_analyze"
|
||||||
" if the label is different from 'ROOTFS'.")
|
" again with a regular boot.img. If this *is* a regular boot.img,"
|
||||||
elif label_ramdisk != "ROOTFS":
|
" replace the value of deviceinfo_bootimg_mtk_label_ramdisk with"
|
||||||
raise RuntimeError(f"{err_start} Expected the ramdisk inside the"
|
" 'RECOVERY'.")
|
||||||
" boot.img to have a 'ROOTFS' label instead of"
|
return "ROOTFS"
|
||||||
f" '{label_ramdisk}'. {err_end}")
|
else:
|
||||||
|
return label
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def bootimg(args, path):
|
def bootimg(args, path):
|
||||||
|
@ -152,10 +121,14 @@ def bootimg(args, path):
|
||||||
output["dtb_offset"] = ("0x%08x"
|
output["dtb_offset"] = ("0x%08x"
|
||||||
% int(f.read().replace('\n', ''), 16))
|
% int(f.read().replace('\n', ''), 16))
|
||||||
|
|
||||||
|
if get_mtk_label(f"{bootimg_path}-kernel") is not None:
|
||||||
|
output["mtk_label_kernel"] = get_mtk_label(f"{bootimg_path}-kernel")
|
||||||
|
if get_mtk_label(f"{bootimg_path}-ramdisk") is not None:
|
||||||
|
output["mtk_label_ramdisk"] = get_mtk_label(f"{bootimg_path}-ramdisk")
|
||||||
|
|
||||||
output["qcdt"] = ("true" if os.path.isfile(f"{bootimg_path}-dt") and
|
output["qcdt"] = ("true" if os.path.isfile(f"{bootimg_path}-dt") and
|
||||||
os.path.getsize(f"{bootimg_path}-dt") > 0 else "false")
|
os.path.getsize(f"{bootimg_path}-dt") > 0 else "false")
|
||||||
output["mtk_mkimage"] = ("true" if check_mtk_bootimg(bootimg_path)
|
|
||||||
else "false")
|
|
||||||
output["dtb_second"] = ("true" if is_dtb(f"{bootimg_path}-second")
|
output["dtb_second"] = ("true" if is_dtb(f"{bootimg_path}-second")
|
||||||
else "false")
|
else "false")
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@ def test_bootimg_normal(args):
|
||||||
"pagesize": "2048",
|
"pagesize": "2048",
|
||||||
"cmdline": "bootopt=64S3,32S1,32S1",
|
"cmdline": "bootopt=64S3,32S1,32S1",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "false",
|
|
||||||
"dtb_second": "false"}
|
"dtb_second": "false"}
|
||||||
assert pmb.parse.bootimg(args, path) == output
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
||||||
|
@ -67,13 +66,12 @@ def test_bootimg_qcdt(args):
|
||||||
"pagesize": "2048",
|
"pagesize": "2048",
|
||||||
"cmdline": "bootopt=64S3,32S1,32S1",
|
"cmdline": "bootopt=64S3,32S1,32S1",
|
||||||
"qcdt": "true",
|
"qcdt": "true",
|
||||||
"mtk_mkimage": "false",
|
|
||||||
"dtb_second": "false"}
|
"dtb_second": "false"}
|
||||||
assert pmb.parse.bootimg(args, path) == output
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
||||||
|
|
||||||
def test_bootimg_mtk_mkimage(args):
|
def test_bootimg_mtk(args):
|
||||||
path = pmb_test.const.testdata + "/bootimg/mtk_mkimage-boot.img"
|
path = pmb_test.const.testdata + "/bootimg/mtk-boot.img"
|
||||||
output = {"header_version": "0",
|
output = {"header_version": "0",
|
||||||
"base": "0x10000000",
|
"base": "0x10000000",
|
||||||
"kernel_offset": "0x00008000",
|
"kernel_offset": "0x00008000",
|
||||||
|
@ -81,15 +79,16 @@ def test_bootimg_mtk_mkimage(args):
|
||||||
"second_offset": "0x00f00000",
|
"second_offset": "0x00f00000",
|
||||||
"tags_offset": "0x00000100",
|
"tags_offset": "0x00000100",
|
||||||
"pagesize": "2048",
|
"pagesize": "2048",
|
||||||
|
"mtk_label_kernel": "KERNEL",
|
||||||
|
"mtk_label_ramdisk": "ROOTFS",
|
||||||
"cmdline": "",
|
"cmdline": "",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "true",
|
|
||||||
"dtb_second": "false"}
|
"dtb_second": "false"}
|
||||||
assert pmb.parse.bootimg(args, path) == output
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
||||||
|
|
||||||
def test_bootimg_mtk_mkimage_recovery(args):
|
def test_bootimg_mtk_recovery(args):
|
||||||
path = pmb_test.const.testdata + "/bootimg/mtk_mkimage-boot-recovery.img"
|
path = pmb_test.const.testdata + "/bootimg/mtk-boot-recovery.img"
|
||||||
output = {"header_version": "0",
|
output = {"header_version": "0",
|
||||||
"base": "0x80000000",
|
"base": "0x80000000",
|
||||||
"kernel_offset": "0x00008000",
|
"kernel_offset": "0x00008000",
|
||||||
|
@ -97,9 +96,26 @@ def test_bootimg_mtk_mkimage_recovery(args):
|
||||||
"second_offset": "0x00f00000",
|
"second_offset": "0x00f00000",
|
||||||
"tags_offset": "0x00000100",
|
"tags_offset": "0x00000100",
|
||||||
"pagesize": "2048",
|
"pagesize": "2048",
|
||||||
|
"mtk_label_kernel": "KERNEL",
|
||||||
|
"mtk_label_ramdisk": "ROOTFS",
|
||||||
|
"cmdline": "",
|
||||||
|
"qcdt": "false",
|
||||||
|
"dtb_second": "false"}
|
||||||
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
||||||
|
|
||||||
|
def test_bootimg_mtk_kernelonly(args):
|
||||||
|
path = pmb_test.const.testdata + "/bootimg/mtk-boot-kernel-only.img"
|
||||||
|
output = {"header_version": "0",
|
||||||
|
"base": "0x10000000",
|
||||||
|
"kernel_offset": "0x00008000",
|
||||||
|
"ramdisk_offset": "0x01000000",
|
||||||
|
"second_offset": "0xf0000000",
|
||||||
|
"tags_offset": "0x00000100",
|
||||||
|
"pagesize": "2048",
|
||||||
|
"mtk_label_kernel": "KERNEL",
|
||||||
"cmdline": "",
|
"cmdline": "",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "true",
|
|
||||||
"dtb_second": "false"}
|
"dtb_second": "false"}
|
||||||
assert pmb.parse.bootimg(args, path) == output
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
||||||
|
@ -115,7 +131,6 @@ def test_bootimg_dtb_second(args):
|
||||||
"pagesize": "2048",
|
"pagesize": "2048",
|
||||||
"cmdline": "bootopt=64S3,32S1,32S1",
|
"cmdline": "bootopt=64S3,32S1,32S1",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "false",
|
|
||||||
"dtb_second": "true"}
|
"dtb_second": "true"}
|
||||||
assert pmb.parse.bootimg(args, path) == output
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
||||||
|
@ -132,7 +147,6 @@ def test_bootimg_v2(args):
|
||||||
"dtb_offset": "0x0bc08000",
|
"dtb_offset": "0x0bc08000",
|
||||||
"cmdline": "bootopt=64S3,32N2,64N2 systempart=/dev/mapper/system",
|
"cmdline": "bootopt=64S3,32N2,64N2 systempart=/dev/mapper/system",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "false",
|
|
||||||
"dtb_second": "false"}
|
"dtb_second": "false"}
|
||||||
assert pmb.parse.bootimg(args, path) == output
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
||||||
|
@ -143,6 +157,5 @@ def test_bootimg_v3(args):
|
||||||
"pagesize": "4096",
|
"pagesize": "4096",
|
||||||
"cmdline": "twrpfastboot=1",
|
"cmdline": "twrpfastboot=1",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "false",
|
|
||||||
"dtb_second": "false"}
|
"dtb_second": "false"}
|
||||||
assert pmb.parse.bootimg(args, path) == output
|
assert pmb.parse.bootimg(args, path) == output
|
||||||
|
|
|
@ -100,7 +100,6 @@ def test_questions_bootimg(args, monkeypatch):
|
||||||
"pagesize": "2048",
|
"pagesize": "2048",
|
||||||
"cmdline": "bootopt=64S3,32S1,32S1",
|
"cmdline": "bootopt=64S3,32S1,32S1",
|
||||||
"qcdt": "false",
|
"qcdt": "false",
|
||||||
"mtk_mkimage": "false",
|
|
||||||
"dtb_second": "false"}
|
"dtb_second": "false"}
|
||||||
assert func(args) == output
|
assert func(args) == output
|
||||||
|
|
||||||
|
|
BIN
test/testdata/bootimg/mtk-boot-kernel-only.img
vendored
Normal file
BIN
test/testdata/bootimg/mtk-boot-kernel-only.img
vendored
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue