Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5bf5139
Showing
5 changed files
with
323 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
|
||
LOCAL_PATH:= $(call my-dir) | ||
include $(CLEAR_VARS) | ||
|
||
LOCAL_SRC_FILES := mkbootimg.c | ||
LOCAL_STATIC_LIBRARIES := libmincrypt | ||
|
||
LOCAL_MODULE := mkbootimg | ||
|
||
include $(BUILD_HOST_EXECUTABLE) | ||
|
||
|
||
include $(CLEAR_VARS) | ||
|
||
LOCAL_SRC_FILES := unbootimg.c | ||
LOCAL_STATIC_LIBRARIES := libmincrypt | ||
|
||
LOCAL_MODULE := unbootimg | ||
|
||
include $(BUILD_HOST_EXECUTABLE) | ||
|
||
|
||
include $(CLEAR_VARS) | ||
|
||
LOCAL_PREBUILT_EXECUTABLES := unpack.sh repack.sh | ||
|
||
include $(BUILD_HOST_PREBUILT) | ||
|
||
|
||
$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE)) |
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,67 @@ | ||
Unbootimg | ||
========= | ||
|
||
When working on Android, I found it useful to be able to unpack a boot image, | ||
replace a few files and repack it. unbootimg is the perfect complement to the | ||
mkbootimg tool that is used to create boot images. | ||
|
||
unbootimg takes a boot image and produces all that is necessary in order to | ||
create a new image using mkbootimg. In particular it extracts the kernel command | ||
line and the addresses of the image parts, and creates a command line for | ||
mkbootimg to regenerate the image as close to the original one. It even verifies | ||
the SHA1 checks! | ||
|
||
unpack and repack | ||
----------------- | ||
|
||
`unpack.sh` and `repack.sh` are trivial shell wrappers for unbootimg that also | ||
take care of the ramdisk packaging: cpio and gzip. They are designed to | ||
complement, so that this would simply recreate boot.img without changes: | ||
|
||
unpack.sh boot.img | ||
repack.sh boot.img | ||
|
||
Building | ||
-------- | ||
|
||
If you already have the AOSP repo and managed to build mkbootimg, adding | ||
unbootimg is easy. | ||
|
||
- Download unbootimg.zip | ||
- Unpack it to your mydroid/repo/system/core/mkbootimg. Note: it overwrites | ||
Android.mk to include unbootimg. | ||
- Build it: | ||
cd mydroid/repo | ||
. build/envsetup.sh | ||
mmm system/core/mkbootimg | ||
# OR | ||
make mkbootimg unbootimg repack.sh unpack.sh | ||
- Put `mydroid/repo/out/host/linux-x86/bin` in your path. Easiest way to do this | ||
is: | ||
setpaths # this is defined by Android build system | ||
|
||
unbootimg depends (like mkbootimg) on libmincrypt for computing the SHA1, but | ||
this can easily be disabled in the source code. | ||
|
||
If you'd rather use pre-built binaries, here's a package with both unbootimg and | ||
mkbootimg: unbootimg-bin.zip | ||
|
||
Usage | ||
----- | ||
|
||
# on the phone: copy the boot or recovery image, for example | ||
dd if=/dev/mtd/mtd3 of=/sdcard/recovery-backup.img | ||
# on the host: pull the backup | ||
adb pull /sdcard/recovery-backup.img . | ||
# unpack it | ||
unpack.sh recovery-backup.img | ||
# edit as you wish: | ||
# cmdline: recovery-backup.img-mk | ||
# kernel: recovery-backup.img-kernel | ||
# ramdisk: recovery-backup.img-ramdisk/ | ||
# repack it | ||
repack.sh recovery-backup.img | ||
# send to phone | ||
adb push recovery-backup.img /sdcard | ||
# flash it using flash_image | ||
|
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,21 @@ | ||
#!/bin/bash | ||
# szym.net, 2010 | ||
# Simple wrapper that uses mkbootimg to resassemble a boot image | ||
# disassembled with unbootimg (see unpack.sh). | ||
|
||
MKBOOTIMG=mkbootimg | ||
|
||
if [ $# -ne 1 ]; then | ||
echo 1>&2 Usage: $0 imagefile.img | ||
exit 127 | ||
fi | ||
|
||
set -e | ||
|
||
IMG=$1 | ||
|
||
cd ${IMG}-ramdisk | ||
find . | cpio -o -H newc | gzip > ../${IMG}-ramdisk.cpio.gz | ||
cd .. | ||
bash -c "${MKBOOTIMG} `cat ${IMG}-mk`" | ||
|
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,183 @@ | ||
/* tools/unbootimg/unbootimg.c | ||
** | ||
** Copyright 2010 szym.net | ||
** | ||
** A simple utility that reverses the actions of mkbootimg. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
#include <fcntl.h> | ||
#include <errno.h> | ||
|
||
#undef NDEBUG | ||
#include <assert.h> // FIXME? | ||
|
||
//#define NOMINCRYPT | ||
#ifndef NOMINCRYPT | ||
#include "mincrypt/sha.h" | ||
#endif | ||
|
||
#include "bootimg.h" | ||
|
||
int usage(void) | ||
{ | ||
fprintf(stderr,"usage: unbootimg <filename>\n" | ||
" Creates <filename>-mk <filename>-kernel <filename>-ramdisk.cpio.gz [<filename>-second]\n" | ||
" Remake with mkbootimg `cat <filename>-mk`\n"); | ||
return 1; | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
const boot_img_hdr *hdr; | ||
|
||
const void *kernel_data = 0; | ||
const void *ramdisk_data = 0; | ||
const void *second_data = 0; | ||
const char *cmdline = 0; | ||
const char *bootimg = 0; | ||
const char *board = 0; | ||
unsigned pagesize = 2048; | ||
int fd; | ||
void *img_data = 0; | ||
unsigned int sz = 0; | ||
#ifndef NOMINCRYPT | ||
SHA_CTX ctx; | ||
const uint8_t* sha; | ||
#endif | ||
|
||
unsigned int base; | ||
|
||
char buf[256]; | ||
FILE *fout; | ||
|
||
if (argc != 2) { | ||
return usage(); | ||
} | ||
|
||
// open img file -- read all into memory | ||
bootimg = argv[1]; | ||
fd = open(bootimg, O_RDONLY); | ||
if(fd < 0) { | ||
fprintf(stderr,"Could not open %s\n", bootimg); | ||
return 1; | ||
} | ||
// does not work | ||
sz = lseek(fd, 0, SEEK_END); | ||
assert (sz > 0); | ||
|
||
assert(lseek(fd, 0, SEEK_SET) == 0); | ||
|
||
img_data = (char*) malloc(sz); | ||
assert(img_data != 0); | ||
|
||
assert(read(fd, (char *)img_data, sz) == sz); | ||
close(fd); | ||
|
||
// parse and check hdr | ||
hdr = (boot_img_hdr *)img_data; | ||
|
||
if(memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE) != 0) { | ||
fprintf(stderr,"error: kernel magic mismatch\n"); | ||
fprintf(stderr,"%s\n", hdr->magic); | ||
return 1; | ||
} | ||
|
||
cmdline = hdr->cmdline; | ||
if(strnlen(cmdline, BOOT_ARGS_SIZE) == BOOT_ARGS_SIZE) { | ||
fprintf(stderr,"error: kernel commandline too large\n"); | ||
return 1; | ||
} | ||
|
||
board = hdr->name; | ||
if(strnlen(board, BOOT_NAME_SIZE) == BOOT_NAME_SIZE) { | ||
fprintf(stderr,"error: board name too large\n"); | ||
return 1; | ||
} | ||
|
||
if (hdr->page_size != pagesize) { | ||
fprintf(stderr,"WARNING: non-standard page_size!\n"); | ||
pagesize = hdr->page_size; | ||
} | ||
|
||
#define PADDED(x) ((((int)(x)-1)/pagesize+1)*pagesize) | ||
kernel_data = (char*)hdr + pagesize; | ||
ramdisk_data = (char*)kernel_data + PADDED(hdr->kernel_size); | ||
second_data = (char*)ramdisk_data + PADDED(hdr->ramdisk_size); | ||
if ((char *)second_data + PADDED(hdr->second_size) != (char *)img_data + sz) { | ||
fprintf(stderr,"section sizes incorrect\nkernel %x %x\nramdisk %x %x\nsecond %x %x\ntotal %x %x\n", | ||
(char*)kernel_data-(char*)hdr, hdr->kernel_size, | ||
(char*)ramdisk_data-(char*)hdr, hdr->ramdisk_size, | ||
(char*)second_data-(char*)hdr, hdr->second_size, | ||
(char *)second_data-(char*)hdr + PADDED(hdr->second_size), sz); | ||
if ((char *)second_data-(char*)hdr + PADDED(hdr->second_size) < sz) { | ||
fprintf(stderr, "...but we can still continue\n"); | ||
} else { | ||
return 1; | ||
} | ||
} | ||
#undef PADDED | ||
|
||
base = hdr->kernel_addr - 0x00008000; | ||
if ((hdr->ramdisk_addr != base + 0x01000000) || | ||
(hdr->second_addr != base + 0x00F00000) || | ||
(hdr->tags_addr != base + 0x00000100)) { | ||
fprintf(stderr,"WARNING: non-standard load addresses!\n"); | ||
} | ||
|
||
#ifndef NOMINCRYPT | ||
// check hash | ||
SHA_init(&ctx); | ||
SHA_update(&ctx, kernel_data, hdr->kernel_size); | ||
SHA_update(&ctx, &hdr->kernel_size, sizeof(hdr->kernel_size)); | ||
SHA_update(&ctx, ramdisk_data, hdr->ramdisk_size); | ||
SHA_update(&ctx, &hdr->ramdisk_size, sizeof(hdr->ramdisk_size)); | ||
SHA_update(&ctx, second_data, hdr->second_size); | ||
SHA_update(&ctx, &hdr->second_size, sizeof(hdr->second_size)); | ||
sha = SHA_final(&ctx); | ||
if(memcmp(hdr->id, sha, | ||
SHA_DIGEST_SIZE > sizeof(hdr->id) ? sizeof(hdr->id) : SHA_DIGEST_SIZE) != 0) { | ||
fprintf(stderr, "WARNING: SHA checksum does not match\n"); | ||
} | ||
#endif | ||
|
||
sprintf(buf, "%s-mk", bootimg); | ||
fout = fopen(buf, "w"); | ||
if (fout == 0) { | ||
fprintf(stderr,"could not open %s for writing", buf); | ||
return 1; | ||
} | ||
fprintf(fout, "--output %s --kernel %s-kernel --ramdisk %s%s %s %s%s --cmdline '%s' --board '%s' --base %x", | ||
bootimg, bootimg, | ||
hdr->ramdisk_size ? bootimg : "NONE", hdr->ramdisk_size ? "-ramdisk.cpio.gz" : "", | ||
hdr->second_size ? "--second" : "", hdr->second_size ? bootimg : "", hdr->second_size ? "-second" : "", | ||
cmdline, board, base); | ||
fclose(fout); | ||
|
||
sprintf(buf, "%s-kernel", bootimg); | ||
fd = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0644); | ||
if(fd < 0) { | ||
fprintf(stderr,"error: could not create '%s'\n", buf); | ||
return 1; | ||
} | ||
assert(write(fd, kernel_data, hdr->kernel_size) == hdr->kernel_size); | ||
close(fd); | ||
if(hdr->ramdisk_size) { | ||
sprintf(buf, "%s-ramdisk.cpio.gz", bootimg); | ||
fd = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0644); | ||
assert(fd >= 0); | ||
assert(write(fd, ramdisk_data, hdr->ramdisk_size) == hdr->ramdisk_size); | ||
close(fd); | ||
} | ||
if(hdr->second_size) { | ||
sprintf(buf, "%s-second", bootimg); | ||
fd = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0644); | ||
assert(fd >= 0); | ||
assert(write(fd, second_data, hdr->second_size) == hdr->second_size); | ||
close(fd); | ||
} | ||
return 0; | ||
} |
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,22 @@ | ||
#!/bin/bash | ||
# szym.net, 2010 | ||
# Simple wrapper that uses unbootimg to disassemble a boot image | ||
# and unzip the ramdisk. | ||
|
||
UNBOOTIMG=unbootimg | ||
|
||
if [ $# -ne 1 ]; then | ||
echo 1>&2 Usage: $0 imagefile.img | ||
exit 127 | ||
fi | ||
|
||
set -e | ||
|
||
IMG=$1 | ||
|
||
${UNBOOTIMG} ${IMG} | ||
mkdir ${IMG}-ramdisk | ||
cd ${IMG}-ramdisk | ||
gunzip -c ../${IMG}-ramdisk.cpio.gz | cpio -i | ||
cd .. | ||
|