mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-17 17:58: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)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := bootimgtools
|
LOCAL_MODULE := bootimgtools
|
||||||
LOCAL_MODULE_TAGS := optional
|
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_CFLAGS += -std=gnu11
|
||||||
|
LOCAL_LDLIBS += -lz
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
@ -28,9 +28,6 @@ typedef struct boot_img_hdr boot_img_hdr;
|
|||||||
#define BOOT_ARGS_SIZE 512
|
#define BOOT_ARGS_SIZE 512
|
||||||
#define BOOT_EXTRA_ARGS_SIZE 1024
|
#define BOOT_EXTRA_ARGS_SIZE 1024
|
||||||
|
|
||||||
#define CHROMEOS_MAGIC "CHROMEOS"
|
|
||||||
#define CHROMEOS_MAGIC_SIZE 8
|
|
||||||
|
|
||||||
struct boot_img_hdr
|
struct boot_img_hdr
|
||||||
{
|
{
|
||||||
uint8_t magic[BOOT_MAGIC_SIZE];
|
uint8_t magic[BOOT_MAGIC_SIZE];
|
||||||
@ -76,10 +73,13 @@ struct boot_img_hdr
|
|||||||
** +-----------------+
|
** +-----------------+
|
||||||
** | second stage | o pages
|
** | second stage | o pages
|
||||||
** +-----------------+
|
** +-----------------+
|
||||||
|
** | device tree | p pages
|
||||||
|
** +-----------------+
|
||||||
**
|
**
|
||||||
** n = (kernel_size + page_size - 1) / page_size
|
** n = (kernel_size + page_size - 1) / page_size
|
||||||
** m = (ramdisk_size + page_size - 1) / page_size
|
** m = (ramdisk_size + page_size - 1) / page_size
|
||||||
** o = (second_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
|
** 0. all entities are page_size aligned in flash
|
||||||
** 1. kernel and ramdisk are required (size != 0)
|
** 1. kernel and ramdisk are required (size != 0)
|
||||||
@ -93,20 +93,4 @@ struct boot_img_hdr
|
|||||||
** else: jump to kernel_addr
|
** 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
|
#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 | dtb info
|
||||||
** +-----------------+
|
** +-----------------+
|
||||||
|
** | program header | (possible) cmdline info
|
||||||
|
** +-----------------+
|
||||||
** ~
|
** ~
|
||||||
** +-----------------+
|
** +-----------------+
|
||||||
** | section header | cmdline info
|
** | section header | cmdline info
|
||||||
|
@ -1,14 +1,4 @@
|
|||||||
#include <getopt.h>
|
#include "magiskboot.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"
|
|
||||||
|
|
||||||
static int hex2int(char c) {
|
static int hex2int(char c) {
|
||||||
int first = c / 16 - 3;
|
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;
|
int fd = open(image, O_RDWR), patternsize = strlen(from) / 2, patchsize = strlen(to) / 2;
|
||||||
size_t filesize = lseek(fd, 0, SEEK_END);
|
size_t filesize = lseek(fd, 0, SEEK_END);
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
@ -57,5 +47,4 @@ int hexpatch(char * image, char *from, char *to) {
|
|||||||
free(pattern);
|
free(pattern);
|
||||||
free(patch);
|
free(patch);
|
||||||
close(fd);
|
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 <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "bootimg.h"
|
#include "magiskboot.h"
|
||||||
|
|
||||||
/********************
|
/********************
|
||||||
Patch Boot Image
|
Patch Boot Image
|
||||||
|
@ -6,8 +6,14 @@
|
|||||||
|
|
||||||
#include "bootimg.h"
|
#include "bootimg.h"
|
||||||
#include "elf.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("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
|
||||||
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_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);
|
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("NAME [%s]\n", hdr.name);
|
||||||
printf("CMDLINE [%s]\n", hdr.cmdline);
|
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) {
|
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
|
// Reset boot image header
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
@ -191,10 +249,10 @@ void parse_elf() {
|
|||||||
error(1, "ELF format error!");
|
error(1, "ELF format error!");
|
||||||
}
|
}
|
||||||
|
|
||||||
print_header();
|
check_headers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_aosp() {
|
static void parse_aosp() {
|
||||||
|
|
||||||
printf("IMG [AOSP]\n");
|
printf("IMG [AOSP]\n");
|
||||||
|
|
||||||
@ -228,5 +286,21 @@ void parse_aosp() {
|
|||||||
page_align(&pos);
|
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 "magiskboot.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"
|
// Global pointer of output
|
||||||
#include "elf.h"
|
|
||||||
|
|
||||||
// Global pointer of current positions
|
|
||||||
static int ofd, opos;
|
static int ofd, opos;
|
||||||
|
|
||||||
static size_t restore(const char *filename) {
|
static size_t restore(const char *filename) {
|
||||||
@ -49,34 +37,24 @@ static void page_align() {
|
|||||||
lseek(ofd, 0, SEEK_END);
|
lseek(ofd, 0, SEEK_END);
|
||||||
}
|
}
|
||||||
|
|
||||||
int repack(const char* image) {
|
void repack(const char* image) {
|
||||||
// Load original boot
|
// Load original image
|
||||||
int ifd = open(image, O_RDONLY), ret = -1;
|
int ifd = open(image, O_RDONLY);
|
||||||
if (ifd < 0)
|
if (ifd < 0)
|
||||||
error(1, "Cannot open %s", image);
|
error(1, "Cannot open %s", image);
|
||||||
|
|
||||||
size_t isize = lseek(ifd, 0, SEEK_END);
|
size_t isize = lseek(ifd, 0, SEEK_END);
|
||||||
lseek(ifd, 0, SEEK_SET);
|
lseek(ifd, 0, SEEK_SET);
|
||||||
unsigned char *orig = mmap(NULL, isize, PROT_READ, MAP_SHARED, ifd, 0);
|
unsigned char *orig = mmap(NULL, isize, PROT_READ, MAP_SHARED, ifd, 0);
|
||||||
|
|
||||||
|
// Parse original image
|
||||||
|
parse_img(orig, isize);
|
||||||
|
|
||||||
// Create new boot image
|
// Create new boot image
|
||||||
unlink("new-boot.img");
|
ofd = open("new-boot.img", O_RDWR | O_CREAT | O_TRUNC, 0644);
|
||||||
ofd = open("new-boot.img", O_RDWR | O_CREAT, 0644);
|
|
||||||
|
|
||||||
// Parse images
|
char name[PATH_MAX];
|
||||||
for(base = orig; base < (orig + isize); base += 256) {
|
#define EXT_NUM 6
|
||||||
if (memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
|
char *ext_list[EXT_NUM] = { "gz", "lzo", "xz", "lzma", "bz2", "lz4" };
|
||||||
parse_aosp();
|
|
||||||
break;
|
|
||||||
} else if (memcmp(base, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
|
|
||||||
parse_elf();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
// Set all sizes to 0
|
// Set all sizes to 0
|
||||||
hdr.kernel_size = 0;
|
hdr.kernel_size = 0;
|
||||||
@ -90,52 +68,87 @@ int repack(const char* image) {
|
|||||||
opos += hdr.page_size;
|
opos += hdr.page_size;
|
||||||
|
|
||||||
// Restore kernel
|
// Restore kernel
|
||||||
if (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) {
|
if (mtk_kernel) {
|
||||||
printf("Dumping MTK header back to kernel\n");
|
|
||||||
restore_buf(512, kernel);
|
restore_buf(512, kernel);
|
||||||
hdr.kernel_size += 512;
|
hdr.kernel_size += 512;
|
||||||
}
|
}
|
||||||
hdr.kernel_size += restore("kernel");
|
hdr.kernel_size += restore(KERNEL_FILE);
|
||||||
page_align();
|
page_align();
|
||||||
|
|
||||||
// Dump ramdisk
|
// Restore ramdisk
|
||||||
if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) {
|
if (mtk_ramdisk) {
|
||||||
printf("Dumping MTK header back to ramdisk\n");
|
|
||||||
restore_buf(512, ramdisk);
|
restore_buf(512, ramdisk);
|
||||||
hdr.ramdisk_size += 512;
|
hdr.ramdisk_size += 512;
|
||||||
}
|
}
|
||||||
if (access("ramdisk.gz", R_OK) == 0) {
|
|
||||||
name = "ramdisk.gz";
|
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||||
} else if (access("ramdisk.lzo", R_OK) == 0) {
|
// If we found raw cpio, recompress to original format
|
||||||
name = "ramdisk.lzo";
|
int rfd = open(RAMDISK_FILE, O_RDONLY);
|
||||||
} else if (access("ramdisk.xz", R_OK) == 0) {
|
if (rfd < 0)
|
||||||
name = "ramdisk.xz";
|
error(1, "Cannot open " RAMDISK_FILE);
|
||||||
} else if (access("ramdisk.lzma", R_OK) == 0) {
|
|
||||||
name = "ramdisk.lzma";
|
size_t cpio_size = lseek(rfd, 0, SEEK_END);
|
||||||
} else if (access("ramdisk.bz2", R_OK) == 0) {
|
lseek(rfd, 0, SEEK_SET);
|
||||||
name = "ramdisk.bz2";
|
unsigned char *cpio = mmap(NULL, cpio_size, PROT_READ, MAP_SHARED, rfd, 0);
|
||||||
} else if (access("ramdisk.lz4", R_OK) == 0) {
|
|
||||||
name = "ramdisk.lz4";
|
switch (ramdisk_type) {
|
||||||
} else {
|
case GZIP:
|
||||||
error(1, "Ramdisk file doesn't exist!");
|
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 {
|
||||||
|
// 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);
|
hdr.ramdisk_size += restore(name);
|
||||||
page_align();
|
page_align();
|
||||||
|
|
||||||
// Dump second
|
// Restore second
|
||||||
if (access("second", R_OK) == 0) {
|
if (access(SECOND_FILE, R_OK) == 0) {
|
||||||
hdr.second_size += restore("second");
|
hdr.second_size += restore(SECOND_FILE);
|
||||||
page_align();
|
page_align();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump dtb
|
// Restore dtb
|
||||||
if (access("dtb", R_OK) == 0) {
|
if (access(DTB_FILE, R_OK) == 0) {
|
||||||
hdr.dt_size += restore("dtb");
|
hdr.dt_size += restore(DTB_FILE);
|
||||||
page_align();
|
page_align();
|
||||||
}
|
}
|
||||||
|
|
||||||
print_header();
|
|
||||||
|
|
||||||
// Write header back
|
// Write header back
|
||||||
lseek(ofd, 0, SEEK_SET);
|
lseek(ofd, 0, SEEK_SET);
|
||||||
write(ofd, &hdr, sizeof(hdr));
|
write(ofd, &hdr, sizeof(hdr));
|
||||||
@ -143,5 +156,7 @@ int repack(const char* image) {
|
|||||||
munmap(orig, isize);
|
munmap(orig, isize);
|
||||||
close(ifd);
|
close(ifd);
|
||||||
close(ofd);
|
close(ofd);
|
||||||
return ret;
|
if (opos > isize) {
|
||||||
|
error(2, "Boot partition too small!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include "magiskboot.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"
|
|
||||||
|
|
||||||
static void dump(unsigned char *buf, size_t size, const char *filename) {
|
static void dump(unsigned char *buf, size_t size, const char *filename) {
|
||||||
unlink(filename);
|
int ofd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||||
int ofd = open(filename, O_WRONLY | O_CREAT, 0644);
|
|
||||||
if (ofd < 0)
|
if (ofd < 0)
|
||||||
error(1, "Cannot open %s", filename);
|
error(1, "Cannot open %s", filename);
|
||||||
if (write(ofd, buf, size) != size)
|
if (write(ofd, buf, size) != size)
|
||||||
@ -22,8 +9,8 @@ static void dump(unsigned char *buf, size_t size, const char *filename) {
|
|||||||
close(ofd);
|
close(ofd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int unpack(const char* image) {
|
void unpack(const char* image) {
|
||||||
int fd = open(image, O_RDONLY), ret = 0;
|
int fd = open(image, O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
error(1, "Cannot open %s", image);
|
error(1, "Cannot open %s", image);
|
||||||
|
|
||||||
@ -31,81 +18,75 @@ int unpack(const char* image) {
|
|||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
unsigned char *orig = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
unsigned char *orig = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
|
||||||
// Parse images
|
// Parse image
|
||||||
for(base = orig; base < (orig + size); base += 256) {
|
parse_img(orig, size);
|
||||||
if (memcmp(base, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) {
|
|
||||||
|
if (boot_type == CHROMEOS) {
|
||||||
|
// The caller should know it's chromeos, as it needs additional signing
|
||||||
dump(base, 0, "chromeos");
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char name[PATH_MAX], *ext;
|
char name[PATH_MAX];
|
||||||
|
|
||||||
// Dump kernel
|
// Dump kernel
|
||||||
if (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) {
|
if (mtk_kernel) {
|
||||||
printf("MTK header found in kernel\n");
|
|
||||||
kernel += 512;
|
kernel += 512;
|
||||||
hdr.kernel_size -= 512;
|
hdr.kernel_size -= 512;
|
||||||
}
|
}
|
||||||
dump(kernel, hdr.kernel_size, "kernel");
|
dump(kernel, hdr.kernel_size, KERNEL_FILE);
|
||||||
|
|
||||||
// Dump ramdisk
|
// Dump ramdisk
|
||||||
if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) {
|
if (mtk_ramdisk) {
|
||||||
printf("MTK header found in ramdisk\n");
|
|
||||||
ramdisk += 512;
|
ramdisk += 512;
|
||||||
hdr.ramdisk_size -= 512;
|
hdr.ramdisk_size -= 512;
|
||||||
}
|
}
|
||||||
// Compression detection
|
|
||||||
if (memcmp(ramdisk, "\x1f\x8b\x08\x00", 4) == 0) {
|
switch (ramdisk_type) {
|
||||||
// gzip header
|
case GZIP:
|
||||||
printf("COMPRESSION [gzip]\n");
|
sprintf(name, "%s.%s", RAMDISK_FILE, "gz");
|
||||||
ext = "gz";
|
gzip(1, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
|
||||||
} else if (memcmp(ramdisk, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
|
break;
|
||||||
// lzop header
|
case LZOP:
|
||||||
printf("COMPRESSION [lzop]\n");
|
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo");
|
||||||
ext = "lzo";
|
break;
|
||||||
} else if (memcmp(ramdisk, "\xfd""7zXZ\x00", 6) == 0) {
|
case XZ:
|
||||||
// xz header
|
sprintf(name, "%s.%s", RAMDISK_FILE, "xz");
|
||||||
printf("COMPRESSION [xz]\n");
|
break;
|
||||||
ext = "xz";
|
case LZMA:
|
||||||
} else if (memcmp(ramdisk, "\x5d\x00\x00", 3) == 0
|
sprintf(name, "%s.%s", RAMDISK_FILE, "lzma");
|
||||||
&& (ramdisk[12] == (unsigned char) '\xff' || ramdisk[12] == (unsigned char) '\x00')) {
|
break;
|
||||||
// lzma header
|
case BZIP2:
|
||||||
printf("COMPRESSION [lzma]\n");
|
sprintf(name, "%s.%s", RAMDISK_FILE, "bz2");
|
||||||
ext = "lzma";
|
break;
|
||||||
} else if (memcmp(ramdisk, "BZh", 3) == 0) {
|
case LZ4:
|
||||||
// bzip2 header
|
sprintf(name, "%s.%s", RAMDISK_FILE, "lz4");
|
||||||
printf("COMPRESSION [bzip2]\n");
|
break;
|
||||||
ext = "bz2";
|
default:
|
||||||
} else if ( ( memcmp(ramdisk, "\x04\x22\x4d\x18", 4) == 0
|
// Never happens
|
||||||
|| memcmp(ramdisk, "\x03\x21\x4c\x18", 4) == 0)
|
break;
|
||||||
|| memcmp(ramdisk, "\x02\x21\x4c\x18", 4) == 0) {
|
|
||||||
// lz4 header
|
|
||||||
printf("COMPRESSION [lz4]\n");
|
|
||||||
ext = "lz4";
|
|
||||||
} else {
|
|
||||||
error(1, "Unknown ramdisk format!");
|
|
||||||
}
|
}
|
||||||
sprintf(name, "%s.%s", "ramdisk", ext);
|
// Dump the compressed ramdisk, just in case
|
||||||
dump(ramdisk, hdr.ramdisk_size, name);
|
dump(ramdisk, hdr.ramdisk_size, name);
|
||||||
|
|
||||||
if (hdr.second_size) {
|
if (hdr.second_size) {
|
||||||
// Dump second
|
// Dump second
|
||||||
dump(second, hdr.second_size, "second");
|
dump(second, hdr.second_size, SECOND_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr.dt_size) {
|
if (hdr.dt_size) {
|
||||||
|
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
|
||||||
dump(dtb, hdr.dt_size, "dtb");
|
dump(dtb, hdr.dt_size, DTB_FILE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
munmap(orig, size);
|
munmap(orig, size);
|
||||||
close(fd);
|
close(fd);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user