/* verify and prepare for booting of a legacy kernel */ int legacy_boot(void *kernel, const char *cmd_line_buf) { const image_header_t *hdr = kernel; bootm_header_t bootm_header; memset(&bootm_header, 0, sizeof(bootm_header)); if (image_get_magic(hdr) != IH_MAGIC) return 1; if (!image_check_hcrc(hdr)) { printf("Bad Header CRC\n"); return 1; } if (!image_check_dcrc(hdr)) { printf("Bad Data CRC\n"); return 1; } bootm_header.os.type = image_get_type(hdr); bootm_header.os.comp = image_get_comp(hdr); bootm_header.os.end = (uint32_t)hdr + image_get_size(hdr) + sizeof(*hdr); bootm_header.os.load = image_get_load(hdr); bootm_header.os.start = (uint32_t) hdr; bootm_header.os.image_start = (uint32_t)(hdr + 1); bootm_header.os.image_len = image_get_size(hdr); bootm_header.ep = image_get_ep(hdr); bootm_header.cmdline = cmd_line_buf; return start_legacy_kernel(&bootm_header); }
static int image_extract_subimage(void *ptr, struct image_tool_params *params) { const image_header_t *hdr = (const image_header_t *)ptr; ulong file_data; ulong file_len; if (image_check_type(hdr, IH_TYPE_MULTI)) { ulong idx = params->pflag; ulong count; /* get the number of data files present in the image */ count = image_multi_count(hdr); /* retrieve the "data file" at the idx position */ image_multi_getimg(hdr, idx, &file_data, &file_len); if ((file_len == 0) || (idx >= count)) { fprintf(stderr, "%s: No such data file %ld in \"%s\"\n", params->cmdname, idx, params->imagefile); return -1; } } else { file_data = image_get_data(hdr); file_len = image_get_size(hdr); } /* save the "data file" into the file system */ return imagetool_save_subimage(params->outfile, file_data, file_len); }
static int moonbase_image_get_size( lua_State *s ) { void *image; struct size size; image = *(void**)luaL_checkudata( s, 1, "moonbase_image" ); image_get_size( image, &size ); lua_createtable( s, 0, 2 ); luacom_write_array( s, -1, "ii", 1, size.w, 2, size.h ); return 1; }
font font_init(const char *path) { font Font; debug_print("Loading Font ...\n"); Font.m_image = image_load(path, true, 0xff, 0x00, 0xff); int iW, iH; image_get_size(Font.m_image, &iW, &iH); if (iW % 16 != 0 || iH % 16 != 0) { debug_print("WARNING: Font has invalid dimensions.\n"); } Font.m_iGlyphWidth = iW / 16; Font.m_iGlyphHeight = iH / 16; return Font; }
static int image_verify_header(char *ptr, int fd) { int len, nread; char *data; uint32_t checksum; image_header_t *hdr = (image_header_t *)ptr; char buf[PAGE_SIZE]; if (image_get_magic(hdr) != IH_MAGIC) return 0; data = (char *)hdr; len = image_get_header_size(); checksum = image_get_hcrc(hdr); hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ if (crc32(0, data, len) != checksum) { fprintf(stderr, "%s: Maybe image found but it has bad header checksum!\n", cmdname); return 0; } len = image_get_size(hdr); checksum = 0; while (len > 0) { nread = read(fd, buf, MIN(len,PAGE_SIZE)); if (nread != MIN(len,PAGE_SIZE)) { fprintf(stderr, "%s: Error while reading: %s\n", cmdname, strerror(errno)); exit(EXIT_FAILURE); } checksum = crc32(checksum, buf, nread); len -= nread; } if (checksum != image_get_dcrc(hdr)) { fprintf (stderr, "%s: Maybe image found but it has corrupted data!\n", cmdname); return 0; } return 1; }
static int vhd_fix_write(int fd) { struct vhd_footer footer; uint64_t imgsz; int error; error = image_copyout(fd); if (!error) { imgsz = image_get_size() * secsz; vhd_make_footer(&footer, imgsz, VHD_DISK_TYPE_FIXED, ~0ULL); if (sparse_write(fd, &footer, sizeof(footer)) < 0) error = errno; } return (error); }
/** * image_print_contents - prints out the contents of the legacy format image * @ptr: pointer to the legacy format image header * @p: pointer to prefix string * * image_print_contents() formats a multi line legacy image contents description. * The routine prints out all header fields followed by the size/offset data * for MULTI/SCRIPT images. * * returns: * no returned results */ void image_print_contents(const void *ptr) { const image_header_t *hdr = (const image_header_t *)ptr; const char __maybe_unused *p; p = IMAGE_INDENT_STRING; printf("%sImage Name: %.*s\n", p, IH_NMLEN, image_get_name(hdr)); if (IMAGE_ENABLE_TIMESTAMP) { printf("%sCreated: ", p); genimg_print_time((time_t)image_get_time(hdr)); } printf("%sImage Type: ", p); image_print_type(hdr); printf("%sData Size: ", p); genimg_print_size(image_get_data_size(hdr)); printf("%sLoad Address: %08x\n", p, image_get_load(hdr)); printf("%sEntry Point: %08x\n", p, image_get_ep(hdr)); if (image_check_type(hdr, IH_TYPE_MULTI) || image_check_type(hdr, IH_TYPE_SCRIPT)) { int i; ulong data, len; ulong count = image_multi_count(hdr); printf("%sContents:\n", p); for (i = 0; i < count; i++) { image_multi_getimg(hdr, i, &data, &len); printf("%s Image %d: ", p, i); genimg_print_size(len); if (image_check_type(hdr, IH_TYPE_SCRIPT) && i > 0) { /* * the user may need to know offsets * if planning to do something with * multiple files */ printf("%s Offset = 0x%08lx\n", p, data); } } } else if (image_check_type(hdr, IH_TYPE_FIRMWARE_IVT)) { printf("HAB Blocks: 0x%08x 0x0000 0x%08x\n", image_get_load(hdr) - image_get_header_size(), image_get_size(hdr) + image_get_header_size() - 0x1FE0); } }
static int vhd_dyn_write(int fd) { struct vhd_footer footer; struct vhd_dyn_header header; uint64_t imgsz; lba_t blk, blkcnt, nblks; uint32_t *bat; void *bitmap; size_t batsz; uint32_t sector; int bat_entries, error, entry; imgsz = image_get_size() * secsz; bat_entries = imgsz / VHD_BLOCK_SIZE; vhd_make_footer(&footer, imgsz, VHD_DISK_TYPE_DYNAMIC, sizeof(footer)); if (sparse_write(fd, &footer, sizeof(footer)) < 0) return (errno); memset(&header, 0, sizeof(header)); be64enc(&header.cookie, VHD_HEADER_COOKIE); be64enc(&header.data_offset, ~0ULL); be64enc(&header.table_offset, sizeof(footer) + sizeof(header)); be32enc(&header.version, VHD_VERSION); be32enc(&header.max_entries, bat_entries); be32enc(&header.block_size, VHD_BLOCK_SIZE); be32enc(&header.checksum, vhd_checksum(&header, sizeof(header))); if (sparse_write(fd, &header, sizeof(header)) < 0) return (errno); batsz = bat_entries * sizeof(uint32_t); batsz = (batsz + VHD_SECTOR_SIZE - 1) & ~(VHD_SECTOR_SIZE - 1); bat = malloc(batsz); if (bat == NULL) return (errno); memset(bat, 0xff, batsz); blkcnt = VHD_BLOCK_SIZE / secsz; sector = (sizeof(footer) + sizeof(header) + batsz) / VHD_SECTOR_SIZE; for (entry = 0; entry < bat_entries; entry++) { blk = entry * blkcnt; if (image_data(blk, blkcnt)) { be32enc(&bat[entry], sector); sector += (VHD_BLOCK_SIZE / VHD_SECTOR_SIZE) + 1; } } if (sparse_write(fd, bat, batsz) < 0) { free(bat); return (errno); } free(bat); bitmap = malloc(VHD_SECTOR_SIZE); if (bitmap == NULL) return (errno); memset(bitmap, 0xff, VHD_SECTOR_SIZE); blk = 0; blkcnt = VHD_BLOCK_SIZE / secsz; error = 0; nblks = image_get_size(); while (blk < nblks) { if (!image_data(blk, blkcnt)) { blk += blkcnt; continue; } if (sparse_write(fd, bitmap, VHD_SECTOR_SIZE) < 0) { error = errno; break; } error = image_copyout_region(fd, blk, blkcnt); if (error) break; blk += blkcnt; } free(bitmap); if (blk != nblks) return (error); if (sparse_write(fd, &footer, sizeof(footer)) < 0) return (errno); return (0); }
/* * Check uImage payload CRC, usually the kernel blob wrapped in uImage * header */ static int image_check_dcrc(const image_header_t *hdr) { uint32_t dcrc = crc32(0, hdr + 1, image_get_size(hdr)); return (dcrc == image_get_dcrc(hdr)); }
static int vmdk_write(int fd) { struct vmdk_header hdr; uint32_t *gt, *gd, *rgd; char *buf, *desc; off_t cur, lim; uint64_t imagesz; lba_t blkofs, blkcnt; size_t gdsz, gtsz; uint32_t sec, cursec; int error, desc_len, n, ngrains, ngts; imagesz = (image_get_size() * secsz) / VMDK_SECTOR_SIZE; memset(&hdr, 0, sizeof(hdr)); le32enc(&hdr.magic, VMDK_MAGIC); le32enc(&hdr.version, VMDK_VERSION); le32enc(&hdr.flags, VMDK_FLAGS_NL_TEST | VMDK_FLAGS_RGT_USED); le64enc(&hdr.capacity, imagesz); le64enc(&hdr.grain_size, grainsz); n = asprintf(&desc, desc_fmt, 1 /*version*/, 0 /*CID*/, (uintmax_t)imagesz /*size*/, "" /*name*/, ncyls /*cylinders*/, nheads /*heads*/, nsecs /*sectors*/); if (n == -1) return (ENOMEM); desc_len = (n + VMDK_SECTOR_SIZE - 1) & ~(VMDK_SECTOR_SIZE - 1); desc = realloc(desc, desc_len); memset(desc + n, 0, desc_len - n); le64enc(&hdr.desc_offset, 1); le64enc(&hdr.desc_size, desc_len / VMDK_SECTOR_SIZE); le32enc(&hdr.ngtes, VMDK_NGTES); sec = desc_len / VMDK_SECTOR_SIZE + 1; ngrains = imagesz / grainsz; ngts = (ngrains + VMDK_NGTES - 1) / VMDK_NGTES; gdsz = (ngts * sizeof(uint32_t) + VMDK_SECTOR_SIZE - 1) & ~(VMDK_SECTOR_SIZE - 1); gd = calloc(1, gdsz); if (gd == NULL) { free(desc); return (ENOMEM); } le64enc(&hdr.gd_offset, sec); sec += gdsz / VMDK_SECTOR_SIZE; for (n = 0; n < ngts; n++) { le32enc(gd + n, sec); sec += VMDK_NGTES * sizeof(uint32_t) / VMDK_SECTOR_SIZE; } rgd = calloc(1, gdsz); if (rgd == NULL) { free(gd); free(desc); return (ENOMEM); } le64enc(&hdr.rgd_offset, sec); sec += gdsz / VMDK_SECTOR_SIZE; for (n = 0; n < ngts; n++) { le32enc(rgd + n, sec); sec += VMDK_NGTES * sizeof(uint32_t) / VMDK_SECTOR_SIZE; } sec = (sec + grainsz - 1) & ~(grainsz - 1); if (verbose) fprintf(stderr, "VMDK: overhead = %ju\n", (uintmax_t)(sec * VMDK_SECTOR_SIZE)); le64enc(&hdr.overhead, sec); be32enc(&hdr.nl_test, VMDK_NL_TEST); gt = calloc(ngts, VMDK_NGTES * sizeof(uint32_t)); if (gt == NULL) { free(rgd); free(gd); free(desc); return (ENOMEM); } gtsz = ngts * VMDK_NGTES * sizeof(uint32_t); cursec = sec; blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; for (n = 0; n < ngrains; n++) { blkofs = n * blkcnt; if (image_data(blkofs, blkcnt)) { le32enc(gt + n, cursec); cursec += grainsz; } } error = 0; if (!error && sparse_write(fd, &hdr, VMDK_SECTOR_SIZE) < 0) error = errno; if (!error && sparse_write(fd, desc, desc_len) < 0) error = errno; if (!error && sparse_write(fd, gd, gdsz) < 0) error = errno; if (!error && sparse_write(fd, gt, gtsz) < 0) error = errno; if (!error && sparse_write(fd, rgd, gdsz) < 0) error = errno; if (!error && sparse_write(fd, gt, gtsz) < 0) error = errno; free(gt); free(rgd); free(gd); free(desc); if (error) return (error); cur = VMDK_SECTOR_SIZE + desc_len + (gdsz + gtsz) * 2; lim = sec * VMDK_SECTOR_SIZE; if (cur < lim) { buf = calloc(1, VMDK_SECTOR_SIZE); if (buf == NULL) error = ENOMEM; while (!error && cur < lim) { if (sparse_write(fd, buf, VMDK_SECTOR_SIZE) < 0) error = errno; cur += VMDK_SECTOR_SIZE; } if (buf != NULL) free(buf); } if (error) return (error); blkcnt = (grainsz * VMDK_SECTOR_SIZE) / secsz; for (n = 0; n < ngrains; n++) { blkofs = n * blkcnt; if (image_data(blkofs, blkcnt)) { error = image_copyout_region(fd, blkofs, blkcnt); if (error) return (error); } } return (image_copyout_done(fd)); }