/* * This file is part of libsamsung-ipc. * * Copyright (C) 2020 Denis 'GNUtoo' Carikli * * libsamsung-ipc is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * libsamsung-ipc is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with libsamsung-ipc. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "../samsung-ipc/devices/i9300/i9300.h" /* Taken from the herolte patch which is GPLv2 or later and has the following: * Copyright (C) 2020 Tony Garnock-Jones */ struct toc_part_info { char name[12]; uint32_t offset; uint32_t loadaddr; uint32_t size; uint32_t crc; uint32_t entryid; } __attribute__((__packed__)); /* TODO: fill in loadaddr, crc, entryid */ static struct toc_part_info gt_i9300[] = { {"PSIRAM", I9300_PSI_OFFSET, 0, I9300_PSI_SIZE, 0, 0}, {"EBL", I9300_EBL_OFFSET, 0, I9300_EBL_SIZE, 0, 0}, {"MAIN", I9300_FIRMWARE_OFFSET, 0, I9300_FIRMWARE_SIZE, 0, 0}, {"SECPACK", I9300_SEC_START_OFFSET, 0, I9300_SEC_START_SIZE, 0, 0}, {"NV", I9300_NV_DATA_OFFSET, 0, I9300_NV_DATA_SIZE, 0, 0}, }; static int part_info_cmp(struct toc_part_info* toc_part_info1, struct toc_part_info* toc_part_info2) { if ((toc_part_info2->offset - toc_part_info1->offset) != 0) { printf("toc_part_info1->offset: 0x%x " "toc_part_info2->offset: 0x%x\n", le32toh(toc_part_info1->offset), le32toh(toc_part_info2->offset)); return toc_part_info2->offset - toc_part_info1->offset; } if ((toc_part_info2->size - toc_part_info1->size) != 0){ printf("toc_part_info1->size: 0x%x " "toc_part_info2->size: 0x%x\n", le32toh(toc_part_info1->size), le32toh(toc_part_info2->size)); return toc_part_info2->size - toc_part_info1->size; } return 0; } static int usage(char* progname) { printf("%s [path/to/RADIO.img]\n", progname); exit(1); } int main(int argc, char* argv[]) { struct toc_part_info* toc_part_info; void* buffer; int fd; int pnum; if (argc != 2) usage(argv[0]); fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("Failed to open"); return -1; } buffer = mmap(NULL, 0x1000, PROT_READ, MAP_SHARED, fd, 0); if (buffer == MAP_FAILED) { perror("mmap failed"); return -1; } size_t name_max_len = 0; for(pnum = 0;pnum < 10;pnum++){ char* toc_part_info_buffer = buffer + pnum * sizeof(struct toc_part_info); char name[13]; if (toc_part_info_buffer[0] == '\0') { break; } toc_part_info = (struct toc_part_info*) toc_part_info_buffer; memcpy(&name, toc_part_info->name, sizeof(toc_part_info->name)); name[12] = '\0'; if (strlen(name) > name_max_len) name_max_len = strlen(name); } for(pnum = 0;pnum < 10;pnum++){ char* toc_part_info_buffer = buffer + pnum * sizeof(struct toc_part_info); char name[13]; size_t i = 0; if (toc_part_info_buffer[0] == '\0') { break; } toc_part_info = (struct toc_part_info*) toc_part_info_buffer; memcpy(&name, toc_part_info->name, sizeof(toc_part_info->name)); name[12] = '\0'; /* Alignement */ printf("%s: ", name); for (i=0 ; i < (name_max_len - strlen(name)) ; i++) printf(" "); printf("offset: 0x%x,",le32toh(toc_part_info->offset)); printf("loadaddr: 0x%x, size: 0x%x, crc: 0x%x, entryid: 0x%x\n", le32toh(toc_part_info->loadaddr), le32toh(toc_part_info->size), le32toh(toc_part_info->crc), le32toh(toc_part_info->entryid)); part_info_cmp(toc_part_info, &(gt_i9300[pnum])); } return 0; }