RK3566 + Android 11
...
Image: kernel.img is ready
...
Image: resource.img (with rk3566-evb2-lp4x-v10-edp.dtb logo.bmp logo_kernel.bmp) is ready
...
Traceback (most recent call last):
File "./scripts/mkbootimg", line 317, in
main()
File "./scripts/mkbootimg", line 291, in main
args = parse_cmdline()
File "./scripts/mkbootimg", line 270, in parse_cmdline
return parser.parse_args()
File "/usr/lib/python2.7/argparse.py", line 1705, in parse_args
args, argv = self.parse_known_args(args, namespace)
File "/usr/lib/python2.7/argparse.py", line 1737, in parse_known_args
namespace, args = self._parse_known_args(args, namespace)
File "/usr/lib/python2.7/argparse.py", line 1943, in _parse_known_args
start_index = consume_optional(start_index)
File "/usr/lib/python2.7/argparse.py", line 1883, in consume_optional
take_action(action, args, option_string)
File "/usr/lib/python2.7/argparse.py", line 1795, in take_action
argument_values = self._get_values(action, argument_strings)
File "/usr/lib/python2.7/argparse.py", line 2235, in _get_values
value = self._get_value(action, arg_string)
File "/usr/lib/python2.7/argparse.py", line 2264, in _get_value
result = type_func(arg_string)
File "./scripts/mkbootimg", line 223, in parse_os_patch_level
assert 0 < m <= 12
从上面的LOG 可以看出kernel.img 与 Resources.img已经编译成功, 问题出在打包部分, 原本以为是python版本问题, 再度确认后发现并无关联.
./scripts/mkbootimg
def parse_cmdline():
parser = ArgumentParser()
parser.add_argument('--kernel', help='path to the kernel', type=FileType('rb'))
parser.add_argument('--ramdisk', help='path to the ramdisk', type=FileType('rb'))
parser.add_argument('--second', help='path to the 2nd bootloader', type=FileType('rb'))
parser.add_argument('--dtb', help='path to dtb', type=FileType('rb'))
recovery_dtbo_group = parser.add_mutually_exclusive_group()
recovery_dtbo_group.add_argument('--recovery_dtbo', help='path to the recovery DTBO',
type=FileType('rb'))
recovery_dtbo_group.add_argument('--recovery_acpio', help='path to the recovery ACPIO',
type=FileType('rb'), metavar='RECOVERY_ACPIO',
dest='recovery_dtbo')
parser.add_argument('--cmdline', help='extra arguments to be passed on the '
'kernel command line', default='', action=ValidateStrLenAction, maxlen=1536)
parser.add_argument('--vendor_cmdline',
help='kernel command line arguments contained in vendor boot',
default='', action=ValidateStrLenAction, maxlen=2048)
parser.add_argument('--base', help='base address', type=parse_int, default=0x10000000)
parser.add_argument('--kernel_offset', help='kernel offset', type=parse_int, default=0x00008000)
parser.add_argument('--ramdisk_offset', help='ramdisk offset', type=parse_int,
default=0x01000000)
parser.add_argument('--second_offset', help='2nd bootloader offset', type=parse_int,
default=0x00f00000)
parser.add_argument('--dtb_offset', help='dtb offset', type=parse_int, default=0x01f00000)
parser.add_argument('--os_version', help='operating system version', type=parse_os_version,
default=0)
parser.add_argument('--os_patch_level', help='operating system patch level',
type=parse_os_patch_level, default=0)
parser.add_argument('--tags_offset', help='tags offset', type=parse_int, default=0x00000100)
parser.add_argument('--board', help='board name', default='', action=ValidateStrLenAction,
maxlen=16)
parser.add_argument('--pagesize', help='page size', type=parse_int,
choices=[2**i for i in range(11, 15)], default=2048)
parser.add_argument('--id', help='print the image ID on standard output',
action='store_true')
parser.add_argument('--header_version', help='boot image header version', type=parse_int,
default=0)
parser.add_argument('-o', '--output', help='output file name', type=FileType('wb'))
parser.add_argument('--vendor_boot', help='vendor boot output file name', type=FileType('wb'))
parser.add_argument('--vendor_ramdisk', help='path to the vendor ramdisk', type=FileType('rb'))
return parser.parse_args()
问题出在 parse_cmdline() 这一行上.
尝试打印出传递进来的参数:
import sys
def main():
print (sys.argv[1:])
args = parse_cmdline()
['--kernel', './arch/arm64/boot/Image', '--second', 'resource.img', '--ramdisk', 'out/ramdisk', '--cmdline', '', '--header_version', '0', '--os_version', '0.0.0', '--os_patch_level', '2000-00', '--output', 'boot.img']
然而, 正常情况下编译的参数是:
['--kernel', './arch/arm64/boot/Image', '--second', 'resource.img', '-o', 'boot.img']
调用流程: mkimg -> mkbootimg
./scripts/mkimg
if [ -f "${BOOT_IMG}" ]; then
if file -p -b ${BOOT_IMG} | grep -q 'Device Tree Blob' ; then
repack_itb;
elif [ -x ${srctree}/scripts/repack-bootimg ]; then
repack_boot_img;
fi
elif [ -x ${srctree}/scripts/mkbootimg ]; then
make_boot_img;
fi
mkimg的调用
kernel/arch/arm64/Makefile: $(Q)$(srctree)/scripts/mkimg --dtb $*.dtb
kernel/arch/arm/Makefile: $(Q)$(srctree)/scripts/mkimg --dtb $*.dtb
参数不同的原因在于BOOT_IMG 是否存在:
BOOT_IMG=rockdev/Image-rk3566_r/boot.img
当BOOT_IMG存在时, 会执行 repack-bootimg
./scripts/repack-bootimg
out=${out-"out"}
log="$out/unpack.log"
cmdline=$(grep -a "^command line args: " $log | tr '\0' '\n'| sed "s/^command line args: //")
$srctree/scripts/mkbootimg \
--kernel $kernel \
$SECOND \
--ramdisk $ramdisk \
$DTB \
$RECOVERY_DTBO \
--cmdline "${cmdline}${extra_cmdline}" \
--header_version $version \
--os_version $os_version \
--os_patch_level $os_patch_level \
--output $output
cmdline的参数来自于unpack.log:
kernel$ ll out/
total 30588
drwxrwxr-x 2 anson anson 4096 1月 27 00:02 ./
drwxrwxr-x 30 anson anson 4096 1月 27 00:02 ../
-rw-rw-r-- 1 anson anson 31141896 1月 27 00:02 kernel
-rw-rw-r-- 1 anson anson 0 1月 27 00:02 ramdisk
-rw-rw-r-- 1 anson anson 162304 1月 27 00:02 second
-rw-rw-r-- 1 anson anson 381 1月 27 00:02 unpack.log
cat out/unpack.log
boot_magic: ANDROID!
kernel_size: 31141896
kernel load address: 0x10008000
ramdisk size: 0
ramdisk load address: 0x0
second bootloader size: 162304
second bootloader load address: 0x10f00000
kernel tags load address: 0x10000100
page size: 2048
os version: 0.0.0
os patch level: 2000-00
boot image header version: 0
product name:
command line args:
additional command line args:
虽然最终定位到这个位置, 但具体原因却无从得知.
这个问题出现在, 第一次编译完成并完成 ./mkimage.sh之后, 解决的方案就是手动删除BOOT_IMG
rm -rf rockdev/Image-rk3566_r/boot.img
这样, 再重新编译kernel便可顺利打包, 只是在执行mkimage.sh后, 需重复发上命令.