system/core
リビジョン | 96b57938c1faeec544bf8509a488412e5e563fb4 (tree) |
---|---|
日時 | 2016-09-08 19:46:33 |
作者 | M1cha <sigmaepsilon92@gmai...> |
コミッター | Gerrit Code Review |
unpackbootimg: stash EFIDroid changes
commit c0bb55fdf63c6ba5b8f4b30303ab624e5cd1eab0
Author: M1cha <sigmaepsilon92@gmail.com>
Date: Fri Aug 26 11:12:28 2016 +0200
commit 39fa4df2e200501400a7f80097543c684c91ad8b
Author: M1cha <sigmaepsilon92@gmail.com>
Date: Sun Aug 28 20:49:00 2016 +0200
commit 4bf90a6ecc2530c3eb6d97d90a595655f5c8189f
Author: M1cha <sigmaepsilon92@gmail.com>
Date: Sun Sep 4 10:54:43 2016 +0200
commit 863757ec8f008f189aeb188a6fb8bf8718c040e6
Author: M1cha <sigmaepsilon92@gmail.com>
Date: Sun Sep 4 10:57:02 2016 +0200
commit 21c7d91fce55bf6ec242ad81768f679a461166cf
Author: M1cha <sigmaepsilon92@gmail.com>
Date: Sun Sep 4 10:57:29 2016 +0200
commit 5a8c5e9fe25cb4e0e182f55c1dc96d49a95b341c
Author: M1cha <sigmaepsilon92@gmail.com>
Date: Sun Sep 4 11:09:47 2016 +0200
Change-Id: I62f4f92c5caaed06cd3858900135231f91f6bc79
@@ -16,9 +16,13 @@ | ||
16 | 16 | from __future__ import print_function |
17 | 17 | from sys import exit |
18 | 18 | from argparse import ArgumentParser, FileType |
19 | -from os import rename | |
20 | -from os.path import basename | |
19 | +from os import rename, makedirs | |
20 | +from os.path import basename, exists | |
21 | 21 | from struct import unpack, calcsize |
22 | +import zlib | |
23 | + | |
24 | +def ROUNDDOWN(number, alignment): | |
25 | + return ((number) & ~((alignment)-1)) | |
22 | 26 | |
23 | 27 | class Bunch: |
24 | 28 | def __init__(self, **kwds): |
@@ -67,14 +71,30 @@ def read_header(args, off): | ||
67 | 71 | os_version = unpacked[10]>>11 |
68 | 72 | os_patch_level = unpacked[10]&0x7ff |
69 | 73 | |
70 | - a = (os_version>>14)&0x7f | |
71 | - b = (os_version>>7)&0x7f | |
72 | - c = os_version&0x7f | |
73 | - parsed.os_version = '%d.%d.%d' % (a,b,c) | |
74 | - | |
75 | - y = (os_patch_level>>4) + 2000 | |
76 | - m = os_patch_level&0xf | |
77 | - parsed.os_patch_level = '%04d-%02d-%02d' % (y,m,0) | |
74 | + parsed.os_version = None | |
75 | + if os_version != 0: | |
76 | + a = (os_version>>14)&0x7f | |
77 | + b = (os_version>>7)&0x7f | |
78 | + c = os_version&0x7f | |
79 | + parsed.os_version = '%d.%d.%d' % (a,b,c) | |
80 | + | |
81 | + parsed.os_patch_level = None | |
82 | + if os_patch_level != 0: | |
83 | + y = (os_patch_level>>4) + 2000 | |
84 | + m = os_patch_level&0xf | |
85 | + parsed.os_patch_level = '%04d-%02d-%02d' % (y,m,0) | |
86 | + | |
87 | + # find common base of all loading addresses | |
88 | + parsed.base = min(parsed.kernel_addr, parsed.ramdisk_addr, parsed.second_addr, parsed.tags_addr) | |
89 | + parsed.base = ROUNDDOWN(parsed.base, parsed.pagesize) | |
90 | + if (parsed.base&0xffff) == 0x8000: | |
91 | + parsed.base -= 0x8000 | |
92 | + | |
93 | + # calculate offsets relative to base | |
94 | + parsed.kernel_offset = parsed.kernel_addr - parsed.base | |
95 | + parsed.ramdisk_offset = parsed.ramdisk_addr - parsed.base | |
96 | + parsed.second_offset = parsed.second_addr - parsed.base | |
97 | + parsed.tags_offset = parsed.tags_addr - parsed.base | |
78 | 98 | |
79 | 99 | return parsed |
80 | 100 |
@@ -89,7 +109,7 @@ def parse_cmdline(): | ||
89 | 109 | parser = ArgumentParser() |
90 | 110 | parser.add_argument('-i', '--input', help='input file name', type=FileType('rb'), |
91 | 111 | required=True) |
92 | - parser.add_argument('-o', '--output', help='output directory', default='') | |
112 | + parser.add_argument('-o', '--output', help='output directory', default='./') | |
93 | 113 | parser.add_argument('--pagesize', help='page size', type=parse_int, |
94 | 114 | choices=[2**i for i in range(11,18)], default=0) |
95 | 115 | return parser.parse_args() |
@@ -119,21 +139,49 @@ def fix_ramdisk_extension(filename): | ||
119 | 139 | else: |
120 | 140 | rename(filename, filename+'.gz') |
121 | 141 | |
142 | +def is_gzip_package(filename): | |
143 | + bytes = [] | |
144 | + with open(filename, 'rb') as f: | |
145 | + data = f.read(3) | |
146 | + if(len(data))!=3: | |
147 | + return False | |
148 | + bytes = unpack('BBB', data) | |
149 | + | |
150 | + return bytes[0]==0x1f and bytes[1]==0x8b and bytes[2]==0x08 | |
151 | + | |
152 | +def is_arm64(filename): | |
153 | + data = None | |
154 | + with open(filename, 'rb') as f: | |
155 | + fmt = '2I6Q2I' | |
156 | + size = calcsize(fmt) | |
157 | + buf = f.read(size) | |
158 | + if(len(buf))!=size: | |
159 | + return False | |
160 | + data = unpack(fmt, buf) | |
161 | + | |
162 | + return data[8]==0x644D5241 | |
163 | + | |
122 | 164 | def write_data(args, header, off): |
123 | 165 | file_prefix = args.output |
124 | 166 | if file_prefix and file_prefix[-1]!='/': |
125 | 167 | file_prefix += '/' |
126 | 168 | file_prefix += basename(args.input.name) + '-' |
127 | 169 | |
170 | + if not exists(args.output): | |
171 | + makedirs(args.output) | |
172 | + | |
128 | 173 | write_str_to_file(file_prefix+'cmdline', header.cmdline) |
129 | - write_str_to_file(file_prefix+'base', '%08x' % (header.kernel_addr - 0x00008000)) | |
130 | - write_str_to_file(file_prefix+'ramdisk_offset', '%08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
131 | - write_str_to_file(file_prefix+'second_offset', '%08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
132 | - write_str_to_file(file_prefix+'tags_offset', '%08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
174 | + write_str_to_file(file_prefix+'base', '%08x' % header.base) | |
175 | + write_str_to_file(file_prefix+'kernel_offset', '%08x' % header.kernel_offset) | |
176 | + write_str_to_file(file_prefix+'ramdisk_offset', '%08x' % header.ramdisk_offset) | |
177 | + write_str_to_file(file_prefix+'second_offset', '%08x' % header.second_offset) | |
178 | + write_str_to_file(file_prefix+'tags_offset', '%08x' % header.tags_offset) | |
133 | 179 | write_str_to_file(file_prefix+'pagesize', '%d' % header.pagesize) |
134 | 180 | write_str_to_file(file_prefix+'name', header.name) |
135 | - write_str_to_file(file_prefix+'os_version', header.os_version) | |
136 | - write_str_to_file(file_prefix+'os_patch_level', header.os_patch_level) | |
181 | + if header.os_version: | |
182 | + write_str_to_file(file_prefix+'os_version', header.os_version) | |
183 | + if header.os_patch_level: | |
184 | + write_str_to_file(file_prefix+'os_patch_level', header.os_patch_level) | |
137 | 185 | |
138 | 186 | seek_padding(args.input, header.headersz, args.pagesize) |
139 | 187 |
@@ -144,16 +192,50 @@ def write_data(args, header, off): | ||
144 | 192 | |
145 | 193 | fix_ramdisk_extension(file_prefix+'ramdisk') |
146 | 194 | |
195 | + if header.kernel_size >= 2: | |
196 | + if is_gzip_package(file_prefix+'zImage'): | |
197 | + with open(file_prefix+'zImage', 'rb') as f_in: | |
198 | + # seek past gzip header | |
199 | + f_in.seek(10) | |
200 | + | |
201 | + # write uncompressed zImage | |
202 | + with open(file_prefix+'zImage.gunzip', 'wb') as f_out: | |
203 | + decomp = zlib.decompressobj(-15) | |
204 | + f_out.write(decomp.decompress(f_in.read())) | |
205 | + | |
206 | + # write fdt | |
207 | + with open(file_prefix+'zImage.fdt', 'wb') as f_out: | |
208 | + f_out.write(decomp.unused_data[8:]) | |
209 | + | |
210 | + elif not is_arm64(file_prefix+'zImage'): | |
211 | + with open(file_prefix+'zImage', 'rb') as f_in: | |
212 | + # get kernel size | |
213 | + f_in.seek(0x28) | |
214 | + unpacked = auto_unpack('2I', f_in) | |
215 | + zimage_start = unpacked[0] | |
216 | + zimage_end = unpacked[1] | |
217 | + zimage_size = zimage_end - zimage_start; | |
218 | + | |
219 | + if zimage_size<header.kernel_size: | |
220 | + # write zImage | |
221 | + f_in.seek(0) | |
222 | + with open(file_prefix+'zImage.real', 'wb') as f_out: | |
223 | + f_out.write(f_in.read(zimage_size)) | |
224 | + | |
225 | + # write fdt | |
226 | + with open(file_prefix+'zImage.fdt', 'wb') as f_out: | |
227 | + f_out.write(f_in.read()) | |
228 | + | |
147 | 229 | def main(): |
148 | 230 | args = parse_cmdline() |
149 | 231 | off = get_magic_off(args.input) |
150 | 232 | header = read_header(args, off) |
151 | 233 | |
152 | 234 | print('BOARD_KERNEL_CMDLINE %s' % header.cmdline) |
153 | - print('BOARD_KERNEL_BASE %08x' % (header.kernel_addr - 0x00008000)) | |
154 | - print('BOARD_RAMDISK_OFFSET %08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
155 | - print('BOARD_SECOND_OFFSET %08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
156 | - print('BOARD_TAGS_OFFSET %08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
235 | + print('BOARD_KERNEL_BASE %08x' % header.kernel_offset) | |
236 | + print('BOARD_RAMDISK_OFFSET %08x' % header.ramdisk_offset) | |
237 | + print('BOARD_SECOND_OFFSET %08x' % header.second_offset) | |
238 | + print('BOARD_TAGS_OFFSET %08x' % header.tags_offset) | |
157 | 239 | print('BOARD_PAGE_SIZE %d' % header.pagesize) |
158 | 240 | print('BOARD_SECOND_SIZE %d' % header.second_size) |
159 | 241 | print('BOARD_DT_SIZE %d' % header.dt_size) |