forked from rockchip-linux/kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Also add unpack_bootimg and update mkbootimg AOSP 96fd8874ef8e ("Check DTB image size for boot image header version 2 and above") Change-Id: I4582913b21f711c84d62bed0ffd024b583a094f7 Signed-off-by: Tao Huang <[email protected]>
- Loading branch information
1 parent
b0d48db
commit 28aa47d
Showing
3 changed files
with
342 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
#!/bin/bash | ||
# SPDX-License-Identifier: GPL-2.0 | ||
# Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd. | ||
set -e | ||
|
||
usage() { | ||
cat >&2 << USAGE | ||
usage: $0 [-h] [-z] --boot_img BOOT_IMG [--out OUT] [--kernel KERNEL] [--ramdisk RAMDISK] [--second SECOND] [--dtb DTB ] [--recovery_dtbo RECOVERY_DTBO] -o OUTPUT | ||
optional arguments: | ||
-h, --help show this help message and exit | ||
-z pack compressed kernel image | ||
--boot_img BOOT_IMG path to the original boot image | ||
--out OUT path to out binaries (default: out) | ||
--kernel KERNEL path to the new kernel | ||
--ramdisk RAMDISK path to the new ramdisk | ||
--second SECOND path to the new 2nd bootloader (default: resource.img) | ||
--dtb DTB path to the new dtb | ||
--recovery_dtbo RECOVERY_DTBO | ||
path to the new recovery DTBO | ||
-o OUTPUT, --output OUTPUT | ||
output file name | ||
USAGE | ||
} | ||
|
||
# Parse command-line arguments | ||
while [ $# -gt 0 ]; do | ||
case $1 in | ||
--boot_img) | ||
boot_img=$2 | ||
shift 2 | ||
;; | ||
--out) | ||
out=$2 | ||
shift 2 | ||
;; | ||
--kernel) | ||
kernel=$2 | ||
shift 2 | ||
;; | ||
--ramdisk) | ||
ramdisk=$2 | ||
shift 2 | ||
;; | ||
--second) | ||
second=$2 | ||
shift 2 | ||
;; | ||
--dtb) | ||
dtb=$2 | ||
shift 2 | ||
;; | ||
--recovery_dtbo) | ||
recovery_dtbo=$2 | ||
shift 2 | ||
;; | ||
-h) | ||
usage | ||
exit 0 | ||
;; | ||
--help) | ||
usage | ||
exit 0 | ||
;; | ||
-z) | ||
compressed_kernel=y | ||
shift | ||
;; | ||
-o) | ||
output=$2 | ||
shift 2 | ||
;; | ||
--output) | ||
output=$2 | ||
shift 2 | ||
;; | ||
*) | ||
shift | ||
;; | ||
esac | ||
done | ||
|
||
if [ "$boot_img" == "" -o ! -e "$boot_img" ]; then | ||
echo "No boot img" | ||
usage | ||
exit 1 | ||
fi | ||
|
||
if [ "$output" == "" ]; then | ||
echo "No output file name" | ||
usage | ||
exit 1 | ||
fi | ||
|
||
srctree=${srctree-"."} | ||
objtree=${objtree-"."} | ||
out=${out-"out"} | ||
if [ "$($srctree/scripts/config --state CONFIG_ARM64)" == "y" ]; then | ||
if [ "$compressed_kernel" == "y" ]; then | ||
default_kernel=arch/arm64/boot/Image.lz4 | ||
else | ||
default_kernel=arch/arm64/boot/Image | ||
fi | ||
else | ||
if [ "$compressed_kernel" == "y" ]; then | ||
default_kernel=arch/arm/boot/zImage | ||
else | ||
default_kernel=arch/arm/boot/Image | ||
fi | ||
fi | ||
kernel=${kernel-$objtree/$default_kernel} | ||
second=${second-$objtree/resource.img} | ||
ramdisk=${ramdisk-$out/ramdisk} | ||
dtb=${dtb-$out/dtb} | ||
recovery_dtbo=${recovery_dtbo-$out/recovery_dtbo} | ||
log="$out/unpack.log" | ||
|
||
mkdir -p $out | ||
$srctree/scripts/unpack_bootimg --boot_img $boot_img --out $out > $log | ||
|
||
cmdline=$(grep -a "^command line args: " $log | tr '\0' '\n'| sed "s/^command line args: //") | ||
extra_cmdline=$(grep -a "^additional command line args: " $log | tr '\0' '\n'| sed "s/^additional command line args: //") | ||
version=$(grep -a "^boot image header version: " $log | sed "s/^boot image header version: //") | ||
|
||
os_version_patch_level=$(grep -a "^os version and patch level: " $log | sed "s/^os version and patch level: //") | ||
|
||
v=$(($os_version_patch_level >> 11)) | ||
a=$(($v >> 14)) | ||
b=$((($v >> 7) & 0x7f)) | ||
c=$(($v & 0x7f)) | ||
os_version=$(printf '%d.%d.%d' $a $b $c) | ||
|
||
v=$(($os_version_patch_level & 0x7ff)) | ||
y=$((($v >> 4) + 2000)) | ||
m=$((($v & 15))) | ||
os_patch_level=$(printf '%d-%02d-01' $y $m) | ||
|
||
dtb_size=$(grep -a "^dtb size: " $log | sed "s/^dtb size: //") | ||
dtb_size=${dtb_size:-0} | ||
if [ $dtb_size -gt 0 -a -e "$dtb" ]; then | ||
DTB="--dtb $dtb" | ||
fi | ||
|
||
recovery_dtbo_size=$(grep -a "^recovery dtbo size: " $log | sed "s/^recovery dtbo size: //") | ||
recovery_dtbo_size=${recovery_dtbo_size:-0} | ||
if [ $recovery_dtbo_size -gt 0 -a -e "$recovery_dtbo" ]; then | ||
RECOVERY_DTBO="--recovery_dtbo $recovery_dtbo" | ||
fi | ||
|
||
$srctree/scripts/mkbootimg \ | ||
--kernel $kernel \ | ||
--second $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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
#!/usr/bin/env python | ||
# Copyright 2018, The Android Open Source Project | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""unpacks the bootimage. | ||
Extracts the kernel, ramdisk, second bootloader, dtb and recovery dtbo images. | ||
""" | ||
|
||
from __future__ import print_function | ||
from argparse import ArgumentParser, FileType | ||
from struct import unpack | ||
import os | ||
|
||
|
||
def create_out_dir(dir_path): | ||
"""creates a directory 'dir_path' if it does not exist""" | ||
if not os.path.exists(dir_path): | ||
os.makedirs(dir_path) | ||
|
||
|
||
def extract_image(offset, size, bootimage, extracted_image_name): | ||
"""extracts an image from the bootimage""" | ||
bootimage.seek(offset) | ||
with open(extracted_image_name, 'wb') as file_out: | ||
file_out.write(bootimage.read(size)) | ||
|
||
|
||
def get_number_of_pages(image_size, page_size): | ||
"""calculates the number of pages required for the image""" | ||
return (image_size + page_size - 1) / page_size | ||
|
||
|
||
def unpack_bootimage(args): | ||
"""extracts kernel, ramdisk, second bootloader and recovery dtbo""" | ||
boot_magic = unpack('8s', args.boot_img.read(8)) | ||
print('boot_magic: %s' % boot_magic) | ||
kernel_ramdisk_second_info = unpack('10I', args.boot_img.read(10 * 4)) | ||
print('kernel_size: %s' % kernel_ramdisk_second_info[0]) | ||
print('kernel load address: %#x' % kernel_ramdisk_second_info[1]) | ||
print('ramdisk size: %s' % kernel_ramdisk_second_info[2]) | ||
print('ramdisk load address: %#x' % kernel_ramdisk_second_info[3]) | ||
print('second bootloader size: %s' % kernel_ramdisk_second_info[4]) | ||
print('second bootloader load address: %#x' % kernel_ramdisk_second_info[5]) | ||
print('kernel tags load address: %#x' % kernel_ramdisk_second_info[6]) | ||
print('page size: %s' % kernel_ramdisk_second_info[7]) | ||
print('boot image header version: %s' % kernel_ramdisk_second_info[8]) | ||
print('os version and patch level: %s' % kernel_ramdisk_second_info[9]) | ||
|
||
product_name = unpack('16s', args.boot_img.read(16)) | ||
print('product name: %s' % product_name) | ||
cmdline = unpack('512s', args.boot_img.read(512)) | ||
print('command line args: %s' % cmdline) | ||
|
||
args.boot_img.read(32) # ignore SHA | ||
|
||
extra_cmdline = unpack('1024s', args.boot_img.read(1024)) | ||
print('additional command line args: %s' % extra_cmdline) | ||
|
||
kernel_size = kernel_ramdisk_second_info[0] | ||
ramdisk_size = kernel_ramdisk_second_info[2] | ||
second_size = kernel_ramdisk_second_info[4] | ||
page_size = kernel_ramdisk_second_info[7] | ||
version = kernel_ramdisk_second_info[8] | ||
if version > 0: | ||
recovery_dtbo_size = unpack('I', args.boot_img.read(1 * 4))[0] | ||
print('recovery dtbo size: %s' % recovery_dtbo_size) | ||
recovery_dtbo_offset = unpack('Q', args.boot_img.read(8))[0] | ||
print('recovery dtbo offset: %#x' % recovery_dtbo_offset) | ||
boot_header_size = unpack('I', args.boot_img.read(4))[0] | ||
print('boot header size: %s' % boot_header_size) | ||
else: | ||
recovery_dtbo_size = 0 | ||
if version > 1: | ||
dtb_size = unpack('I', args.boot_img.read(4))[0] | ||
print('dtb size: %s' % dtb_size) | ||
dtb_load_address = unpack('Q', args.boot_img.read(8))[0] | ||
print('dtb address: %#x' % dtb_load_address) | ||
else: | ||
dtb_size = 0 | ||
|
||
|
||
# The first page contains the boot header | ||
num_header_pages = 1 | ||
|
||
num_kernel_pages = get_number_of_pages(kernel_size, page_size) | ||
kernel_offset = page_size * num_header_pages # header occupies a page | ||
image_info_list = [(kernel_offset, kernel_size, 'kernel')] | ||
|
||
num_ramdisk_pages = get_number_of_pages(ramdisk_size, page_size) | ||
ramdisk_offset = page_size * (num_header_pages + num_kernel_pages | ||
) # header + kernel | ||
image_info_list.append((ramdisk_offset, ramdisk_size, 'ramdisk')) | ||
|
||
if second_size > 0: | ||
second_offset = page_size * ( | ||
num_header_pages + num_kernel_pages + num_ramdisk_pages | ||
) # header + kernel + ramdisk | ||
image_info_list.append((second_offset, second_size, 'second')) | ||
|
||
if recovery_dtbo_size > 0: | ||
image_info_list.append((recovery_dtbo_offset, recovery_dtbo_size, | ||
'recovery_dtbo')) | ||
if dtb_size > 0: | ||
num_second_pages = get_number_of_pages(second_size, page_size) | ||
num_recovery_dtbo_pages = get_number_of_pages(recovery_dtbo_size, page_size) | ||
dtb_offset = page_size * ( | ||
num_header_pages + num_kernel_pages + num_ramdisk_pages + num_second_pages + | ||
num_recovery_dtbo_pages | ||
) | ||
|
||
image_info_list.append((dtb_offset, dtb_size, 'dtb')) | ||
|
||
for image_info in image_info_list: | ||
extract_image(image_info[0], image_info[1], args.boot_img, | ||
os.path.join(args.out, image_info[2])) | ||
|
||
|
||
def parse_cmdline(): | ||
"""parse command line arguments""" | ||
parser = ArgumentParser( | ||
description='Unpacks boot.img/recovery.img, extracts the kernel,' | ||
'ramdisk, second bootloader, recovery dtbo and dtb') | ||
parser.add_argument( | ||
'--boot_img', | ||
help='path to boot image', | ||
type=FileType('rb'), | ||
required=True) | ||
parser.add_argument('--out', help='path to out binaries', default='out') | ||
return parser.parse_args() | ||
|
||
|
||
def main(): | ||
"""parse arguments and unpack boot image""" | ||
args = parse_cmdline() | ||
create_out_dir(args.out) | ||
unpack_bootimage(args) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |