mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-28 10:37:53 +00:00
Add kernel decompression and appended dtb support
This commit is contained in:
parent
59c1125e72
commit
6b41653a32
@ -1,11 +1,6 @@
|
||||
#include "bootimg.h"
|
||||
#include "magiskboot.h"
|
||||
|
||||
static void *kernel, *ramdisk, *second, *dtb, *extra;
|
||||
static boot_img_hdr hdr;
|
||||
static int mtk_kernel = 0, mtk_ramdisk = 0;
|
||||
static file_t ramdisk_type;
|
||||
|
||||
static void dump(void *buf, size_t size, const char *filename) {
|
||||
int fd = open_new(filename);
|
||||
xwrite(fd, buf, size);
|
||||
@ -25,17 +20,17 @@ static void restore_buf(int fd, const void *buf, size_t size) {
|
||||
xwrite(fd, buf, size);
|
||||
}
|
||||
|
||||
static void print_info() {
|
||||
fprintf(stderr, "KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
|
||||
fprintf(stderr, "RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
|
||||
fprintf(stderr, "SECOND [%d] @ 0x%08x\n", hdr.second_size, hdr.second_addr);
|
||||
fprintf(stderr, "DTB [%d] @ 0x%08x\n", hdr.dt_size, hdr.tags_addr);
|
||||
fprintf(stderr, "PAGESIZE [%d]\n", hdr.page_size);
|
||||
if (hdr.os_version != 0) {
|
||||
static void print_hdr(const boot_img_hdr *hdr) {
|
||||
fprintf(stderr, "KERNEL [%d] @ 0x%08x\n", hdr->kernel_size, hdr->kernel_addr);
|
||||
fprintf(stderr, "RAMDISK [%d] @ 0x%08x\n", hdr->ramdisk_size, hdr->ramdisk_addr);
|
||||
fprintf(stderr, "SECOND [%d] @ 0x%08x\n", hdr->second_size, hdr->second_addr);
|
||||
fprintf(stderr, "DTB [%d] @ 0x%08x\n", hdr->dt_size, hdr->tags_addr);
|
||||
fprintf(stderr, "PAGESIZE [%d]\n", hdr->page_size);
|
||||
if (hdr->os_version != 0) {
|
||||
int a,b,c,y,m = 0;
|
||||
int os_version, os_patch_level;
|
||||
os_version = hdr.os_version >> 11;
|
||||
os_patch_level = hdr.os_version & 0x7ff;
|
||||
os_version = hdr->os_version >> 11;
|
||||
os_patch_level = hdr->os_version & 0x7ff;
|
||||
|
||||
a = (os_version >> 14) & 0x7f;
|
||||
b = (os_version >> 7) & 0x7f;
|
||||
@ -46,20 +41,16 @@ static void print_info() {
|
||||
m = os_patch_level & 0xf;
|
||||
fprintf(stderr, "PATCH_LEVEL [%d-%02d]\n", y, m);
|
||||
}
|
||||
fprintf(stderr, "NAME [%s]\n", hdr.name);
|
||||
fprintf(stderr, "CMDLINE [%s]\n", hdr.cmdline);
|
||||
|
||||
char cmp[16];
|
||||
|
||||
get_type_name(ramdisk_type, cmp);
|
||||
fprintf(stderr, "RAMDISK_COMP [%s]\n", cmp);
|
||||
fprintf(stderr, "NAME [%s]\n", hdr->name);
|
||||
fprintf(stderr, "CMDLINE [%s]\n", hdr->cmdline);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int parse_img(void *orig, size_t size) {
|
||||
int parse_img(void *orig, size_t size, boot_img *boot) {
|
||||
void *base, *end;
|
||||
size_t pos = 0;
|
||||
int ret = 0;
|
||||
memset(boot, 0, sizeof(*boot));
|
||||
for(base = orig, end = orig + size; base < end; base += 256, size -= 256) {
|
||||
switch (check_type(base)) {
|
||||
case CHROMEOS:
|
||||
@ -72,53 +63,75 @@ int parse_img(void *orig, size_t size) {
|
||||
exit(4);
|
||||
case AOSP:
|
||||
// Read the header
|
||||
memcpy(&hdr, base, sizeof(hdr));
|
||||
pos += hdr.page_size;
|
||||
memcpy(&boot->hdr, base, sizeof(boot->hdr));
|
||||
pos += boot->hdr.page_size;
|
||||
|
||||
// Kernel position
|
||||
kernel = base + pos;
|
||||
pos += hdr.kernel_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
print_hdr(&boot->hdr);
|
||||
|
||||
// Ramdisk position
|
||||
ramdisk = base + pos;
|
||||
pos += hdr.ramdisk_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
boot->kernel = base + pos;
|
||||
pos += boot->hdr.kernel_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
|
||||
if (hdr.second_size) {
|
||||
// Second position
|
||||
second = base + pos;
|
||||
pos += hdr.second_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
boot->ramdisk = base + pos;
|
||||
pos += boot->hdr.ramdisk_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
|
||||
if (boot->hdr.second_size) {
|
||||
boot->second = base + pos;
|
||||
pos += boot->hdr.second_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
}
|
||||
|
||||
if (hdr.dt_size) {
|
||||
// dtb position
|
||||
dtb = base + pos;
|
||||
pos += hdr.dt_size;
|
||||
mem_align(&pos, hdr.page_size);
|
||||
if (boot->hdr.dt_size) {
|
||||
boot->dtb = base + pos;
|
||||
pos += boot->hdr.dt_size;
|
||||
mem_align(&pos, boot->hdr.page_size);
|
||||
}
|
||||
|
||||
if (pos < size) {
|
||||
extra = base + pos;
|
||||
boot->extra = base + pos;
|
||||
}
|
||||
|
||||
// Check ramdisk compression type
|
||||
ramdisk_type = check_type(ramdisk);
|
||||
// Linear search in kernel for DTB
|
||||
for (int i = 0; i < boot->hdr.kernel_size; ++i) {
|
||||
if (memcmp(boot->kernel + i, DTB_MAGIC, 4) == 0) {
|
||||
boot->flags |= APPEND_DTB;
|
||||
boot->dtb = boot->kernel + i;
|
||||
boot->hdr.dt_size = boot->hdr.kernel_size - i;
|
||||
boot->hdr.kernel_size = i;
|
||||
fprintf(stderr, "APPEND_DTB [%d]\n", boot->hdr.dt_size);
|
||||
}
|
||||
}
|
||||
|
||||
boot->ramdisk_type = check_type(boot->ramdisk);
|
||||
boot->kernel_type = check_type(boot->kernel);
|
||||
|
||||
// Check MTK
|
||||
if (check_type(kernel) == MTK) {
|
||||
fprintf(stderr, "MTK header found in kernel\n");
|
||||
mtk_kernel = 1;
|
||||
if (boot->kernel_type == MTK) {
|
||||
fprintf(stderr, "MTK_KERNEL_HDR [512]\n");
|
||||
boot->flags |= MTK_KERNEL;
|
||||
memcpy(&boot->mtk_kernel_hdr, boot->kernel, sizeof(mtk_hdr));
|
||||
boot->kernel += 512;
|
||||
boot->hdr.kernel_size -= 512;
|
||||
boot->kernel_type = check_type(boot->kernel);
|
||||
}
|
||||
if (ramdisk_type == MTK) {
|
||||
fprintf(stderr, "MTK header found in ramdisk\n");
|
||||
mtk_ramdisk = 1;
|
||||
ramdisk_type = check_type(ramdisk + 512);
|
||||
if (boot->ramdisk_type == MTK) {
|
||||
fprintf(stderr, "MTK_RAMDISK_HDR [512]\n");
|
||||
boot->flags |= MTK_RAMDISK;
|
||||
memcpy(&boot->mtk_ramdisk_hdr, boot->ramdisk, sizeof(mtk_hdr));
|
||||
boot->ramdisk += 512;
|
||||
boot->hdr.ramdisk_size -= 512;
|
||||
boot->ramdisk_type = check_type(boot->ramdisk + 512);
|
||||
}
|
||||
|
||||
// Print info
|
||||
print_info();
|
||||
char fmt[16];
|
||||
|
||||
get_type_name(boot->kernel_type, fmt);
|
||||
fprintf(stderr, "KERNEL_FMT [%s]\n", fmt);
|
||||
get_type_name(boot->ramdisk_type, fmt);
|
||||
fprintf(stderr, "RAMDISK_FMT [%s]\n", fmt);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
return ret;
|
||||
default:
|
||||
continue;
|
||||
@ -131,39 +144,40 @@ void unpack(const char* image) {
|
||||
size_t size;
|
||||
void *orig;
|
||||
mmap_ro(image, &orig, &size);
|
||||
int fd;
|
||||
boot_img boot;
|
||||
|
||||
// Parse image
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n\n", image);
|
||||
int ret = parse_img(orig, size);
|
||||
int ret = parse_img(orig, size, &boot);
|
||||
|
||||
// Dump kernel
|
||||
if (mtk_kernel) {
|
||||
kernel += 512;
|
||||
hdr.kernel_size -= 512;
|
||||
if (boot.kernel_type == UNKNOWN) {
|
||||
dump(boot.kernel, boot.hdr.kernel_size, KERNEL_FILE);
|
||||
} else {
|
||||
fd = open_new(KERNEL_FILE);
|
||||
decomp(boot.kernel_type, fd, boot.kernel, boot.hdr.kernel_size);
|
||||
close(fd);
|
||||
}
|
||||
dump(kernel, hdr.kernel_size, KERNEL_FILE);
|
||||
|
||||
// Dump ramdisk
|
||||
if (mtk_ramdisk) {
|
||||
ramdisk += 512;
|
||||
hdr.ramdisk_size -= 512;
|
||||
}
|
||||
int fd = open_new(RAMDISK_FILE);
|
||||
if (decomp(ramdisk_type, fd, ramdisk, hdr.ramdisk_size) < 0) {
|
||||
// Dump the compressed ramdisk
|
||||
dump(ramdisk, hdr.ramdisk_size, RAMDISK_FILE ".raw");
|
||||
if (boot.ramdisk_type == UNKNOWN) {
|
||||
dump(boot.ramdisk, boot.hdr.ramdisk_size, RAMDISK_FILE ".raw");
|
||||
LOGE(1, "Unknown ramdisk format! Dumped to %s\n", RAMDISK_FILE ".raw");
|
||||
} else {
|
||||
fd = open_new(RAMDISK_FILE);
|
||||
decomp(boot.ramdisk_type, fd, boot.ramdisk, boot.hdr.ramdisk_size);
|
||||
close(fd);
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (hdr.second_size) {
|
||||
if (boot.hdr.second_size) {
|
||||
// Dump second
|
||||
dump(second, hdr.second_size, SECOND_FILE);
|
||||
dump(boot.second, boot.hdr.second_size, SECOND_FILE);
|
||||
}
|
||||
|
||||
if (hdr.dt_size) {
|
||||
if (boot.hdr.dt_size) {
|
||||
// Dump dtb
|
||||
dump(dtb, hdr.dt_size, DTB_FILE);
|
||||
dump(boot.dtb, boot.hdr.dt_size, DTB_FILE);
|
||||
}
|
||||
|
||||
munmap(orig, size);
|
||||
@ -173,9 +187,9 @@ void unpack(const char* image) {
|
||||
void repack(const char* orig_image, const char* out_image) {
|
||||
size_t size;
|
||||
void *orig;
|
||||
boot_img boot;
|
||||
|
||||
// There are possible two MTK headers
|
||||
mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr;
|
||||
size_t mtk_kernel_off, mtk_ramdisk_off;
|
||||
|
||||
// Load original image
|
||||
@ -183,51 +197,47 @@ void repack(const char* orig_image, const char* out_image) {
|
||||
|
||||
// Parse original image
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n\n", orig_image);
|
||||
parse_img(orig, size);
|
||||
parse_img(orig, size, &boot);
|
||||
|
||||
fprintf(stderr, "Repack to boot image: [%s]\n\n", out_image);
|
||||
|
||||
// Create new image
|
||||
int fd = open_new(out_image);
|
||||
|
||||
// Set all sizes to 0
|
||||
hdr.kernel_size = 0;
|
||||
hdr.ramdisk_size = 0;
|
||||
hdr.second_size = 0;
|
||||
hdr.dt_size = 0;
|
||||
|
||||
// Skip a page for header
|
||||
write_zero(fd, hdr.page_size);
|
||||
write_zero(fd, boot.hdr.page_size);
|
||||
|
||||
if (mtk_kernel) {
|
||||
if (boot.flags & MTK_KERNEL) {
|
||||
// Record position and skip MTK header
|
||||
mtk_kernel_off = lseek(fd, 0, SEEK_CUR);
|
||||
// Skip header
|
||||
write_zero(fd, 512);
|
||||
memcpy(&mtk_kernel_hdr, kernel, sizeof(mtk_kernel_hdr));
|
||||
}
|
||||
hdr.kernel_size = restore(KERNEL_FILE, fd);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
if (boot.kernel_type == UNKNOWN) {
|
||||
boot.hdr.kernel_size = restore(KERNEL_FILE, fd);
|
||||
} else {
|
||||
size_t raw_size;
|
||||
void *kernel_raw;
|
||||
mmap_ro(KERNEL_FILE, &kernel_raw, &raw_size);
|
||||
boot.hdr.kernel_size = comp(boot.kernel_type, fd, kernel_raw, raw_size);
|
||||
munmap(kernel_raw, raw_size);
|
||||
}
|
||||
if (boot.flags & APPEND_DTB) {
|
||||
boot.hdr.kernel_size += restore(DTB_FILE, fd);
|
||||
boot.hdr.dt_size = 0;
|
||||
}
|
||||
file_align(fd, boot.hdr.page_size, 1);
|
||||
|
||||
if (mtk_ramdisk) {
|
||||
if (boot.flags & MTK_RAMDISK) {
|
||||
// Record position and skip MTK header
|
||||
mtk_ramdisk_off = lseek(fd, 0, SEEK_CUR);
|
||||
// Skip header
|
||||
write_zero(fd, 512);
|
||||
memcpy(&mtk_ramdisk_hdr, ramdisk, sizeof(mtk_ramdisk_hdr));
|
||||
}
|
||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||
// If we found raw cpio, compress to original format
|
||||
size_t cpio_size;
|
||||
void *cpio;
|
||||
mmap_ro(RAMDISK_FILE, &cpio, &cpio_size);
|
||||
|
||||
long long ramdisk_size = comp(ramdisk_type, fd, cpio, cpio_size);
|
||||
|
||||
if (ramdisk_size < 0) {
|
||||
LOGE(1, "Unsupported ramdisk format!\n");
|
||||
} else {
|
||||
hdr.ramdisk_size = ramdisk_size;
|
||||
}
|
||||
|
||||
boot.hdr.ramdisk_size = comp(boot.ramdisk_type, fd, cpio, cpio_size);
|
||||
munmap(cpio, cpio_size);
|
||||
} else {
|
||||
// Find compressed ramdisk
|
||||
@ -242,49 +252,50 @@ void repack(const char* orig_image, const char* out_image) {
|
||||
}
|
||||
if (!found)
|
||||
LOGE(1, "No ramdisk exists!\n");
|
||||
hdr.ramdisk_size = restore(name, fd);
|
||||
boot.hdr.ramdisk_size = restore(name, fd);
|
||||
}
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
file_align(fd, boot.hdr.page_size, 1);
|
||||
|
||||
// Restore second
|
||||
if (access(SECOND_FILE, R_OK) == 0) {
|
||||
hdr.second_size = restore(SECOND_FILE, fd);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
if (boot.hdr.second_size && access(SECOND_FILE, R_OK) == 0) {
|
||||
boot.hdr.second_size = restore(SECOND_FILE, fd);
|
||||
file_align(fd, boot.hdr.page_size, 1);
|
||||
}
|
||||
|
||||
// Restore dtb
|
||||
if (access(DTB_FILE, R_OK) == 0) {
|
||||
hdr.dt_size = restore(DTB_FILE, fd);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
if (boot.hdr.dt_size && access(DTB_FILE, R_OK) == 0) {
|
||||
printf("Here\n");
|
||||
boot.hdr.dt_size = restore(DTB_FILE, fd);
|
||||
file_align(fd, boot.hdr.page_size, 1);
|
||||
}
|
||||
|
||||
// Check extra info, currently only for LG Bump and Samsung SEANDROIDENFORCE
|
||||
if (extra) {
|
||||
if (memcmp(extra, "SEANDROIDENFORCE", 16) == 0 ||
|
||||
memcmp(extra, LG_BUMP_MAGIC, 16) == 0 ) {
|
||||
restore_buf(fd, extra, 16);
|
||||
if (boot.extra) {
|
||||
if (memcmp(boot.extra, "SEANDROIDENFORCE", 16) == 0 ||
|
||||
memcmp(boot.extra, LG_BUMP_MAGIC, 16) == 0 ) {
|
||||
restore_buf(fd, boot.extra, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// Write MTK headers back
|
||||
if (mtk_kernel) {
|
||||
if (boot.flags & MTK_KERNEL) {
|
||||
lseek(fd, mtk_kernel_off, SEEK_SET);
|
||||
mtk_kernel_hdr.size = hdr.kernel_size;
|
||||
hdr.kernel_size += 512;
|
||||
restore_buf(fd, &mtk_kernel_hdr, sizeof(mtk_kernel_hdr));
|
||||
boot.mtk_kernel_hdr.size = boot.hdr.kernel_size;
|
||||
boot.hdr.kernel_size += 512;
|
||||
restore_buf(fd, &boot.mtk_kernel_hdr, sizeof(mtk_hdr));
|
||||
}
|
||||
if (mtk_ramdisk) {
|
||||
if (boot.flags & MTK_RAMDISK) {
|
||||
lseek(fd, mtk_ramdisk_off, SEEK_SET);
|
||||
mtk_ramdisk_hdr.size = hdr.ramdisk_size;
|
||||
hdr.ramdisk_size += 512;
|
||||
restore_buf(fd, &mtk_ramdisk_hdr, sizeof(mtk_ramdisk_hdr));
|
||||
boot.mtk_ramdisk_hdr.size = boot.hdr.ramdisk_size;
|
||||
boot.hdr.ramdisk_size += 512;
|
||||
restore_buf(fd, &boot.mtk_ramdisk_hdr, sizeof(mtk_hdr));
|
||||
}
|
||||
// Main header
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
restore_buf(fd, &hdr, sizeof(hdr));
|
||||
restore_buf(fd, &boot.hdr, sizeof(boot.hdr));
|
||||
|
||||
// Print new image info
|
||||
print_info();
|
||||
print_hdr(&boot.hdr);
|
||||
|
||||
munmap(orig, size);
|
||||
close(fd);
|
||||
|
@ -2,20 +2,21 @@
|
||||
**
|
||||
** Copyright 2007, 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
|
||||
** 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
|
||||
** 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
|
||||
** 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "magic.h"
|
||||
|
||||
#ifndef _BOOT_IMAGE_H_
|
||||
#define _BOOT_IMAGE_H_
|
||||
@ -64,12 +65,12 @@ struct boot_img_hdr
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
** +-----------------+
|
||||
** +-----------------+
|
||||
** | boot header | 1 page
|
||||
** +-----------------+
|
||||
** | kernel | n pages
|
||||
** | kernel | n pages
|
||||
** +-----------------+
|
||||
** | ramdisk | m pages
|
||||
** | ramdisk | m pages
|
||||
** +-----------------+
|
||||
** | second stage | o pages
|
||||
** +-----------------+
|
||||
@ -99,4 +100,21 @@ typedef struct mtk_hdr {
|
||||
uint8_t name[32]; /* The type of the header */
|
||||
} mtk_hdr;
|
||||
|
||||
// Flags
|
||||
#define MTK_KERNEL 0x1
|
||||
#define MTK_RAMDISK 0x2
|
||||
#define APPEND_DTB 0x4
|
||||
|
||||
typedef struct boot_img {
|
||||
boot_img_hdr hdr;
|
||||
void *kernel;
|
||||
void *ramdisk;
|
||||
void *second;
|
||||
void *dtb;
|
||||
void *extra;
|
||||
int flags;
|
||||
file_t kernel_type, ramdisk_type;
|
||||
mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr;
|
||||
} boot_img;
|
||||
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@ extern file_t SUP_TYPE_LIST[];
|
||||
void unpack(const char *image);
|
||||
void repack(const char* orig_image, const char* out_image);
|
||||
void hexpatch(const char *image, const char *from, const char *to);
|
||||
int parse_img(void *orig, size_t size);
|
||||
int parse_img(void *orig, size_t size, boot_img *boot);
|
||||
int cpio_commands(const char *command, int argc, char *argv[]);
|
||||
void comp_file(const char *method, const char *from, const char *to);
|
||||
void decomp_file(char *from, const char *to);
|
||||
|
Loading…
x
Reference in New Issue
Block a user