Support Tegra blobs

This commit is contained in:
topjohnwu 2018-01-30 05:20:18 +08:00
parent 7cfc24d68f
commit f48e6c93b8
4 changed files with 49 additions and 13 deletions

View File

@ -81,6 +81,7 @@ static void clean_boot(boot_img *boot) {
free(boot->hdr); free(boot->hdr);
free(boot->k_hdr); free(boot->k_hdr);
free(boot->r_hdr); free(boot->r_hdr);
free(boot->b_hdr);
memset(boot, 0, sizeof(*boot)); memset(boot, 0, sizeof(*boot));
} }
@ -91,7 +92,7 @@ int parse_img(const char *image, boot_img *boot) {
// Parse image // Parse image
fprintf(stderr, "Parsing boot image: [%s]\n", image); fprintf(stderr, "Parsing boot image: [%s]\n", image);
for (void *head = boot->map_addr; head < boot->map_addr + boot->map_size; head += 256) { for (void *head = boot->map_addr; head < boot->map_addr + boot->map_size; ++head) {
size_t pos = 0; size_t pos = 0;
switch (check_fmt(head)) { switch (check_fmt(head)) {
@ -108,6 +109,12 @@ int parse_img(const char *image, boot_img *boot) {
exit(ELF32_RET); exit(ELF32_RET);
case ELF64: case ELF64:
exit(ELF64_RET); exit(ELF64_RET);
case BLOB:
boot->flags |= BLOB_FLAG;
fprintf(stderr, "TEGRA_BLOB\n");
boot->b_hdr = malloc(sizeof(blob_hdr));
memcpy(boot->b_hdr, head, sizeof(blob_hdr));
continue;
case AOSP: case AOSP:
// Read the header // Read the header
if (((boot_img_hdr*) head)->page_size >= 0x02000000) { if (((boot_img_hdr*) head)->page_size >= 0x02000000) {
@ -261,7 +268,7 @@ int unpack(const char *image) {
#define file_align() write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR) - header_off, header(&boot, page_size))) #define file_align() write_zero(fd, align_off(lseek(fd, 0, SEEK_CUR) - header_off, header(&boot, page_size)))
void repack(const char* orig_image, const char* out_image) { void repack(const char* orig_image, const char* out_image) {
boot_img boot; boot_img boot;
off_t header_off, kernel_off, ramdisk_off, second_off, extra_off; off_t header_off, kernel_off, ramdisk_off, second_off, extra_off;
// Parse original image // Parse original image
@ -275,6 +282,9 @@ void repack(const char* orig_image, const char* out_image) {
if (boot.flags & DHTB_FLAG) { if (boot.flags & DHTB_FLAG) {
// Skip DHTB header // Skip DHTB header
write_zero(fd, 512); write_zero(fd, 512);
} else if (boot.flags & BLOB_FLAG) {
// Skip blob header
write_zero(fd, sizeof(blob_hdr));
} }
// Skip a page for header // Skip a page for header
@ -400,12 +410,16 @@ void repack(const char* orig_image, const char* out_image) {
memcpy(boot.map_addr + header_off, boot.hdr, memcpy(boot.map_addr + header_off, boot.hdr,
(boot.flags & PXA_FLAG) ? sizeof(pxa_boot_img_hdr) : sizeof(boot_img_hdr)); (boot.flags & PXA_FLAG) ? sizeof(pxa_boot_img_hdr) : sizeof(boot_img_hdr));
// DHTB header
if (boot.flags & DHTB_FLAG) { if (boot.flags & DHTB_FLAG) {
// DHTB header
dhtb_hdr *hdr = boot.map_addr; dhtb_hdr *hdr = boot.map_addr;
memcpy(hdr, DHTB_MAGIC, 8); memcpy(hdr, DHTB_MAGIC, 8);
hdr->size = boot.map_size - 512; hdr->size = boot.map_size - 512;
SHA256_hash(boot.map_addr + 512, hdr->size, hdr->checksum); SHA256_hash(boot.map_addr + 512, hdr->size, hdr->checksum);
} else if (boot.flags & BLOB_FLAG) {
// Blob headers
boot.b_hdr->size = boot.map_size - sizeof(blob_hdr);
memcpy(boot.map_addr, boot.b_hdr, sizeof(blob_hdr));
} }
clean_boot(&boot); clean_boot(&boot);

View File

@ -104,15 +104,32 @@ typedef struct dhtb_hdr {
uint32_t size; /* Payload size, whole image + SEANDROIDENFORCE + 0xFFFFFFFF */ uint32_t size; /* Payload size, whole image + SEANDROIDENFORCE + 0xFFFFFFFF */
} __attribute__((packed)) dhtb_hdr; } __attribute__((packed)) dhtb_hdr;
typedef struct blob_hdr {
char secure_magic[20]; /* "-SIGNED-BY-SIGNBLOB-" */
uint32_t datalen; /* 0x00000000 */
uint32_t signature; /* 0x00000000 */
char magic[16]; /* "MSM-RADIO-UPDATE" */
uint32_t hdr_version; /* 0x00010000 */
uint32_t hdr_size; /* Size of header */
uint32_t part_offset; /* Same as size */
uint32_t num_parts; /* Number of partitions */
uint32_t unknown[7]; /* All 0x00000000 */
char name[4]; /* Name of partition */
uint32_t offset; /* offset in blob where this partition starts */
uint32_t size; /* Size of data */
uint32_t version; /* 0x00000001 */
} __attribute__((packed)) blob_hdr;
// Flags // Flags
#define MTK_KERNEL 0x01 #define MTK_KERNEL 0x0001
#define MTK_RAMDISK 0x02 #define MTK_RAMDISK 0x0002
#define CHROMEOS_FLAG 0x04 #define CHROMEOS_FLAG 0x0004
#define PXA_FLAG 0x08 #define PXA_FLAG 0x0008
#define DHTB_FLAG 0x10 #define DHTB_FLAG 0x0010
#define SEANDROID_FLAG 0x20 #define SEANDROID_FLAG 0x0020
#define LG_BUMP_FLAG 0x40 #define LG_BUMP_FLAG 0x0040
#define SHA256_FLAG 0x80 #define SHA256_FLAG 0x0080
#define BLOB_FLAG 0x0100
typedef struct boot_img { typedef struct boot_img {
// Memory map of the whole image // Memory map of the whole image
@ -123,9 +140,10 @@ typedef struct boot_img {
void *hdr; /* Either boot_img_hdr or pxa_boot_img_hdr */ void *hdr; /* Either boot_img_hdr or pxa_boot_img_hdr */
mtk_hdr *k_hdr; /* MTK kernel header */ mtk_hdr *k_hdr; /* MTK kernel header */
mtk_hdr *r_hdr; /* MTK ramdisk header */ mtk_hdr *r_hdr; /* MTK ramdisk header */
blob_hdr *b_hdr; /* Tegra blob header */
// Flags to indicate the state of current boot image // Flags to indicate the state of current boot image
uint8_t flags; uint16_t flags;
// The format of kernel and ramdisk // The format of kernel and ramdisk
format_t k_fmt; format_t k_fmt;

View File

@ -33,6 +33,8 @@ format_t check_fmt(const void *buf) {
return DTB; return DTB;
} else if (memcmp(buf, DHTB_MAGIC, 8) == 0) { } else if (memcmp(buf, DHTB_MAGIC, 8) == 0) {
return DHTB; return DHTB;
} else if (memcmp(buf, TEGRABLOB_MAGIC, 20) == 0) {
return BLOB;
} else { } else {
return UNKNOWN; return UNKNOWN;
} }

View File

@ -16,7 +16,8 @@ typedef enum {
LZ4_LEGACY, LZ4_LEGACY,
MTK, MTK,
DTB, DTB,
DHTB DHTB,
BLOB
} format_t; } format_t;
#define COMPRESSED(fmt) (fmt >= GZIP && fmt <= LZ4_LEGACY) #define COMPRESSED(fmt) (fmt >= GZIP && fmt <= LZ4_LEGACY)
@ -36,6 +37,7 @@ typedef enum {
#define LG_BUMP_MAGIC "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79" #define LG_BUMP_MAGIC "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79"
#define DHTB_MAGIC "\x44\x48\x54\x42\x01\x00\x00\x00" #define DHTB_MAGIC "\x44\x48\x54\x42\x01\x00\x00\x00"
#define SEANDROID_MAGIC "SEANDROIDENFORCE" #define SEANDROID_MAGIC "SEANDROIDENFORCE"
#define TEGRABLOB_MAGIC "-SIGNED-BY-SIGNBLOB-"
#define SUP_LIST ((char *[]) { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL }) #define SUP_LIST ((char *[]) { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL })
#define SUP_EXT_LIST ((char *[]) { "gz", "xz", "lzma", "bz2", "lz4", "lz4", NULL }) #define SUP_EXT_LIST ((char *[]) { "gz", "xz", "lzma", "bz2", "lz4", "lz4", NULL })