Magisk/jni/magiskboot/repack.c

119 lines
2.6 KiB
C
Raw Normal View History

2017-02-27 21:37:47 +00:00
#include "magiskboot.h"
2017-03-04 13:16:59 +00:00
static size_t restore(const char *filename, int fd) {
int ifd = open(filename, O_RDONLY);
if (ifd < 0)
error(1, "Cannot open %s\n", filename);
2017-03-04 13:16:59 +00:00
size_t size = lseek(ifd, 0, SEEK_END);
lseek(ifd, 0, SEEK_SET);
if (sendfile(fd, ifd, NULL, size) != size) {
error(1, "Cannot write %s\n", filename);
}
2017-03-04 13:16:59 +00:00
close(ifd);
return size;
}
2017-03-04 13:16:59 +00:00
static void restore_buf(const void *buf, size_t size, int fd) {
if (write(fd, buf, size) != size) {
error(1, "Cannot dump from input file\n");
}
}
2017-03-07 16:54:23 +00:00
void repack(const char* orig_image, const char* out_image) {
2017-03-04 13:16:59 +00:00
size_t size;
unsigned char *orig;
char name[PATH_MAX];
2017-02-27 21:37:47 +00:00
// Load original image
2017-03-07 16:54:23 +00:00
mmap_ro(orig_image, &orig, &size);
2017-02-24 19:29:12 +00:00
2017-02-27 21:37:47 +00:00
// Parse original image
2017-03-07 16:54:23 +00:00
printf("\nParsing boot image: [%s]\n\n", orig_image);
2017-03-04 13:16:59 +00:00
parse_img(orig, size);
2017-03-04 13:16:59 +00:00
// Create new image
2017-03-07 16:54:23 +00:00
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;
2017-02-24 19:29:12 +00:00
// Skip a page for header
2017-03-04 13:16:59 +00:00
ftruncate(fd, hdr.page_size);
lseek(fd, 0, SEEK_END);
2017-02-24 19:29:12 +00:00
// Restore kernel
2017-02-27 21:37:47 +00:00
if (mtk_kernel) {
2017-03-04 13:16:59 +00:00
restore_buf(kernel, 512, fd);
hdr.kernel_size += 512;
}
2017-03-04 13:16:59 +00:00
hdr.kernel_size += restore(KERNEL_FILE, fd);
2017-03-07 16:54:23 +00:00
file_align(fd, hdr.page_size, 1);
2017-02-27 21:37:47 +00:00
// Restore ramdisk
if (mtk_ramdisk) {
2017-03-04 13:16:59 +00:00
restore_buf(ramdisk, 512, fd);
hdr.ramdisk_size += 512;
}
2017-02-27 21:37:47 +00:00
if (access(RAMDISK_FILE, R_OK) == 0) {
2017-03-02 13:59:37 +00:00
// If we found raw cpio, compress to original format
// Before we start, clean up previous compressed files
for (int i = 0; i < SUP_NUM; ++i) {
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
unlink(name);
}
2017-03-04 13:16:59 +00:00
size_t cpio_size;
unsigned char *cpio;
mmap_ro(RAMDISK_FILE, &cpio, &cpio_size);
2017-02-27 21:37:47 +00:00
2017-03-02 13:59:37 +00:00
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
error(1, "Unsupported ramdisk format!");
2017-02-27 21:37:47 +00:00
munmap(cpio, cpio_size);
2017-03-02 13:59:37 +00:00
}
int found = 0;
for (int i = 0; i < SUP_NUM; ++i) {
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
2017-03-02 13:59:37 +00:00
if (access(name, R_OK) == 0) {
ramdisk_type = SUP_TYPE_LIST[i];
2017-03-02 13:59:37 +00:00
found = 1;
break;
2017-02-27 21:37:47 +00:00
}
}
2017-03-02 13:59:37 +00:00
if (!found)
error(1, "No ramdisk exists!");
2017-03-04 13:16:59 +00:00
hdr.ramdisk_size += restore(name, fd);
2017-03-07 16:54:23 +00:00
file_align(fd, hdr.page_size, 1);
2017-02-27 21:37:47 +00:00
// Restore second
if (access(SECOND_FILE, R_OK) == 0) {
2017-03-04 13:16:59 +00:00
hdr.second_size += restore(SECOND_FILE, fd);
2017-03-07 16:54:23 +00:00
file_align(fd, hdr.page_size, 1);
}
2017-02-27 21:37:47 +00:00
// Restore dtb
if (access(DTB_FILE, R_OK) == 0) {
2017-03-04 13:16:59 +00:00
hdr.dt_size += restore(DTB_FILE, fd);
2017-03-07 16:54:23 +00:00
file_align(fd, hdr.page_size, 1);
}
// Write header back
2017-03-07 16:54:23 +00:00
printf("\nRepack to boot image: [%s]\n\n", out_image);
print_info();
2017-03-04 13:16:59 +00:00
lseek(fd, 0, SEEK_SET);
write(fd, &hdr, sizeof(hdr));
2017-03-04 13:16:59 +00:00
munmap(orig, size);
if (lseek(fd, 0, SEEK_CUR) > size) {
2017-02-27 21:37:47 +00:00
error(2, "Boot partition too small!");
}
2017-03-04 13:16:59 +00:00
close(fd);
}