/* Open the tos partition and load the tos image into memory * Parameters: * label - Label for the partition in the GPT * image - the image pointer after loading from the GPT * Return values: * EFI_SUCCESS - image is loaded * EFI_ACCESS_DENIED - Error in image loading * EFI_INVALID_PARAMETER - wrong image size * EFI_OUT_OF_RESOURCES - Out of memory */ static EFI_STATUS tos_image_load_partition(IN const CHAR16 *label, OUT VOID **image) { UINT32 MediaId; UINT32 img_size; EFI_STATUS ret; struct gpt_partition_interface gpart; UINT64 partition_start; UINT64 partition_size; VOID *bootimg; struct boot_img_hdr aosp_header; ret = gpt_get_partition_by_label(label, &gpart, LOGICAL_UNIT_USER); if (EFI_ERROR(ret)) { efi_perror(ret, L"Partition %s not found", label); return ret; } MediaId = gpart.bio->Media->MediaId; partition_start = gpart.part.starting_lba * gpart.bio->Media->BlockSize; partition_size = (gpart.part.ending_lba + 1 - gpart.part.starting_lba) * gpart.bio->Media->BlockSize; debug(L"Reading TOS image header"); ret = uefi_call_wrapper(gpart.dio->ReadDisk, 5, gpart.dio, MediaId, partition_start, sizeof(aosp_header), &aosp_header); if (EFI_ERROR(ret)) { efi_perror(ret, L"ReadDisk (aosp_header)"); return ret; } img_size = bootimage_size(&aosp_header) + BOOT_SIGNATURE_MAX_SIZE; if (img_size > partition_size) { error(L"TOS image is larger than partition size"); return EFI_INVALID_PARAMETER; } bootimg = AllocatePool(img_size); if (!bootimg) { error(L"Alloc memory for TOS image failed"); return EFI_OUT_OF_RESOURCES; } debug(L"Reading Tos image: %d bytes", img_size); ret = uefi_call_wrapper(gpart.dio->ReadDisk, 5, gpart.dio, MediaId, partition_start, img_size, bootimg); if (EFI_ERROR(ret)) { efi_perror(ret, L"ReadDisk Error for TOS image read"); FreePool(bootimg); return ret; } *image = bootimg; return EFI_SUCCESS; }
int read_image_gpt(const char *name, void **data) { ssize_t size; struct boot_img_hdr hdr; int ret = -1; int fd; fd = open_bootimage(name); if (fd < 0) { error("Failed to open %s image\n", name); goto out; } size = bootimage_size(fd, &hdr, true); if (size <= 0) { error("Invalid %s image\n", name); goto out; } if (lseek(fd, 0, SEEK_SET) < 0) { error("Seek to beginning of file failed: %s\n", strerror(errno)); goto out; } *data = malloc(size); if (!*data) { error("Memory allocation failure\n"); goto close; } ret = safe_read(fd, *data, size); if (ret) free(*data); else ret = size; close: close(fd); out: return ret; }
static EFI_STATUS flash_zimage(VOID *data, UINTN size) { struct boot_img_hdr *bootimage, *new_bootimage; VOID *new_cur, *cur; UINTN new_size, partlen; EFI_STATUS ret; ret = gpt_get_partition_by_label(L"boot", &gparti, LOGICAL_UNIT_USER); if (EFI_ERROR(ret)) { error(L"Unable to get information on the boot partition"); return ret; } partlen = (gparti.part.ending_lba + 1 - gparti.part.starting_lba) * gparti.bio->Media->BlockSize; bootimage = AllocatePool(partlen); if (!bootimage) { error(L"Unable to allocate bootimage buffer"); return EFI_OUT_OF_RESOURCES; } ret = uefi_call_wrapper(gparti.dio->ReadDisk, 5, gparti.dio, gparti.bio->Media->MediaId, gparti.part.starting_lba * gparti.bio->Media->BlockSize, partlen, bootimage); if (EFI_ERROR(ret)) { efi_perror(ret, L"Failed to load the current bootimage"); goto out; } if (strncmpa((CHAR8 *)BOOT_MAGIC, bootimage->magic, BOOT_MAGIC_SIZE)) { error(L"boot partition does not contain a valid bootimage"); ret = EFI_UNSUPPORTED; goto out; } new_size = bootimage_size(bootimage) - bootimage->kernel_size + pagealign(bootimage, size); if (new_size > partlen) { error(L"Kernel image is too large to fit in the boot partition"); ret = EFI_INVALID_PARAMETER; goto out; } new_bootimage = AllocateZeroPool(new_size); if (!new_bootimage) { ret = EFI_OUT_OF_RESOURCES; goto out; } /* Create the new bootimage. */ memcpy((VOID *)new_bootimage, bootimage, bootimage->page_size); new_bootimage->kernel_size = size; new_bootimage->kernel_addr = bootimage->kernel_addr; new_cur = (VOID *)new_bootimage + bootimage->page_size; memcpy(new_cur, data, size); new_cur += pagealign(new_bootimage, size); cur = (VOID *)bootimage + bootimage->page_size + pagealign(bootimage, bootimage->kernel_size); memcpy(new_cur, cur, bootimage->ramdisk_size); new_cur += pagealign(new_bootimage, new_bootimage->ramdisk_size); cur += pagealign(bootimage, bootimage->ramdisk_size); memcpy(new_cur, cur, bootimage->second_size); /* Flash new the bootimage. */ cur_offset = gparti.part.starting_lba * gparti.bio->Media->BlockSize; ret = flash_write(new_bootimage, new_size); FreePool(new_bootimage); out: FreePool(bootimage); return ret; }