mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 02:25:28 +00:00
Add gzip native support
This commit is contained in:
parent
2ccd8b8838
commit
f621fb2060
@ -3,6 +3,7 @@ LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := bootimgtools
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c parseimg.c
|
||||
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c parseimg.c compress.c
|
||||
LOCAL_CFLAGS += -std=gnu11
|
||||
LOCAL_LDLIBS += -lz
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
@ -28,9 +28,6 @@ typedef struct boot_img_hdr boot_img_hdr;
|
||||
#define BOOT_ARGS_SIZE 512
|
||||
#define BOOT_EXTRA_ARGS_SIZE 1024
|
||||
|
||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||
#define CHROMEOS_MAGIC_SIZE 8
|
||||
|
||||
struct boot_img_hdr
|
||||
{
|
||||
uint8_t magic[BOOT_MAGIC_SIZE];
|
||||
@ -76,10 +73,13 @@ struct boot_img_hdr
|
||||
** +-----------------+
|
||||
** | second stage | o pages
|
||||
** +-----------------+
|
||||
** | device tree | p pages
|
||||
** +-----------------+
|
||||
**
|
||||
** n = (kernel_size + page_size - 1) / page_size
|
||||
** m = (ramdisk_size + page_size - 1) / page_size
|
||||
** o = (second_size + page_size - 1) / page_size
|
||||
** p = (dt_size + page_size - 1) / page_size
|
||||
**
|
||||
** 0. all entities are page_size aligned in flash
|
||||
** 1. kernel and ramdisk are required (size != 0)
|
||||
@ -93,20 +93,4 @@ struct boot_img_hdr
|
||||
** else: jump to kernel_addr
|
||||
*/
|
||||
|
||||
|
||||
/* Self defined stuffs */
|
||||
|
||||
// Global pointers to mmap
|
||||
unsigned char *base, *kernel, *ramdisk, *second, *dtb;
|
||||
// Parsed header
|
||||
boot_img_hdr hdr;
|
||||
|
||||
int unpack(const char *image);
|
||||
int repack(const char *image);
|
||||
int hexpatch(char *image, char *from, char *to);
|
||||
void error(int rc, const char *msg, ...);
|
||||
void print_header();
|
||||
void parse_elf();
|
||||
void parse_aosp();
|
||||
|
||||
#endif
|
||||
|
59
jni/bootimgtools/compress.c
Normal file
59
jni/bootimgtools/compress.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "magiskboot.h"
|
||||
|
||||
void gzip(int dec, const char* filename, unsigned char* buf, size_t size) {
|
||||
int ret, flush, have, pos = 0;
|
||||
z_stream strm;
|
||||
unsigned char out[CHUNK];
|
||||
|
||||
int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
|
||||
if (fd < 0)
|
||||
error(1, "Unable to create %s", filename);
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
if (dec) {
|
||||
ret = inflateInit2(&strm, windowBits | ZLIB_GZIP);
|
||||
} else {
|
||||
ret = deflateInit2(&strm, 9, Z_DEFLATED, windowBits | ZLIB_GZIP, memLevel, Z_DEFAULT_STRATEGY);
|
||||
}
|
||||
|
||||
if (ret != Z_OK)
|
||||
error(1, "Unable to init zlib");
|
||||
|
||||
do {
|
||||
strm.next_in = buf + pos;
|
||||
if (pos + CHUNK > size) {
|
||||
strm.avail_in = size - pos;
|
||||
pos = size;
|
||||
flush = Z_FINISH;
|
||||
} else {
|
||||
strm.avail_in = CHUNK;
|
||||
pos += CHUNK;
|
||||
flush = Z_NO_FLUSH;
|
||||
}
|
||||
|
||||
do {
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
if (dec) {
|
||||
inflate(&strm, flush);
|
||||
} else {
|
||||
deflate(&strm, flush);
|
||||
}
|
||||
have = CHUNK - strm.avail_out;
|
||||
if (write(fd, out, have) != have)
|
||||
error(1, "Error in writing %s", filename);
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
} while(pos < size);
|
||||
|
||||
if (dec) {
|
||||
inflateEnd(&strm);
|
||||
} else {
|
||||
deflateEnd(&strm);
|
||||
}
|
||||
close(fd);
|
||||
}
|
@ -22,6 +22,8 @@
|
||||
** +-----------------+
|
||||
** | program header | dtb info
|
||||
** +-----------------+
|
||||
** | program header | (possible) cmdline info
|
||||
** +-----------------+
|
||||
** ~
|
||||
** +-----------------+
|
||||
** | section header | cmdline info
|
||||
|
@ -1,14 +1,4 @@
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
#include "magiskboot.h"
|
||||
|
||||
static int hex2int(char c) {
|
||||
int first = c / 16 - 3;
|
||||
@ -35,7 +25,7 @@ static void hexstr2str(char *hex, unsigned char *str) {
|
||||
}
|
||||
}
|
||||
|
||||
int hexpatch(char * image, char *from, char *to) {
|
||||
void hexpatch(char * image, char *from, char *to) {
|
||||
int fd = open(image, O_RDWR), patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
|
||||
size_t filesize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
@ -57,5 +47,4 @@ int hexpatch(char * image, char *from, char *to) {
|
||||
free(pattern);
|
||||
free(patch);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
62
jni/bootimgtools/magiskboot.h
Normal file
62
jni/bootimgtools/magiskboot.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef _ARCHIVE_H_
|
||||
#define _ARCHIVE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
|
||||
#define windowBits 15
|
||||
#define ZLIB_GZIP 16
|
||||
#define memLevel 8
|
||||
#define CHUNK 0x40000
|
||||
|
||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
||||
#define CHROMEOS_MAGIC_SIZE 8
|
||||
|
||||
#define KERNEL_FILE "kernel"
|
||||
#define RAMDISK_FILE "ramdisk.cpio"
|
||||
#define SECOND_FILE "second"
|
||||
#define DTB_FILE "dtb"
|
||||
|
||||
typedef enum {
|
||||
DONTCARE,
|
||||
CHROMEOS,
|
||||
AOSP,
|
||||
ELF,
|
||||
GZIP,
|
||||
LZOP,
|
||||
XZ,
|
||||
LZMA,
|
||||
BZIP2,
|
||||
LZ4,
|
||||
QCDT,
|
||||
} file_t;
|
||||
|
||||
// Global variables
|
||||
extern unsigned char *base, *kernel, *ramdisk, *second, *dtb;
|
||||
extern boot_img_hdr hdr;
|
||||
extern file_t boot_type, ramdisk_type, dtb_type;
|
||||
extern int mtk_kernel, mtk_ramdisk;
|
||||
|
||||
// Main entries
|
||||
void unpack(const char *image);
|
||||
void repack(const char *image);
|
||||
void hexpatch(char *image, char *from, char *to);
|
||||
void error(int rc, const char *msg, ...);
|
||||
|
||||
// Parse image
|
||||
void parse_img(unsigned char *orig, size_t size);
|
||||
|
||||
// Compressions
|
||||
void gzip(int dec, const char* filename, unsigned char* buf, size_t size);
|
||||
|
||||
#endif
|
@ -3,7 +3,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
#include "magiskboot.h"
|
||||
|
||||
/********************
|
||||
Patch Boot Image
|
||||
|
@ -6,8 +6,14 @@
|
||||
|
||||
#include "bootimg.h"
|
||||
#include "elf.h"
|
||||
#include "magiskboot.h"
|
||||
|
||||
void print_header() {
|
||||
unsigned char *base, *kernel, *ramdisk, *second, *dtb;
|
||||
boot_img_hdr hdr;
|
||||
int mtk_kernel = 0, mtk_ramdisk = 0;
|
||||
file_t boot_type, ramdisk_type, dtb_type;
|
||||
|
||||
static void check_headers() {
|
||||
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
|
||||
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
|
||||
printf("SECOND [%d] @ 0x%08x\n", hdr.second_size, hdr.second_addr);
|
||||
@ -30,6 +36,58 @@ void print_header() {
|
||||
}
|
||||
printf("NAME [%s]\n", hdr.name);
|
||||
printf("CMDLINE [%s]\n", hdr.cmdline);
|
||||
|
||||
// Check compression
|
||||
if (memcmp(ramdisk, "\x1f\x8b\x08\x00", 4) == 0) {
|
||||
// gzip header
|
||||
printf("COMPRESSION [gzip]\n");
|
||||
ramdisk_type = GZIP;
|
||||
} else if (memcmp(ramdisk, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
|
||||
// lzop header
|
||||
printf("COMPRESSION [lzop]\n");
|
||||
ramdisk_type = LZOP;
|
||||
} else if (memcmp(ramdisk, "\xfd""7zXZ\x00", 6) == 0) {
|
||||
// xz header
|
||||
printf("COMPRESSION [xz]\n");
|
||||
ramdisk_type = XZ;
|
||||
} else if (memcmp(ramdisk, "\x5d\x00\x00", 3) == 0
|
||||
&& (ramdisk[12] == (unsigned char) '\xff' || ramdisk[12] == (unsigned char) '\x00')) {
|
||||
// lzma header
|
||||
printf("COMPRESSION [lzma]\n");
|
||||
ramdisk_type = LZMA;
|
||||
} else if (memcmp(ramdisk, "BZh", 3) == 0) {
|
||||
// bzip2 header
|
||||
printf("COMPRESSION [bzip2]\n");
|
||||
ramdisk_type = BZIP2;
|
||||
} else if ( ( memcmp(ramdisk, "\x04\x22\x4d\x18", 4) == 0
|
||||
|| memcmp(ramdisk, "\x03\x21\x4c\x18", 4) == 0)
|
||||
|| memcmp(ramdisk, "\x02\x21\x4c\x18", 4) == 0) {
|
||||
// lz4 header
|
||||
printf("COMPRESSION [lz4]\n");
|
||||
ramdisk_type = LZ4;
|
||||
|
||||
} else {
|
||||
error(1, "Unknown ramdisk format!");
|
||||
}
|
||||
|
||||
// Check MTK
|
||||
if (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) {
|
||||
printf("MTK header found in kernel\n");
|
||||
mtk_kernel = 1;
|
||||
}
|
||||
if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) {
|
||||
printf("MTK header found in ramdisk\n");
|
||||
mtk_kernel = 1;
|
||||
}
|
||||
|
||||
// Check dtb
|
||||
if (boot_type == ELF && hdr.dt_size) {
|
||||
if (memcmp(dtb, "QCDT", 4) == 0) {
|
||||
dtb_type = QCDT;
|
||||
} else if (memcmp(dtb, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
||||
dtb_type = ELF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void page_align(unsigned char **pos) {
|
||||
@ -120,7 +178,7 @@ static void elf_set(int i, size_t size, size_t offset, size_t addr) {
|
||||
}
|
||||
}
|
||||
|
||||
void parse_elf() {
|
||||
static void parse_elf() {
|
||||
|
||||
// Reset boot image header
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
@ -191,10 +249,10 @@ void parse_elf() {
|
||||
error(1, "ELF format error!");
|
||||
}
|
||||
|
||||
print_header();
|
||||
check_headers();
|
||||
}
|
||||
|
||||
void parse_aosp() {
|
||||
static void parse_aosp() {
|
||||
|
||||
printf("IMG [AOSP]\n");
|
||||
|
||||
@ -228,5 +286,21 @@ void parse_aosp() {
|
||||
page_align(&pos);
|
||||
}
|
||||
|
||||
print_header();
|
||||
}
|
||||
check_headers();
|
||||
}
|
||||
|
||||
void parse_img(unsigned char *orig, size_t size) {
|
||||
for(base = orig; base < (orig + size); base += 256) {
|
||||
if (memcmp(base, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) {
|
||||
boot_type = CHROMEOS;
|
||||
} else if (memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
||||
if (boot_type != CHROMEOS) boot_type = AOSP;
|
||||
parse_aosp();
|
||||
break;
|
||||
} else if (memcmp(base, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
||||
boot_type = ELF;
|
||||
parse_elf();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "magiskboot.h"
|
||||
|
||||
#include "bootimg.h"
|
||||
#include "elf.h"
|
||||
|
||||
// Global pointer of current positions
|
||||
// Global pointer of output
|
||||
static int ofd, opos;
|
||||
|
||||
static size_t restore(const char *filename) {
|
||||
@ -49,34 +37,24 @@ static void page_align() {
|
||||
lseek(ofd, 0, SEEK_END);
|
||||
}
|
||||
|
||||
int repack(const char* image) {
|
||||
// Load original boot
|
||||
int ifd = open(image, O_RDONLY), ret = -1;
|
||||
void repack(const char* image) {
|
||||
// Load original image
|
||||
int ifd = open(image, O_RDONLY);
|
||||
if (ifd < 0)
|
||||
error(1, "Cannot open %s", image);
|
||||
|
||||
size_t isize = lseek(ifd, 0, SEEK_END);
|
||||
lseek(ifd, 0, SEEK_SET);
|
||||
unsigned char *orig = mmap(NULL, isize, PROT_READ, MAP_SHARED, ifd, 0);
|
||||
|
||||
// Parse original image
|
||||
parse_img(orig, isize);
|
||||
|
||||
// Create new boot image
|
||||
unlink("new-boot.img");
|
||||
ofd = open("new-boot.img", O_RDWR | O_CREAT, 0644);
|
||||
ofd = open("new-boot.img", O_RDWR | O_CREAT | O_TRUNC, 0644);
|
||||
|
||||
// Parse images
|
||||
for(base = orig; base < (orig + isize); base += 256) {
|
||||
if (memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
||||
parse_aosp();
|
||||
break;
|
||||
} else if (memcmp(base, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
||||
parse_elf();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
char *name;
|
||||
char name[PATH_MAX];
|
||||
#define EXT_NUM 6
|
||||
char *ext_list[EXT_NUM] = { "gz", "lzo", "xz", "lzma", "bz2", "lz4" };
|
||||
|
||||
// Set all sizes to 0
|
||||
hdr.kernel_size = 0;
|
||||
@ -90,52 +68,87 @@ int repack(const char* image) {
|
||||
opos += hdr.page_size;
|
||||
|
||||
// Restore kernel
|
||||
if (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) {
|
||||
printf("Dumping MTK header back to kernel\n");
|
||||
if (mtk_kernel) {
|
||||
restore_buf(512, kernel);
|
||||
hdr.kernel_size += 512;
|
||||
}
|
||||
hdr.kernel_size += restore("kernel");
|
||||
hdr.kernel_size += restore(KERNEL_FILE);
|
||||
page_align();
|
||||
|
||||
// Dump ramdisk
|
||||
if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) {
|
||||
printf("Dumping MTK header back to ramdisk\n");
|
||||
// Restore ramdisk
|
||||
if (mtk_ramdisk) {
|
||||
restore_buf(512, ramdisk);
|
||||
hdr.ramdisk_size += 512;
|
||||
}
|
||||
if (access("ramdisk.gz", R_OK) == 0) {
|
||||
name = "ramdisk.gz";
|
||||
} else if (access("ramdisk.lzo", R_OK) == 0) {
|
||||
name = "ramdisk.lzo";
|
||||
} else if (access("ramdisk.xz", R_OK) == 0) {
|
||||
name = "ramdisk.xz";
|
||||
} else if (access("ramdisk.lzma", R_OK) == 0) {
|
||||
name = "ramdisk.lzma";
|
||||
} else if (access("ramdisk.bz2", R_OK) == 0) {
|
||||
name = "ramdisk.bz2";
|
||||
} else if (access("ramdisk.lz4", R_OK) == 0) {
|
||||
name = "ramdisk.lz4";
|
||||
|
||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||
// If we found raw cpio, recompress to original format
|
||||
int rfd = open(RAMDISK_FILE, O_RDONLY);
|
||||
if (rfd < 0)
|
||||
error(1, "Cannot open " RAMDISK_FILE);
|
||||
|
||||
size_t cpio_size = lseek(rfd, 0, SEEK_END);
|
||||
lseek(rfd, 0, SEEK_SET);
|
||||
unsigned char *cpio = mmap(NULL, cpio_size, PROT_READ, MAP_SHARED, rfd, 0);
|
||||
|
||||
switch (ramdisk_type) {
|
||||
case GZIP:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "gz");
|
||||
gzip(0, name, cpio, cpio_size);
|
||||
break;
|
||||
case LZOP:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo");
|
||||
break;
|
||||
case XZ:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "xz");
|
||||
break;
|
||||
case LZMA:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "lzma");
|
||||
break;
|
||||
case BZIP2:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "bz2");
|
||||
break;
|
||||
case LZ4:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "lz4");
|
||||
break;
|
||||
default:
|
||||
// Never happens
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Re-compressed %s to %s\n", RAMDISK_FILE, name);
|
||||
munmap(cpio, cpio_size);
|
||||
close(rfd);
|
||||
} else {
|
||||
error(1, "Ramdisk file doesn't exist!");
|
||||
// If no raw cpio found, find compressed ones
|
||||
int found = 0;
|
||||
for (int i = 0; i < EXT_NUM; ++i) {
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]);
|
||||
if (access(name, R_OK) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
error(1, "No ramdisk exists!");
|
||||
}
|
||||
}
|
||||
|
||||
hdr.ramdisk_size += restore(name);
|
||||
page_align();
|
||||
|
||||
// Dump second
|
||||
if (access("second", R_OK) == 0) {
|
||||
hdr.second_size += restore("second");
|
||||
// Restore second
|
||||
if (access(SECOND_FILE, R_OK) == 0) {
|
||||
hdr.second_size += restore(SECOND_FILE);
|
||||
page_align();
|
||||
}
|
||||
|
||||
// Dump dtb
|
||||
if (access("dtb", R_OK) == 0) {
|
||||
hdr.dt_size += restore("dtb");
|
||||
// Restore dtb
|
||||
if (access(DTB_FILE, R_OK) == 0) {
|
||||
hdr.dt_size += restore(DTB_FILE);
|
||||
page_align();
|
||||
}
|
||||
|
||||
print_header();
|
||||
|
||||
// Write header back
|
||||
lseek(ofd, 0, SEEK_SET);
|
||||
write(ofd, &hdr, sizeof(hdr));
|
||||
@ -143,5 +156,7 @@ int repack(const char* image) {
|
||||
munmap(orig, isize);
|
||||
close(ifd);
|
||||
close(ofd);
|
||||
return ret;
|
||||
if (opos > isize) {
|
||||
error(2, "Boot partition too small!");
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bootimg.h"
|
||||
#include "elf.h"
|
||||
#include "magiskboot.h"
|
||||
|
||||
static void dump(unsigned char *buf, size_t size, const char *filename) {
|
||||
unlink(filename);
|
||||
int ofd = open(filename, O_WRONLY | O_CREAT, 0644);
|
||||
int ofd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (ofd < 0)
|
||||
error(1, "Cannot open %s", filename);
|
||||
if (write(ofd, buf, size) != size)
|
||||
@ -22,8 +9,8 @@ static void dump(unsigned char *buf, size_t size, const char *filename) {
|
||||
close(ofd);
|
||||
}
|
||||
|
||||
int unpack(const char* image) {
|
||||
int fd = open(image, O_RDONLY), ret = 0;
|
||||
void unpack(const char* image) {
|
||||
int fd = open(image, O_RDONLY);
|
||||
if (fd < 0)
|
||||
error(1, "Cannot open %s", image);
|
||||
|
||||
@ -31,81 +18,75 @@ int unpack(const char* image) {
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
unsigned char *orig = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
|
||||
// Parse images
|
||||
for(base = orig; base < (orig + size); base += 256) {
|
||||
if (memcmp(base, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) {
|
||||
dump(base, 0, "chromeos");
|
||||
} else if (memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
||||
parse_aosp();
|
||||
break;
|
||||
} else if (memcmp(base, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
||||
parse_elf();
|
||||
break;
|
||||
}
|
||||
// Parse image
|
||||
parse_img(orig, size);
|
||||
|
||||
if (boot_type == CHROMEOS) {
|
||||
// The caller should know it's chromeos, as it needs additional signing
|
||||
dump(base, 0, "chromeos");
|
||||
}
|
||||
|
||||
char name[PATH_MAX], *ext;
|
||||
char name[PATH_MAX];
|
||||
|
||||
// Dump kernel
|
||||
if (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) {
|
||||
printf("MTK header found in kernel\n");
|
||||
if (mtk_kernel) {
|
||||
kernel += 512;
|
||||
hdr.kernel_size -= 512;
|
||||
}
|
||||
dump(kernel, hdr.kernel_size, "kernel");
|
||||
dump(kernel, hdr.kernel_size, KERNEL_FILE);
|
||||
|
||||
// Dump ramdisk
|
||||
if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) {
|
||||
printf("MTK header found in ramdisk\n");
|
||||
if (mtk_ramdisk) {
|
||||
ramdisk += 512;
|
||||
hdr.ramdisk_size -= 512;
|
||||
}
|
||||
// Compression detection
|
||||
if (memcmp(ramdisk, "\x1f\x8b\x08\x00", 4) == 0) {
|
||||
// gzip header
|
||||
printf("COMPRESSION [gzip]\n");
|
||||
ext = "gz";
|
||||
} else if (memcmp(ramdisk, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
|
||||
// lzop header
|
||||
printf("COMPRESSION [lzop]\n");
|
||||
ext = "lzo";
|
||||
} else if (memcmp(ramdisk, "\xfd""7zXZ\x00", 6) == 0) {
|
||||
// xz header
|
||||
printf("COMPRESSION [xz]\n");
|
||||
ext = "xz";
|
||||
} else if (memcmp(ramdisk, "\x5d\x00\x00", 3) == 0
|
||||
&& (ramdisk[12] == (unsigned char) '\xff' || ramdisk[12] == (unsigned char) '\x00')) {
|
||||
// lzma header
|
||||
printf("COMPRESSION [lzma]\n");
|
||||
ext = "lzma";
|
||||
} else if (memcmp(ramdisk, "BZh", 3) == 0) {
|
||||
// bzip2 header
|
||||
printf("COMPRESSION [bzip2]\n");
|
||||
ext = "bz2";
|
||||
} else if ( ( memcmp(ramdisk, "\x04\x22\x4d\x18", 4) == 0
|
||||
|| memcmp(ramdisk, "\x03\x21\x4c\x18", 4) == 0)
|
||||
|| memcmp(ramdisk, "\x02\x21\x4c\x18", 4) == 0) {
|
||||
// lz4 header
|
||||
printf("COMPRESSION [lz4]\n");
|
||||
ext = "lz4";
|
||||
} else {
|
||||
error(1, "Unknown ramdisk format!");
|
||||
|
||||
switch (ramdisk_type) {
|
||||
case GZIP:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "gz");
|
||||
gzip(1, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
|
||||
break;
|
||||
case LZOP:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo");
|
||||
break;
|
||||
case XZ:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "xz");
|
||||
break;
|
||||
case LZMA:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "lzma");
|
||||
break;
|
||||
case BZIP2:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "bz2");
|
||||
break;
|
||||
case LZ4:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "lz4");
|
||||
break;
|
||||
default:
|
||||
// Never happens
|
||||
break;
|
||||
}
|
||||
sprintf(name, "%s.%s", "ramdisk", ext);
|
||||
// Dump the compressed ramdisk, just in case
|
||||
dump(ramdisk, hdr.ramdisk_size, name);
|
||||
|
||||
if (hdr.second_size) {
|
||||
// Dump second
|
||||
dump(second, hdr.second_size, "second");
|
||||
dump(second, hdr.second_size, SECOND_FILE);
|
||||
}
|
||||
|
||||
if (hdr.dt_size) {
|
||||
// Dump dtb
|
||||
dump(dtb, hdr.dt_size, "dtb");
|
||||
if (boot_type == ELF && (dtb_type != QCDT && dtb_type != ELF )) {
|
||||
printf("Non QC dtb found in ELF kernel, recreate kernel\n");
|
||||
gzip(0, KERNEL_FILE, kernel, hdr.kernel_size);
|
||||
int kfp = open(KERNEL_FILE, O_WRONLY | O_APPEND);
|
||||
write(kfp, dtb, hdr.dt_size);
|
||||
close(kfp);
|
||||
} else {
|
||||
// Dump dtb
|
||||
dump(dtb, hdr.dt_size, DTB_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
munmap(orig, size);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user