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;
}
示例#3
0
/*!
 * \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;
}
示例#4
0
/*!
 * \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;
}