Created
March 17, 2018 07:36
-
-
Save manjotsidhu/409216b871645f6c48e184e3cd331d2d to your computer and use it in GitHub Desktop.
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
From f20d184176c66c16f0568a0673633594ffae0d30 Mon Sep 17 00:00:00 2001 | |
From: Steve Kondik <steve@cyngn.com> | |
Date: Mon, 2 Aug 2010 11:23:47 -0700 | |
Subject: [PATCH] Forward-port mkbootimg / unpackbootimg support | |
* Mostly from Koush and Seth Shelnutt | |
unpackbootimg (squashed) | |
unpackbootimg ported forward from eclair | |
Change-Id: I74d2df0b47d40e7105cc58c2b05f8f383dc7f8a0 | |
port forward pagesize arg from eclair | |
Change-Id: Ia789a4f392a3890aa0efa7efb42032482b48beb0 | |
unpackbootimg should output BOARD_PAGE_SIZE | |
Change-Id: Ieb5cda01943a33da97eee4d025f56c2c6e7560e8 | |
output page size in mkbootimg | |
add an option to override the pagesize for boot images created by nubs. ie, acer liquid mkliquidbootimg. | |
Change-Id: Ie0c7e67edf5ae59019517e72b9be8c0b81388e41 | |
Update unpackbootimg to verify the Android boot image magic value. It will also search the first 512 bytes for padding. | |
Change-Id: I490cba05f2bb616a3f64e3271ecaa61eb9e64be8 | |
unpackbootimg: Fix up the padding search in case the magic does not fall on a 8 byte boundary. | |
Change-Id: I57471f9c2117cd7965b6958ea0aa88e356436da6 | |
unpackbootimg: Fix magic search. | |
Change-Id: I68470b637556a08e48ff72b7ef8811cba13b04ad | |
unpackbootimg: apparently mkbootimg no longer accepts hex values | |
Change-Id: I95a33f7b40470e4500d418d863a65a75e7aa8499 | |
unpackbootimg: Need to also update the written file. | |
Change-Id: I45faddbae85273c79b2837f97933634b6e70546f | |
ramdiskaddr is now ramdisk_offset | |
Change-Id: I3bf83af5f7001f581506dc7fd9b1eb653334ad35 | |
unpackbootimg: remove host LOCAL_MODULE_TAG | |
Change-Id: I199d680dc5ab8bf50f5be65c29095bf3adade695 | |
unpackbootimg: Add support for device trees | |
Change-Id: I340eed99d2274a2f4cbaf5a9f27726ff3a9302e5 | |
unpackbootimg: Add support for detecting lz4 compressed ramdisks | |
This will check for lz4 magic, and if found change the extension of the | |
file. Else it'll fall back to the default behavior of assuming gzip. This has | |
been tested with stock LS980 boot images and LS970 boot images for lz4 | |
and gzip respectively. | |
Change-Id: If2139ff172397b6db079ffb7ab9cb61897c38fb3 | |
unpackbootimg: Add support for dumping ramdisk offset | |
Change-Id: Ic62b9fe61db4435ecbc52b66db5ffc9b9d79cbb4 | |
unpackbootimg: Add support for second, second_offset and tags_offset. | |
Change-Id: Ia7ef7f00191dbf2c44736c4e4d980f72afa8c253 | |
--- | |
mkbootimg/Android.mk | 5 ++ | |
mkbootimg/unpackbootimg.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++ | |
2 files changed, 216 insertions(+) | |
create mode 100644 mkbootimg/unpackbootimg.c | |
diff --git a/mkbootimg/Android.mk b/mkbootimg/Android.mk | |
index 8661d7d..ed4fbdf 100644 | |
--- a/mkbootimg/Android.mk | |
+++ b/mkbootimg/Android.mk | |
@@ -9,3 +9,8 @@ LOCAL_IS_HOST_MODULE := true | |
LOCAL_MODULE := mkbootimg | |
include $(BUILD_PREBUILT) | |
+ | |
+include $(CLEAR_VARS) | |
+LOCAL_SRC_FILES := unpackbootimg.c | |
+LOCAL_MODULE := unpackbootimg | |
+include $(BUILD_HOST_EXECUTABLE) | |
diff --git a/mkbootimg/unpackbootimg.c b/mkbootimg/unpackbootimg.c | |
new file mode 100644 | |
index 0000000..3d2fda7 | |
--- /dev/null | |
+++ b/mkbootimg/unpackbootimg.c | |
@@ -0,0 +1,211 @@ | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <unistd.h> | |
+#include <fcntl.h> | |
+#include <errno.h> | |
+#include <limits.h> | |
+#include <libgen.h> | |
+ | |
+#include "mincrypt/sha.h" | |
+#include "bootimg.h" | |
+ | |
+typedef unsigned char byte; | |
+ | |
+int read_padding(FILE* f, unsigned itemsize, int pagesize) | |
+{ | |
+ byte* buf = (byte*)malloc(sizeof(byte) * pagesize); | |
+ unsigned pagemask = pagesize - 1; | |
+ unsigned count; | |
+ | |
+ if((itemsize & pagemask) == 0) { | |
+ free(buf); | |
+ return 0; | |
+ } | |
+ | |
+ count = pagesize - (itemsize & pagemask); | |
+ | |
+ fread(buf, count, 1, f); | |
+ free(buf); | |
+ return count; | |
+} | |
+ | |
+void write_string_to_file(char* file, char* string) | |
+{ | |
+ FILE* f = fopen(file, "w"); | |
+ fwrite(string, strlen(string), 1, f); | |
+ fwrite("\n", 1, 1, f); | |
+ fclose(f); | |
+} | |
+ | |
+int usage() { | |
+ printf("usage: unpackbootimg\n"); | |
+ printf("\t-i|--input boot.img\n"); | |
+ printf("\t[ -o|--output output_directory]\n"); | |
+ printf("\t[ -p|--pagesize <size-in-hexadecimal> ]\n"); | |
+ return 0; | |
+} | |
+ | |
+int main(int argc, char** argv) | |
+{ | |
+ char tmp[PATH_MAX]; | |
+ char* directory = "./"; | |
+ char* filename = NULL; | |
+ int pagesize = 0; | |
+ | |
+ argc--; | |
+ argv++; | |
+ while(argc > 0){ | |
+ char *arg = argv[0]; | |
+ char *val = argv[1]; | |
+ argc -= 2; | |
+ argv += 2; | |
+ if(!strcmp(arg, "--input") || !strcmp(arg, "-i")) { | |
+ filename = val; | |
+ } else if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { | |
+ directory = val; | |
+ } else if(!strcmp(arg, "--pagesize") || !strcmp(arg, "-p")) { | |
+ pagesize = strtoul(val, 0, 16); | |
+ } else { | |
+ return usage(); | |
+ } | |
+ } | |
+ | |
+ if (filename == NULL) { | |
+ return usage(); | |
+ } | |
+ | |
+ int total_read = 0; | |
+ FILE* f = fopen(filename, "rb"); | |
+ boot_img_hdr header; | |
+ | |
+ //printf("Reading header...\n"); | |
+ int i; | |
+ for (i = 0; i <= 512; i++) { | |
+ fseek(f, i, SEEK_SET); | |
+ fread(tmp, BOOT_MAGIC_SIZE, 1, f); | |
+ if (memcmp(tmp, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) | |
+ break; | |
+ } | |
+ total_read = i; | |
+ if (i > 512) { | |
+ printf("Android boot magic not found.\n"); | |
+ return 1; | |
+ } | |
+ fseek(f, i, SEEK_SET); | |
+ printf("Android magic found at: %d\n", i); | |
+ | |
+ fread(&header, sizeof(header), 1, f); | |
+ printf("BOARD_KERNEL_CMDLINE %s\n", header.cmdline); | |
+ printf("BOARD_KERNEL_BASE %08x\n", header.kernel_addr - 0x00008000); | |
+ printf("BOARD_RAMDISK_OFFSET %08x\n", header.ramdisk_addr - header.kernel_addr + 0x00008000); | |
+ printf("BOARD_SECOND_OFFSET %08x\n", header.second_addr - header.kernel_addr + 0x00008000); | |
+ printf("BOARD_TAGS_OFFSET %08x\n",header.tags_addr - header.kernel_addr + 0x00008000); | |
+ printf("BOARD_PAGE_SIZE %d\n", header.page_size); | |
+ printf("BOARD_SECOND_SIZE %d\n", header.second_size); | |
+ printf("BOARD_DT_SIZE %d\n", header.dt_size); | |
+ | |
+ if (pagesize == 0) { | |
+ pagesize = header.page_size; | |
+ } | |
+ | |
+ //printf("cmdline...\n"); | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-cmdline"); | |
+ write_string_to_file(tmp, header.cmdline); | |
+ | |
+ //printf("base...\n"); | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-base"); | |
+ char basetmp[200]; | |
+ sprintf(basetmp, "%08x", header.kernel_addr - 0x00008000); | |
+ write_string_to_file(tmp, basetmp); | |
+ | |
+ //printf("ramdisk_offset...\n"); | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-ramdisk_offset"); | |
+ char ramdisktmp[200]; | |
+ sprintf(ramdisktmp, "%08x", header.ramdisk_addr - header.kernel_addr + 0x00008000); | |
+ write_string_to_file(tmp, ramdisktmp); | |
+ | |
+ //printf("second_offset...\n"); | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-second_offset"); | |
+ char secondtmp[200]; | |
+ sprintf(secondtmp, "%08x", header.second_addr - header.kernel_addr + 0x00008000); | |
+ write_string_to_file(tmp, secondtmp); | |
+ | |
+ //printf("tags_offset...\n"); | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-tags_offset"); | |
+ char tagstmp[200]; | |
+ sprintf(tagstmp, "%08x", header.tags_addr - header.kernel_addr + 0x00008000); | |
+ write_string_to_file(tmp, tagstmp); | |
+ | |
+ //printf("pagesize...\n"); | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-pagesize"); | |
+ char pagesizetmp[200]; | |
+ sprintf(pagesizetmp, "%d", header.page_size); | |
+ write_string_to_file(tmp, pagesizetmp); | |
+ | |
+ total_read += sizeof(header); | |
+ //printf("total read: %d\n", total_read); | |
+ total_read += read_padding(f, sizeof(header), pagesize); | |
+ | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-zImage"); | |
+ FILE *k = fopen(tmp, "wb"); | |
+ byte* kernel = (byte*)malloc(header.kernel_size); | |
+ //printf("Reading kernel...\n"); | |
+ fread(kernel, header.kernel_size, 1, f); | |
+ total_read += header.kernel_size; | |
+ fwrite(kernel, header.kernel_size, 1, k); | |
+ fclose(k); | |
+ | |
+ //printf("total read: %d\n", header.kernel_size); | |
+ total_read += read_padding(f, header.kernel_size, pagesize); | |
+ | |
+ | |
+ byte* ramdisk = (byte*)malloc(header.ramdisk_size); | |
+ //printf("Reading ramdisk...\n"); | |
+ fread(ramdisk, header.ramdisk_size, 1, f); | |
+ total_read += header.ramdisk_size; | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ if(ramdisk[0] == 0x02 && ramdisk[1]== 0x21) | |
+ strcat(tmp, "-ramdisk.lz4"); | |
+ else | |
+ strcat(tmp, "-ramdisk.gz"); | |
+ FILE *r = fopen(tmp, "wb"); | |
+ fwrite(ramdisk, header.ramdisk_size, 1, r); | |
+ fclose(r); | |
+ | |
+ total_read += read_padding(f, header.ramdisk_size, pagesize); | |
+ | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-second"); | |
+ FILE *s = fopen(tmp, "wb"); | |
+ byte* second = (byte*)malloc(header.second_size); | |
+ //printf("Reading second...\n"); | |
+ fread(second, header.second_size, 1, f); | |
+ total_read += header.second_size; | |
+ fwrite(second, header.second_size, 1, r); | |
+ fclose(s); | |
+ | |
+ total_read += read_padding(f, header.second_size, pagesize); | |
+ | |
+ sprintf(tmp, "%s/%s", directory, basename(filename)); | |
+ strcat(tmp, "-dt"); | |
+ FILE *d = fopen(tmp, "wb"); | |
+ byte* dt = (byte*)malloc(header.dt_size); | |
+ //printf("Reading dt...\n"); | |
+ fread(dt, header.dt_size, 1, f); | |
+ total_read += header.dt_size; | |
+ fwrite(dt, header.dt_size, 1, r); | |
+ fclose(d); | |
+ | |
+ fclose(f); | |
+ | |
+ //printf("Total Read: %d\n", total_read); | |
+ return 0; | |
+} | |
-- | |
2.7.4 |
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
From 4984ad1cbe03022f8d0df8f60898b00425f85959 Mon Sep 17 00:00:00 2001 | |
From: M1cha <sigmaepsilon92@gmail.com> | |
Date: Fri, 26 Aug 2016 06:29:27 +0200 | |
Subject: [PATCH] unpackbootimg: turn into a python script | |
Turn unpackbootimg into a python script instead of a C utility | |
Change-Id: If049319d12ee9841eefb9ca3fdae5c775403bbbf | |
--- | |
mkbootimg/Android.mk | 10 ++- | |
mkbootimg/unpackbootimg | 167 ++++++++++++++++++++++++++++++++++++ | |
mkbootimg/unpackbootimg.c | 211 ---------------------------------------------- | |
3 files changed, 175 insertions(+), 213 deletions(-) | |
create mode 100755 mkbootimg/unpackbootimg | |
delete mode 100644 mkbootimg/unpackbootimg.c | |
diff --git a/mkbootimg/Android.mk b/mkbootimg/Android.mk | |
index ed4fbdf..f52297d 100644 | |
--- a/mkbootimg/Android.mk | |
+++ b/mkbootimg/Android.mk | |
@@ -10,7 +10,13 @@ LOCAL_MODULE := mkbootimg | |
include $(BUILD_PREBUILT) | |
+ | |
include $(CLEAR_VARS) | |
-LOCAL_SRC_FILES := unpackbootimg.c | |
+ | |
+LOCAL_SRC_FILES := unpackbootimg | |
+LOCAL_MODULE_CLASS := EXECUTABLES | |
+LOCAL_IS_HOST_MODULE := true | |
+ | |
LOCAL_MODULE := unpackbootimg | |
-include $(BUILD_HOST_EXECUTABLE) | |
+ | |
+include $(BUILD_PREBUILT) | |
diff --git a/mkbootimg/unpackbootimg b/mkbootimg/unpackbootimg | |
new file mode 100755 | |
index 0000000..2415a5f | |
--- /dev/null | |
+++ b/mkbootimg/unpackbootimg | |
@@ -0,0 +1,167 @@ | |
+#!/usr/bin/env python | |
+# Copyright 2015, 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. | |
+ | |
+from __future__ import print_function | |
+from sys import exit | |
+from argparse import ArgumentParser, FileType | |
+from os import rename | |
+from os.path import basename | |
+from struct import unpack, calcsize | |
+ | |
+class Bunch: | |
+ def __init__(self, **kwds): | |
+ self.__dict__.update(kwds) | |
+ | |
+def auto_unpack(fmt, f): | |
+ size = calcsize(fmt) | |
+ data = f.read(size) | |
+ return unpack(fmt, data[0:size]) | |
+ | |
+def get_magic_off(f): | |
+ BOOT_MAGIC = 'ANDROID!'.encode() | |
+ | |
+ for i in range(513): | |
+ f.seek(i) | |
+ tmp = f.read(len(BOOT_MAGIC)) | |
+ if tmp == BOOT_MAGIC: | |
+ print('Android magic found at: %d' % i) | |
+ return i | |
+ | |
+ print('Android boot magic not found.'); | |
+ exit(1) | |
+ | |
+def read_header(args, off): | |
+ args.input.seek(off) | |
+ fmt = '8s10I16s512s32s1024s' | |
+ unpacked = auto_unpack(fmt, args.input) | |
+ | |
+ parsed = Bunch() | |
+ parsed.headersz = calcsize(fmt) | |
+ parsed.magic = unpacked[0] | |
+ parsed.kernel_size = unpacked[1] | |
+ parsed.kernel_addr = unpacked[2] | |
+ parsed.ramdisk_size = unpacked[3] | |
+ parsed.ramdisk_addr = unpacked[4] | |
+ parsed.second_size = unpacked[5] | |
+ parsed.second_addr = unpacked[6] | |
+ parsed.tags_addr = unpacked[7] | |
+ parsed.pagesize = unpacked[8] | |
+ parsed.dt_size = unpacked[9] | |
+ parsed.name = unpacked[11].partition(b'\0')[0].decode() | |
+ parsed.cmdline = unpacked[12].partition(b'\0')[0].decode() | |
+ parsed.id = unpacked[13] | |
+ parsed.cmdline += unpacked[14].partition(b'\0')[0].decode() | |
+ | |
+ os_version = unpacked[10]>>11 | |
+ os_patch_level = unpacked[10]&0x7ff | |
+ | |
+ a = (os_version>>14)&0x7f | |
+ b = (os_version>>7)&0x7f | |
+ c = os_version&0x7f | |
+ parsed.os_version = '%d.%d.%d' % (a,b,c) | |
+ | |
+ y = (os_patch_level>>4) + 2000 | |
+ m = os_patch_level&0xf | |
+ parsed.os_patch_level = '%04d-%02d-%02d' % (y,m,0) | |
+ | |
+ return parsed | |
+ | |
+def write_str_to_file(filename, s): | |
+ with open(filename, 'wb') as f: | |
+ f.write(s.encode()) | |
+ | |
+def parse_int(x): | |
+ return int(x, 0) | |
+ | |
+def parse_cmdline(): | |
+ parser = ArgumentParser() | |
+ parser.add_argument('-i', '--input', help='input file name', type=FileType('rb'), | |
+ required=True) | |
+ parser.add_argument('-o', '--output', help='output directory', default='') | |
+ parser.add_argument('--pagesize', help='page size', type=parse_int, | |
+ choices=[2**i for i in range(11,15)], default=0) | |
+ return parser.parse_args() | |
+ | |
+def seek_padding(f, size, pagesize): | |
+ pagemask = pagesize - 1; | |
+ if((size & pagemask) != 0): | |
+ count = pagesize - (size & pagemask); | |
+ f.seek(count, 1); | |
+ | |
+def write_input_to_file(args, filename, size): | |
+ with open(filename, 'wb') as f_out: | |
+ f_out.write(args.input.read(size)) | |
+ | |
+ seek_padding(args.input, size, args.pagesize) | |
+ | |
+def fix_ramdisk_extension(filename): | |
+ bytes = [] | |
+ with open(filename, 'rb') as f: | |
+ data = f.read(2) | |
+ if(len(data))!=2: | |
+ return | |
+ bytes = unpack('BB', data) | |
+ | |
+ if bytes[0]==0x02 and bytes[1]==0x21: | |
+ rename(filename, filename+'.lz4') | |
+ else: | |
+ rename(filename, filename+'.gz') | |
+ | |
+def write_data(args, header, off): | |
+ file_prefix = args.output | |
+ if file_prefix and file_prefix[-1]!='/': | |
+ file_prefix += '/' | |
+ file_prefix += basename(args.input.name) + '-' | |
+ | |
+ write_str_to_file(file_prefix+'cmdline', header.cmdline) | |
+ write_str_to_file(file_prefix+'base', '%08x' % (header.kernel_addr - 0x00008000)) | |
+ write_str_to_file(file_prefix+'ramdisk_offset', '%08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
+ write_str_to_file(file_prefix+'second_offset', '%08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
+ write_str_to_file(file_prefix+'tags_offset', '%08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
+ write_str_to_file(file_prefix+'pagesize', '%d' % header.pagesize) | |
+ write_str_to_file(file_prefix+'name', header.name) | |
+ write_str_to_file(file_prefix+'os_version', header.os_version) | |
+ write_str_to_file(file_prefix+'os_patch_level', header.os_patch_level) | |
+ | |
+ seek_padding(args.input, header.headersz, args.pagesize) | |
+ | |
+ write_input_to_file(args, file_prefix+'zImage', header.kernel_size) | |
+ write_input_to_file(args, file_prefix+'ramdisk', header.ramdisk_size) | |
+ write_input_to_file(args, file_prefix+'second', header.second_size) | |
+ write_input_to_file(args, file_prefix+'dt', header.dt_size) | |
+ | |
+ fix_ramdisk_extension(file_prefix+'ramdisk') | |
+ | |
+def main(): | |
+ args = parse_cmdline() | |
+ off = get_magic_off(args.input) | |
+ header = read_header(args, off) | |
+ | |
+ print('BOARD_KERNEL_CMDLINE %s' % header.cmdline) | |
+ print('BOARD_KERNEL_BASE %08x' % (header.kernel_addr - 0x00008000)) | |
+ print('BOARD_RAMDISK_OFFSET %08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
+ print('BOARD_SECOND_OFFSET %08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
+ print('BOARD_TAGS_OFFSET %08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
+ print('BOARD_PAGE_SIZE %d' % header.pagesize) | |
+ print('BOARD_SECOND_SIZE %d' % header.second_size) | |
+ print('BOARD_DT_SIZE %d' % header.dt_size) | |
+ | |
+ if args.pagesize == 0: | |
+ args.pagesize = header.pagesize | |
+ | |
+ write_data(args, header, off) | |
+ | |
+if __name__ == '__main__': | |
+ main() | |
diff --git a/mkbootimg/unpackbootimg.c b/mkbootimg/unpackbootimg.c | |
deleted file mode 100644 | |
index 3d2fda7..0000000 | |
--- a/mkbootimg/unpackbootimg.c | |
+++ /dev/null | |
@@ -1,211 +0,0 @@ | |
-#include <stdio.h> | |
-#include <stdlib.h> | |
-#include <string.h> | |
-#include <unistd.h> | |
-#include <fcntl.h> | |
-#include <errno.h> | |
-#include <limits.h> | |
-#include <libgen.h> | |
- | |
-#include "mincrypt/sha.h" | |
-#include "bootimg.h" | |
- | |
-typedef unsigned char byte; | |
- | |
-int read_padding(FILE* f, unsigned itemsize, int pagesize) | |
-{ | |
- byte* buf = (byte*)malloc(sizeof(byte) * pagesize); | |
- unsigned pagemask = pagesize - 1; | |
- unsigned count; | |
- | |
- if((itemsize & pagemask) == 0) { | |
- free(buf); | |
- return 0; | |
- } | |
- | |
- count = pagesize - (itemsize & pagemask); | |
- | |
- fread(buf, count, 1, f); | |
- free(buf); | |
- return count; | |
-} | |
- | |
-void write_string_to_file(char* file, char* string) | |
-{ | |
- FILE* f = fopen(file, "w"); | |
- fwrite(string, strlen(string), 1, f); | |
- fwrite("\n", 1, 1, f); | |
- fclose(f); | |
-} | |
- | |
-int usage() { | |
- printf("usage: unpackbootimg\n"); | |
- printf("\t-i|--input boot.img\n"); | |
- printf("\t[ -o|--output output_directory]\n"); | |
- printf("\t[ -p|--pagesize <size-in-hexadecimal> ]\n"); | |
- return 0; | |
-} | |
- | |
-int main(int argc, char** argv) | |
-{ | |
- char tmp[PATH_MAX]; | |
- char* directory = "./"; | |
- char* filename = NULL; | |
- int pagesize = 0; | |
- | |
- argc--; | |
- argv++; | |
- while(argc > 0){ | |
- char *arg = argv[0]; | |
- char *val = argv[1]; | |
- argc -= 2; | |
- argv += 2; | |
- if(!strcmp(arg, "--input") || !strcmp(arg, "-i")) { | |
- filename = val; | |
- } else if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { | |
- directory = val; | |
- } else if(!strcmp(arg, "--pagesize") || !strcmp(arg, "-p")) { | |
- pagesize = strtoul(val, 0, 16); | |
- } else { | |
- return usage(); | |
- } | |
- } | |
- | |
- if (filename == NULL) { | |
- return usage(); | |
- } | |
- | |
- int total_read = 0; | |
- FILE* f = fopen(filename, "rb"); | |
- boot_img_hdr header; | |
- | |
- //printf("Reading header...\n"); | |
- int i; | |
- for (i = 0; i <= 512; i++) { | |
- fseek(f, i, SEEK_SET); | |
- fread(tmp, BOOT_MAGIC_SIZE, 1, f); | |
- if (memcmp(tmp, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) | |
- break; | |
- } | |
- total_read = i; | |
- if (i > 512) { | |
- printf("Android boot magic not found.\n"); | |
- return 1; | |
- } | |
- fseek(f, i, SEEK_SET); | |
- printf("Android magic found at: %d\n", i); | |
- | |
- fread(&header, sizeof(header), 1, f); | |
- printf("BOARD_KERNEL_CMDLINE %s\n", header.cmdline); | |
- printf("BOARD_KERNEL_BASE %08x\n", header.kernel_addr - 0x00008000); | |
- printf("BOARD_RAMDISK_OFFSET %08x\n", header.ramdisk_addr - header.kernel_addr + 0x00008000); | |
- printf("BOARD_SECOND_OFFSET %08x\n", header.second_addr - header.kernel_addr + 0x00008000); | |
- printf("BOARD_TAGS_OFFSET %08x\n",header.tags_addr - header.kernel_addr + 0x00008000); | |
- printf("BOARD_PAGE_SIZE %d\n", header.page_size); | |
- printf("BOARD_SECOND_SIZE %d\n", header.second_size); | |
- printf("BOARD_DT_SIZE %d\n", header.dt_size); | |
- | |
- if (pagesize == 0) { | |
- pagesize = header.page_size; | |
- } | |
- | |
- //printf("cmdline...\n"); | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-cmdline"); | |
- write_string_to_file(tmp, header.cmdline); | |
- | |
- //printf("base...\n"); | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-base"); | |
- char basetmp[200]; | |
- sprintf(basetmp, "%08x", header.kernel_addr - 0x00008000); | |
- write_string_to_file(tmp, basetmp); | |
- | |
- //printf("ramdisk_offset...\n"); | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-ramdisk_offset"); | |
- char ramdisktmp[200]; | |
- sprintf(ramdisktmp, "%08x", header.ramdisk_addr - header.kernel_addr + 0x00008000); | |
- write_string_to_file(tmp, ramdisktmp); | |
- | |
- //printf("second_offset...\n"); | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-second_offset"); | |
- char secondtmp[200]; | |
- sprintf(secondtmp, "%08x", header.second_addr - header.kernel_addr + 0x00008000); | |
- write_string_to_file(tmp, secondtmp); | |
- | |
- //printf("tags_offset...\n"); | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-tags_offset"); | |
- char tagstmp[200]; | |
- sprintf(tagstmp, "%08x", header.tags_addr - header.kernel_addr + 0x00008000); | |
- write_string_to_file(tmp, tagstmp); | |
- | |
- //printf("pagesize...\n"); | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-pagesize"); | |
- char pagesizetmp[200]; | |
- sprintf(pagesizetmp, "%d", header.page_size); | |
- write_string_to_file(tmp, pagesizetmp); | |
- | |
- total_read += sizeof(header); | |
- //printf("total read: %d\n", total_read); | |
- total_read += read_padding(f, sizeof(header), pagesize); | |
- | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-zImage"); | |
- FILE *k = fopen(tmp, "wb"); | |
- byte* kernel = (byte*)malloc(header.kernel_size); | |
- //printf("Reading kernel...\n"); | |
- fread(kernel, header.kernel_size, 1, f); | |
- total_read += header.kernel_size; | |
- fwrite(kernel, header.kernel_size, 1, k); | |
- fclose(k); | |
- | |
- //printf("total read: %d\n", header.kernel_size); | |
- total_read += read_padding(f, header.kernel_size, pagesize); | |
- | |
- | |
- byte* ramdisk = (byte*)malloc(header.ramdisk_size); | |
- //printf("Reading ramdisk...\n"); | |
- fread(ramdisk, header.ramdisk_size, 1, f); | |
- total_read += header.ramdisk_size; | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- if(ramdisk[0] == 0x02 && ramdisk[1]== 0x21) | |
- strcat(tmp, "-ramdisk.lz4"); | |
- else | |
- strcat(tmp, "-ramdisk.gz"); | |
- FILE *r = fopen(tmp, "wb"); | |
- fwrite(ramdisk, header.ramdisk_size, 1, r); | |
- fclose(r); | |
- | |
- total_read += read_padding(f, header.ramdisk_size, pagesize); | |
- | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-second"); | |
- FILE *s = fopen(tmp, "wb"); | |
- byte* second = (byte*)malloc(header.second_size); | |
- //printf("Reading second...\n"); | |
- fread(second, header.second_size, 1, f); | |
- total_read += header.second_size; | |
- fwrite(second, header.second_size, 1, r); | |
- fclose(s); | |
- | |
- total_read += read_padding(f, header.second_size, pagesize); | |
- | |
- sprintf(tmp, "%s/%s", directory, basename(filename)); | |
- strcat(tmp, "-dt"); | |
- FILE *d = fopen(tmp, "wb"); | |
- byte* dt = (byte*)malloc(header.dt_size); | |
- //printf("Reading dt...\n"); | |
- fread(dt, header.dt_size, 1, f); | |
- total_read += header.dt_size; | |
- fwrite(dt, header.dt_size, 1, r); | |
- fclose(d); | |
- | |
- fclose(f); | |
- | |
- //printf("Total Read: %d\n", total_read); | |
- return 0; | |
-} | |
-- | |
2.7.4 |
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
From a68eec6b0a132f1ccf52b0592aeef6a397785457 Mon Sep 17 00:00:00 2001 | |
From: M1cha <sigmaepsilon92@gmail.com> | |
Date: Sun, 4 Sep 2016 12:59:51 +0200 | |
Subject: [PATCH] unpackbootimg: stash EFIDroid changes | |
Source: https://github.com/efidroid/build/commits/5a8c5e9fe25cb4e0e182f55c1dc96d49a95b341c/tools/unpackbootimg | |
commit c0bb55fdf63c6ba5b8f4b30303ab624e5cd1eab0 | |
Author: M1cha <sigmaepsilon92@gmail.com> | |
Date: Fri Aug 26 11:12:28 2016 +0200 | |
unpackbootimg: extract appended fdt too | |
commit 39fa4df2e200501400a7f80097543c684c91ad8b | |
Author: M1cha <sigmaepsilon92@gmail.com> | |
Date: Sun Aug 28 20:49:00 2016 +0200 | |
tools: unpackbootimg: don't write os_version and os_patch_level if they are 0 | |
commit 4bf90a6ecc2530c3eb6d97d90a595655f5c8189f | |
Author: M1cha <sigmaepsilon92@gmail.com> | |
Date: Sun Sep 4 10:54:43 2016 +0200 | |
tools: unpackbootimg: create output directory if it doesn't exist | |
commit 863757ec8f008f189aeb188a6fb8bf8718c040e6 | |
Author: M1cha <sigmaepsilon92@gmail.com> | |
Date: Sun Sep 4 10:57:02 2016 +0200 | |
tools: unpackbootimg: don't try to split zImage if it's too small | |
commit 21c7d91fce55bf6ec242ad81768f679a461166cf | |
Author: M1cha <sigmaepsilon92@gmail.com> | |
Date: Sun Sep 4 10:57:29 2016 +0200 | |
tools: unpackbootimg: fix base and offset calculations | |
commit 5a8c5e9fe25cb4e0e182f55c1dc96d49a95b341c | |
Author: M1cha <sigmaepsilon92@gmail.com> | |
Date: Sun Sep 4 11:09:47 2016 +0200 | |
tools: unpackbootimg: improve base calculation by substracting 0x8000 | |
Change-Id: I62f4f92c5caaed06cd3858900135231f91f6bc79 | |
--- | |
mkbootimg/unpackbootimg | 124 ++++++++++++++++++++++++++++++++++++++++-------- | |
1 file changed, 103 insertions(+), 21 deletions(-) | |
diff --git a/mkbootimg/unpackbootimg b/mkbootimg/unpackbootimg | |
index 198c8fc..b5dc663 100755 | |
--- a/mkbootimg/unpackbootimg | |
+++ b/mkbootimg/unpackbootimg | |
@@ -16,9 +16,13 @@ | |
from __future__ import print_function | |
from sys import exit | |
from argparse import ArgumentParser, FileType | |
-from os import rename | |
-from os.path import basename | |
+from os import rename, makedirs | |
+from os.path import basename, exists | |
from struct import unpack, calcsize | |
+import zlib | |
+ | |
+def ROUNDDOWN(number, alignment): | |
+ return ((number) & ~((alignment)-1)) | |
class Bunch: | |
def __init__(self, **kwds): | |
@@ -67,14 +71,30 @@ def read_header(args, off): | |
os_version = unpacked[10]>>11 | |
os_patch_level = unpacked[10]&0x7ff | |
- a = (os_version>>14)&0x7f | |
- b = (os_version>>7)&0x7f | |
- c = os_version&0x7f | |
- parsed.os_version = '%d.%d.%d' % (a,b,c) | |
- | |
- y = (os_patch_level>>4) + 2000 | |
- m = os_patch_level&0xf | |
- parsed.os_patch_level = '%04d-%02d-%02d' % (y,m,0) | |
+ parsed.os_version = None | |
+ if os_version != 0: | |
+ a = (os_version>>14)&0x7f | |
+ b = (os_version>>7)&0x7f | |
+ c = os_version&0x7f | |
+ parsed.os_version = '%d.%d.%d' % (a,b,c) | |
+ | |
+ parsed.os_patch_level = None | |
+ if os_patch_level != 0: | |
+ y = (os_patch_level>>4) + 2000 | |
+ m = os_patch_level&0xf | |
+ parsed.os_patch_level = '%04d-%02d-%02d' % (y,m,0) | |
+ | |
+ # find common base of all loading addresses | |
+ parsed.base = min(parsed.kernel_addr, parsed.ramdisk_addr, parsed.second_addr, parsed.tags_addr) | |
+ parsed.base = ROUNDDOWN(parsed.base, parsed.pagesize) | |
+ if (parsed.base&0xffff) == 0x8000: | |
+ parsed.base -= 0x8000 | |
+ | |
+ # calculate offsets relative to base | |
+ parsed.kernel_offset = parsed.kernel_addr - parsed.base | |
+ parsed.ramdisk_offset = parsed.ramdisk_addr - parsed.base | |
+ parsed.second_offset = parsed.second_addr - parsed.base | |
+ parsed.tags_offset = parsed.tags_addr - parsed.base | |
return parsed | |
@@ -89,7 +109,7 @@ def parse_cmdline(): | |
parser = ArgumentParser() | |
parser.add_argument('-i', '--input', help='input file name', type=FileType('rb'), | |
required=True) | |
- parser.add_argument('-o', '--output', help='output directory', default='') | |
+ parser.add_argument('-o', '--output', help='output directory', default='./') | |
parser.add_argument('--pagesize', help='page size', type=parse_int, | |
choices=[2**i for i in range(11,18)], default=0) | |
return parser.parse_args() | |
@@ -119,21 +139,49 @@ def fix_ramdisk_extension(filename): | |
else: | |
rename(filename, filename+'.gz') | |
+def is_gzip_package(filename): | |
+ bytes = [] | |
+ with open(filename, 'rb') as f: | |
+ data = f.read(3) | |
+ if(len(data))!=3: | |
+ return False | |
+ bytes = unpack('BBB', data) | |
+ | |
+ return bytes[0]==0x1f and bytes[1]==0x8b and bytes[2]==0x08 | |
+ | |
+def is_arm64(filename): | |
+ data = None | |
+ with open(filename, 'rb') as f: | |
+ fmt = '2I6Q2I' | |
+ size = calcsize(fmt) | |
+ buf = f.read(size) | |
+ if(len(buf))!=size: | |
+ return False | |
+ data = unpack(fmt, buf) | |
+ | |
+ return data[8]==0x644D5241 | |
+ | |
def write_data(args, header, off): | |
file_prefix = args.output | |
if file_prefix and file_prefix[-1]!='/': | |
file_prefix += '/' | |
file_prefix += basename(args.input.name) + '-' | |
+ if not exists(args.output): | |
+ makedirs(args.output) | |
+ | |
write_str_to_file(file_prefix+'cmdline', header.cmdline) | |
- write_str_to_file(file_prefix+'base', '%08x' % (header.kernel_addr - 0x00008000)) | |
- write_str_to_file(file_prefix+'ramdisk_offset', '%08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
- write_str_to_file(file_prefix+'second_offset', '%08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
- write_str_to_file(file_prefix+'tags_offset', '%08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
+ write_str_to_file(file_prefix+'base', '%08x' % header.base) | |
+ write_str_to_file(file_prefix+'kernel_offset', '%08x' % header.kernel_offset) | |
+ write_str_to_file(file_prefix+'ramdisk_offset', '%08x' % header.ramdisk_offset) | |
+ write_str_to_file(file_prefix+'second_offset', '%08x' % header.second_offset) | |
+ write_str_to_file(file_prefix+'tags_offset', '%08x' % header.tags_offset) | |
write_str_to_file(file_prefix+'pagesize', '%d' % header.pagesize) | |
write_str_to_file(file_prefix+'name', header.name) | |
- write_str_to_file(file_prefix+'os_version', header.os_version) | |
- write_str_to_file(file_prefix+'os_patch_level', header.os_patch_level) | |
+ if header.os_version: | |
+ write_str_to_file(file_prefix+'os_version', header.os_version) | |
+ if header.os_patch_level: | |
+ write_str_to_file(file_prefix+'os_patch_level', header.os_patch_level) | |
seek_padding(args.input, header.headersz, args.pagesize) | |
@@ -144,16 +192,50 @@ def write_data(args, header, off): | |
fix_ramdisk_extension(file_prefix+'ramdisk') | |
+ if header.kernel_size >= 2: | |
+ if is_gzip_package(file_prefix+'zImage'): | |
+ with open(file_prefix+'zImage', 'rb') as f_in: | |
+ # seek past gzip header | |
+ f_in.seek(10) | |
+ | |
+ # write uncompressed zImage | |
+ with open(file_prefix+'zImage.gunzip', 'wb') as f_out: | |
+ decomp = zlib.decompressobj(-15) | |
+ f_out.write(decomp.decompress(f_in.read())) | |
+ | |
+ # write fdt | |
+ with open(file_prefix+'zImage.fdt', 'wb') as f_out: | |
+ f_out.write(decomp.unused_data[8:]) | |
+ | |
+ elif not is_arm64(file_prefix+'zImage'): | |
+ with open(file_prefix+'zImage', 'rb') as f_in: | |
+ # get kernel size | |
+ f_in.seek(0x28) | |
+ unpacked = auto_unpack('2I', f_in) | |
+ zimage_start = unpacked[0] | |
+ zimage_end = unpacked[1] | |
+ zimage_size = zimage_end - zimage_start; | |
+ | |
+ if zimage_size<header.kernel_size: | |
+ # write zImage | |
+ f_in.seek(0) | |
+ with open(file_prefix+'zImage.real', 'wb') as f_out: | |
+ f_out.write(f_in.read(zimage_size)) | |
+ | |
+ # write fdt | |
+ with open(file_prefix+'zImage.fdt', 'wb') as f_out: | |
+ f_out.write(f_in.read()) | |
+ | |
def main(): | |
args = parse_cmdline() | |
off = get_magic_off(args.input) | |
header = read_header(args, off) | |
print('BOARD_KERNEL_CMDLINE %s' % header.cmdline) | |
- print('BOARD_KERNEL_BASE %08x' % (header.kernel_addr - 0x00008000)) | |
- print('BOARD_RAMDISK_OFFSET %08x' % (header.ramdisk_addr - header.kernel_addr + 0x00008000)) | |
- print('BOARD_SECOND_OFFSET %08x' % (header.second_addr - header.kernel_addr + 0x00008000)) | |
- print('BOARD_TAGS_OFFSET %08x' % (header.tags_addr - header.kernel_addr + 0x00008000)) | |
+ print('BOARD_KERNEL_BASE %08x' % header.kernel_offset) | |
+ print('BOARD_RAMDISK_OFFSET %08x' % header.ramdisk_offset) | |
+ print('BOARD_SECOND_OFFSET %08x' % header.second_offset) | |
+ print('BOARD_TAGS_OFFSET %08x' % header.tags_offset) | |
print('BOARD_PAGE_SIZE %d' % header.pagesize) | |
print('BOARD_SECOND_SIZE %d' % header.second_size) | |
print('BOARD_DT_SIZE %d' % header.dt_size) | |
-- | |
2.7.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment