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):
|
logging.warning(
|
||||||
""" Check if a boot.img contains a kernel and ramdisk with Mediatek
|
"WARNING: This boot.img has MediaTek headers. Since you passed a"
|
||||||
headers, and verify that these headers have labels we expect in
|
" recovery image instead of a regular boot.img, we can't tell what"
|
||||||
boot-deploy.
|
" the ramdisk signature label is supposed to be, so we assume that"
|
||||||
:param bootimg_path: path to boot.img, with extracted files in the same
|
" it's the most common value, ROOTFS. There is a chance that this"
|
||||||
directory
|
" is wrong and it may not boot; in that case, run bootimg_analyze"
|
||||||
:returns: * True: has Mediatek headers
|
" again with a regular boot.img. If this *is* a regular boot.img,"
|
||||||
* False: has no Mediatek headers """
|
" replace the value of deviceinfo_bootimg_mtk_label_ramdisk with"
|
||||||
label_kernel = get_mtk_label(f"{bootimg_path}-kernel")
|
" 'RECOVERY'.")
|
||||||
label_ramdisk = get_mtk_label(f"{bootimg_path}-ramdisk")
|
return "ROOTFS"
|
||||||
|
else:
|
||||||
# Doesn't have Mediatek headers
|
return label
|
||||||
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(
|
|
||||||
f"WARNING: {err_start} But since you apparently passed a recovery"
|
|
||||||
" image instead of a regular boot.img, we can't tell if it has the"
|
|
||||||
" expected label 'ROOTFS' inside the ramdisk (found 'RECOVERY')."
|
|
||||||
" So there is a slight chance that it may not boot, in that case"
|
|
||||||
" run bootimg_analyze again with a regular boot.img. It will fail"
|
|
||||||
" if the label is different from 'ROOTFS'.")
|
|
||||||
elif label_ramdisk != "ROOTFS":
|
|
||||||
raise RuntimeError(f"{err_start} Expected the ramdisk inside the"
|
|
||||||
" boot.img to have a 'ROOTFS' label instead of"
|
|
||||||
f" '{label_ramdisk}'. {err_end}")
|
|
||||||
|
|
||||||
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