MB_BEGIN_C_DECLS int sony_elf_writer_get_header(MbBiWriter *biw, void *userdata, MbBiHeader *header) { (void) biw; (void) userdata; mb_bi_header_set_supported_fields(header, SONY_ELF_SUPPORTED_FIELDS); return MB_BI_OK; }
int android_set_header(AndroidHeader *hdr, MbBiHeader *header) { int ret; char board_name[sizeof(hdr->name) + 1]; char cmdline[sizeof(hdr->cmdline) + 1]; strncpy(board_name, reinterpret_cast<char *>(hdr->name), sizeof(hdr->name)); strncpy(cmdline, reinterpret_cast<char *>(hdr->cmdline), sizeof(hdr->cmdline)); board_name[sizeof(hdr->name)] = '\0'; cmdline[sizeof(hdr->cmdline)] = '\0'; mb_bi_header_set_supported_fields(header, ANDROID_SUPPORTED_FIELDS); ret = mb_bi_header_set_board_name(header, board_name); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_cmdline(header, cmdline); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_page_size(header, hdr->page_size); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_address(header, hdr->kernel_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_ramdisk_address(header, hdr->ramdisk_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_secondboot_address(header, hdr->second_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_tags_address(header, hdr->tags_addr); if (ret != MB_BI_OK) return ret; // TODO: unused // TODO: id return MB_BI_OK; }
/*! * \brief Read header for new-style Loki image * * \param[in] bir MbBiReader to set error message * \param[in] file MbFile handle * \param[in] hdr Android header for image * \param[in] loki_hdr Loki header for image * \param[out] header MbBiHeader instance to store header values * \param[out] kernel_offset_out Pointer to store kernel offset * \param[out] kernel_size_out Pointer to store kernel size * \param[out] ramdisk_offset_out Pointer to store ramdisk offset * \param[out] ramdisk_size_out Pointer to store ramdisk size * \param[out] dt_offset_out Pointer to store device tree offset * * \return * * #MB_BI_OK if the header is successfully read * * #MB_BI_WARN if parts of the header are missing or invalid * * #MB_BI_FAILED if any file operation fails non-fatally * * #MB_BI_FATAL if any file operation fails fatally */ int loki_read_new_header(MbBiReader *bir, MbFile *file, AndroidHeader *hdr, LokiHeader *loki_hdr, MbBiHeader *header, uint64_t *kernel_offset_out, uint32_t *kernel_size_out, uint64_t *ramdisk_offset_out, uint32_t *ramdisk_size_out, uint64_t *dt_offset_out) { uint32_t fake_size; uint32_t ramdisk_addr; int ret; if (hdr->page_size == 0) { mb_bi_reader_set_error(bir, MB_BI_ERROR_FILE_FORMAT, "Page size cannot be 0"); return MB_BI_WARN; } if (LOKI_IS_LG_RAMDISK_ADDR(hdr->ramdisk_addr)) { fake_size = hdr->page_size; } else { fake_size = 0x200; } // Find original ramdisk address ret = loki_find_ramdisk_address(bir, file, hdr, loki_hdr, &ramdisk_addr); if (ret != MB_BI_OK) { return ret; } // Restore original values in boot image header *kernel_size_out = loki_hdr->orig_kernel_size; *ramdisk_size_out = loki_hdr->orig_ramdisk_size; char board_name[sizeof(hdr->name) + 1]; char cmdline[sizeof(hdr->cmdline) + 1]; strncpy(board_name, reinterpret_cast<char *>(hdr->name), sizeof(hdr->name)); strncpy(cmdline, reinterpret_cast<char *>(hdr->cmdline), sizeof(hdr->cmdline)); board_name[sizeof(hdr->name)] = '\0'; cmdline[sizeof(hdr->cmdline)] = '\0'; mb_bi_header_set_supported_fields(header, LOKI_NEW_SUPPORTED_FIELDS); ret = mb_bi_header_set_board_name(header, board_name); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_cmdline(header, cmdline); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_page_size(header, hdr->page_size); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_address(header, hdr->kernel_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_ramdisk_address(header, ramdisk_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_secondboot_address(header, hdr->second_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_tags_address(header, hdr->tags_addr); if (ret != MB_BI_OK) return ret; uint64_t pos = 0; // pos cannot overflow due to the nature of the operands (adding UINT32_MAX // a few times can't overflow a uint64_t). File length overflow is checked // during read. // Header pos += hdr->page_size; // Kernel *kernel_offset_out = pos; pos += loki_hdr->orig_kernel_size; pos += align_page_size<uint64_t>(pos, hdr->page_size); // Ramdisk *ramdisk_offset_out = pos; pos += loki_hdr->orig_ramdisk_size; pos += align_page_size<uint64_t>(pos, hdr->page_size); // Device tree if (hdr->dt_size != 0) { pos += fake_size; } *dt_offset_out = pos; pos += hdr->dt_size; pos += align_page_size<uint64_t>(pos, hdr->page_size); return MB_BI_OK; }
/*! * \brief Read header for old-style Loki image * * \param[in] bir MbBiReader to set error message * \param[in] file MbFile handle * \param[in] hdr Android header for image * \param[in] loki_hdr Loki header for image * \param[out] header MbBiHeader instance to store header values * \param[out] kernel_offset_out Pointer to store kernel offset * \param[out] kernel_size_out Pointer to store kernel size * \param[out] ramdisk_offset_out Pointer to store ramdisk offset * \param[out] ramdisk_size_out Pointer to store ramdisk size * * \return * * #MB_BI_OK if the header is successfully read * * #MB_BI_WARN if parts of the header are missing or invalid * * #MB_BI_FAILED if any file operation fails non-fatally * * #MB_BI_FATAL if any file operation fails fatally */ int loki_read_old_header(MbBiReader *bir, MbFile *file, AndroidHeader *hdr, LokiHeader *loki_hdr, MbBiHeader *header, uint64_t *kernel_offset_out, uint32_t *kernel_size_out, uint64_t *ramdisk_offset_out, uint32_t *ramdisk_size_out) { uint32_t tags_addr; uint32_t kernel_size; uint32_t ramdisk_size; uint32_t ramdisk_addr; uint64_t gzip_offset; int ret; if (hdr->page_size == 0) { mb_bi_reader_set_error(bir, MB_BI_ERROR_FILE_FORMAT, "Page size cannot be 0"); return MB_BI_WARN; } // The kernel tags address is invalid in the old loki images, so use the // default for jflte tags_addr = hdr->kernel_addr - ANDROID_DEFAULT_KERNEL_OFFSET + ANDROID_DEFAULT_TAGS_OFFSET; // Try to guess kernel size ret = find_linux_kernel_size(bir, file, hdr->page_size, &kernel_size); if (ret != MB_BI_OK) { return ret; } // Look for gzip offset for the ramdisk ret = loki_old_find_gzip_offset( bir, file, hdr->page_size + kernel_size + align_page_size<uint64_t>(kernel_size, hdr->page_size), &gzip_offset); if (ret != MB_BI_OK) { return ret; } // Try to guess ramdisk size ret = loki_old_find_ramdisk_size(bir, file, hdr, gzip_offset, &ramdisk_size); if (ret != MB_BI_OK) { return ret; } // Guess original ramdisk address ret = loki_find_ramdisk_address(bir, file, hdr, loki_hdr, &ramdisk_addr); if (ret != MB_BI_OK) { return ret; } *kernel_size_out = kernel_size; *ramdisk_size_out = ramdisk_size; char board_name[sizeof(hdr->name) + 1]; char cmdline[sizeof(hdr->cmdline) + 1]; strncpy(board_name, reinterpret_cast<char *>(hdr->name), sizeof(hdr->name)); strncpy(cmdline, reinterpret_cast<char *>(hdr->cmdline), sizeof(hdr->cmdline)); board_name[sizeof(hdr->name)] = '\0'; cmdline[sizeof(hdr->cmdline)] = '\0'; mb_bi_header_set_supported_fields(header, LOKI_OLD_SUPPORTED_FIELDS); ret = mb_bi_header_set_board_name(header, board_name); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_cmdline(header, cmdline); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_page_size(header, hdr->page_size); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_address(header, hdr->kernel_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_ramdisk_address(header, ramdisk_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_secondboot_address(header, hdr->second_addr); if (ret != MB_BI_OK) return ret; ret = mb_bi_header_set_kernel_tags_address(header, tags_addr); if (ret != MB_BI_OK) return ret; uint64_t pos = 0; // pos cannot overflow due to the nature of the operands (adding UINT32_MAX // a few times can't overflow a uint64_t). File length overflow is checked // during read. // Header pos += hdr->page_size; // Kernel *kernel_offset_out = pos; pos += kernel_size; pos += align_page_size<uint64_t>(pos, hdr->page_size); // Ramdisk *ramdisk_offset_out = pos = gzip_offset; pos += ramdisk_size; pos += align_page_size<uint64_t>(pos, hdr->page_size); return MB_BI_OK; }