static int do_bootm_barebox(struct image_data *data) { void *barebox; barebox = read_file(data->os_file, NULL); if (!barebox) return -EINVAL; if (IS_ENABLED(CONFIG_OFTREE) && data->of_root_node) { data->oftree = of_get_fixed_tree(data->of_root_node); fdt_add_reserve_map(data->oftree); of_print_cmdline(data->of_root_node); if (bootm_verbose(data) > 1) of_print_nodes(data->of_root_node, 0); } if (bootm_verbose(data)) { printf("\nStarting barebox at 0x%p", barebox); if (data->oftree) printf(", oftree at 0x%p", data->oftree); printf("...\n"); } start_linux(barebox, 0, 0, 0, data->oftree); reset_cpu(0); }
static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int swap) { unsigned long kernel; unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0; int ret; kernel = data->os_res->start + data->os_entry; initrd_start = data->initrd_address; if (initrd_start == UIMAGE_INVALID_ADDRESS) { initrd_start = PAGE_ALIGN(free_mem); if (bootm_verbose(data)) { printf("no initrd load address, defaulting to 0x%08lx\n", initrd_start); } } if (bootm_has_initrd(data)) { ret = bootm_load_initrd(data, initrd_start); if (ret) return ret; } if (data->initrd_res) { initrd_start = data->initrd_res->start; initrd_end = data->initrd_res->end; initrd_size = resource_size(data->initrd_res); free_mem = PAGE_ALIGN(initrd_end + 1); } ret = bootm_load_devicetree(data, free_mem); if (ret) return ret; if (bootm_verbose(data)) { printf("\nStarting kernel at 0x%08lx", kernel); if (initrd_size) printf(", initrd at 0x%08lx", initrd_start); if (data->oftree) printf(", oftree at 0x%p", data->oftree); printf("...\n"); } if (data->dryrun) return 0; start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree); restart_machine(); return -ERESTARTSYS; }
static int do_bootm_linux(struct image_data *data) { unsigned long load_address, mem_free; int ret; load_address = data->os_address; ret = get_kernel_addresses(bootm_get_os_size(data), bootm_verbose(data), &load_address, &mem_free); if (ret) return ret; ret = bootm_load_os(data, load_address); if (ret) return ret; return __do_bootm_linux(data, mem_free, 0); }
static int do_bootm_linux(struct image_data *data) { unsigned long load_address, mem_start, mem_size, mem_free; int ret; ret = sdram_start_and_size(&mem_start, &mem_size); if (ret) return ret; load_address = data->os_address; if (load_address == UIMAGE_INVALID_ADDRESS) { /* * Just use a conservative default of 4 times the size of the * compressed image, to avoid the need for the kernel to * relocate itself before decompression. */ load_address = mem_start + PAGE_ALIGN( uimage_get_size(data->os, data->os_num) * 4); if (bootm_verbose(data)) printf("no OS load address, defaulting to 0x%08lx\n", load_address); } ret = bootm_load_os(data, load_address); if (ret) return ret; /* * put oftree/initrd close behind compressed kernel image to avoid * placing it outside of the kernels lowmem. */ mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M); return __do_bootm_linux(data, mem_free, 0); }
static int do_bootz_linux(struct image_data *data) { int fd, ret, swap = 0; struct zimage_header __header, *header; void *zimage; u32 end, start; size_t image_size; unsigned long load_address = data->os_address; unsigned long mem_free; fd = open(data->os_file, O_RDONLY); if (fd < 0) { perror("open"); return 1; } header = &__header; ret = read(fd, header, sizeof(*header)); if (ret < sizeof(*header)) { printf("could not read %s\n", data->os_file); goto err_out; } switch (header->magic) { case swab32(ZIMAGE_MAGIC): swap = 1; /* fall through */ case ZIMAGE_MAGIC: break; default: printf("invalid magic 0x%08x\n", header->magic); ret = -EINVAL; goto err_out; } end = header->end; start = header->start; if (swap) { end = swab32(end); start = swab32(start); } image_size = end - start; load_address = data->os_address; ret = get_kernel_addresses(image_size, bootm_verbose(data), &load_address, &mem_free); if (ret) return ret; data->os_res = request_sdram_region("zimage", load_address, image_size); if (!data->os_res) { pr_err("bootm/zImage: failed to request memory at 0x%lx to 0x%lx (%d).\n", load_address, load_address + image_size, image_size); ret = -ENOMEM; goto err_out; } zimage = (void *)data->os_res->start; memcpy(zimage, header, sizeof(*header)); ret = read_full(fd, zimage + sizeof(*header), image_size - sizeof(*header)); if (ret < 0) goto err_out; if (ret < image_size - sizeof(*header)) { printf("premature end of image\n"); ret = -EIO; goto err_out; } if (swap) { void *ptr; for (ptr = zimage; ptr < zimage + end; ptr += 4) *(u32 *)ptr = swab32(*(u32 *)ptr); } ret = do_bootz_linux_fdt(fd, data); if (ret && ret != -ENXIO) goto err_out; close(fd); return __do_bootm_linux(data, mem_free, swap); err_out: close(fd); return ret; }
static int __do_bootm_linux(struct image_data *data, int swap) { unsigned long kernel; unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0; struct memory_bank *bank; unsigned long load_address; if (data->os_res) { load_address = data->os_res->start; } else if (data->os_address != UIMAGE_INVALID_ADDRESS) { load_address = data->os_address; } else { bank = list_first_entry(&memory_banks, struct memory_bank, list); load_address = bank->start + SZ_32K; if (bootm_verbose(data)) printf("no os load address, defaulting to 0x%08lx\n", load_address); } if (!data->os_res && data->os) { data->os_res = uimage_load_to_sdram(data->os, data->os_num, load_address); if (!data->os_res) return -ENOMEM; } if (!data->os_res) { data->os_res = file_to_sdram(data->os_file, load_address); if (!data->os_res) return -ENOMEM; } kernel = data->os_res->start + data->os_entry; initrd_start = data->initrd_address; if (data->initrd_file && initrd_start == UIMAGE_INVALID_ADDRESS) { initrd_start = data->os_res->start + SZ_8M; if (bootm_verbose(data)) { printf("no initrd load address, defaulting to 0x%08lx\n", initrd_start); } } if (data->initrd) { data->initrd_res = uimage_load_to_sdram(data->initrd, data->initrd_num, initrd_start); if (!data->initrd_res) return -ENOMEM; } else if (data->initrd_file) { data->initrd_res = file_to_sdram(data->initrd_file, initrd_start); if (!data->initrd_res) return -ENOMEM; } if (data->initrd_res) { initrd_start = data->initrd_res->start; initrd_end = data->initrd_res->end; initrd_size = resource_size(data->initrd_res); } if (IS_ENABLED(CONFIG_OFTREE) && data->of_root_node) { of_add_initrd(data->of_root_node, initrd_start, initrd_end); if (initrd_end) of_add_reserve_entry(initrd_start, initrd_end); data->oftree = of_get_fixed_tree(data->of_root_node); fdt_add_reserve_map(data->oftree); of_print_cmdline(data->of_root_node); if (bootm_verbose(data) > 1) of_print_nodes(data->of_root_node, 0); } if (bootm_verbose(data)) { printf("\nStarting kernel at 0x%08lx", kernel); if (initrd_size) printf(", initrd at 0x%08lx", initrd_start); if (data->oftree) printf(", oftree at 0x%p", data->oftree); printf("...\n"); } start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree); reset_cpu(0); return -ERESTARTSYS; }
static int do_bootz_linux(struct image_data *data) { int fd, ret, swap = 0; struct zimage_header __header, *header; void *zimage; u32 end; unsigned long load_address = data->os_address; if (load_address == UIMAGE_INVALID_ADDRESS) { struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list); data->os_address = bank->start + SZ_8M; load_address = data->os_address; if (bootm_verbose(data)) printf("no os load address, defaulting to 0x%08lx\n", load_address); } fd = open(data->os_file, O_RDONLY); if (fd < 0) { perror("open"); return 1; } header = &__header; ret = read(fd, header, sizeof(*header)); if (ret < sizeof(*header)) { printf("could not read %s\n", data->os_file); goto err_out; } switch (header->magic) { case swab32(ZIMAGE_MAGIC): swap = 1; /* fall through */ case ZIMAGE_MAGIC: break; default: printf("invalid magic 0x%08x\n", header->magic); ret = -EINVAL; goto err_out; } end = header->end; if (swap) end = swab32(end); data->os_res = request_sdram_region("zimage", load_address, end); if (!data->os_res) { pr_err("bootm/zImage: failed to request memory at 0x%lx to 0x%lx (%d).\n", load_address, load_address + end, end); ret = -ENOMEM; goto err_out; } zimage = (void *)data->os_res->start; memcpy(zimage, header, sizeof(*header)); ret = read_full(fd, zimage + sizeof(*header), end - sizeof(*header)); if (ret < 0) goto err_out; if (ret < end - sizeof(*header)) { printf("premature end of image\n"); ret = -EIO; goto err_out; } if (swap) { void *ptr; for (ptr = zimage; ptr < zimage + end; ptr += 4) *(u32 *)ptr = swab32(*(u32 *)ptr); } ret = do_bootz_linux_fdt(fd, data); if (ret && ret != -ENXIO) goto err_out; close(fd); return __do_bootm_linux(data, swap); err_out: close(fd); return ret; }
static int do_bootz_linux(struct image_data *data) { int fd, ret, swap = 0; struct zimage_header __header, *header; void *zimage; u32 end, start; size_t image_size; unsigned long load_address = data->os_address; unsigned long mem_start, mem_size, mem_free; ret = sdram_start_and_size(&mem_start, &mem_size); if (ret) return ret; fd = open(data->os_file, O_RDONLY); if (fd < 0) { perror("open"); return 1; } header = &__header; ret = read(fd, header, sizeof(*header)); if (ret < sizeof(*header)) { printf("could not read %s\n", data->os_file); goto err_out; } switch (header->magic) { case swab32(ZIMAGE_MAGIC): swap = 1; /* fall through */ case ZIMAGE_MAGIC: break; default: printf("invalid magic 0x%08x\n", header->magic); ret = -EINVAL; goto err_out; } end = header->end; start = header->start; if (swap) { end = swab32(end); start = swab32(start); } image_size = end - start; if (load_address == UIMAGE_INVALID_ADDRESS) { /* * Just use a conservative default of 4 times the size of the * compressed image, to avoid the need for the kernel to * relocate itself before decompression. */ data->os_address = mem_start + PAGE_ALIGN(image_size * 4); load_address = data->os_address; if (bootm_verbose(data)) printf("no OS load address, defaulting to 0x%08lx\n", load_address); } data->os_res = request_sdram_region("zimage", load_address, image_size); if (!data->os_res) { pr_err("bootm/zImage: failed to request memory at 0x%lx to 0x%lx (%d).\n", load_address, load_address + image_size, image_size); ret = -ENOMEM; goto err_out; } zimage = (void *)data->os_res->start; memcpy(zimage, header, sizeof(*header)); ret = read_full(fd, zimage + sizeof(*header), image_size - sizeof(*header)); if (ret < 0) goto err_out; if (ret < end - sizeof(*header)) { printf("premature end of image\n"); ret = -EIO; goto err_out; } if (swap) { void *ptr; for (ptr = zimage; ptr < zimage + end; ptr += 4) *(u32 *)ptr = swab32(*(u32 *)ptr); } ret = do_bootz_linux_fdt(fd, data); if (ret && ret != -ENXIO) goto err_out; close(fd); /* * put oftree/initrd close behind compressed kernel image to avoid * placing it outside of the kernels lowmem. */ mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M); return __do_bootm_linux(data, mem_free, swap); err_out: close(fd); return ret; }
static int do_bootm_efi(struct image_data *data) { void *tmp; void *initrd = NULL; size_t size; efi_handle_t handle; int ret; const char *options; efi_loaded_image_t *loaded_image; struct linux_kernel_header *image_header, *boot_header; ret = efi_load_image(data->os_file, &loaded_image, &handle); if (ret) return ret; image_header = (struct linux_kernel_header *)loaded_image->image_base; if (image_header->boot_flag != 0xAA55 || image_header->header != 0x53726448 || image_header->version < 0x20b || !image_header->relocatable_kernel) { pr_err("Not a valid kernel image!\n"); BS->unload_image(handle); return -EINVAL; } boot_header = xmalloc(0x4000); memset(boot_header, 0, 0x4000); memcpy(boot_header, image_header, sizeof(*image_header)); boot_header->type_of_loader = 0xff; if (data->initrd_file) { tmp = read_file(data->initrd_file, &size); initrd = xmemalign(PAGE_SIZE, PAGE_ALIGN(size)); memcpy(initrd, tmp, size); memset(initrd + size, 0, PAGE_ALIGN(size) - size); free(tmp); boot_header->ramdisk_image = (uint64_t)initrd; boot_header->ramdisk_size = PAGE_ALIGN(size); } options = linux_bootargs_get(); boot_header->cmd_line_ptr = (uint64_t)options; boot_header->cmdline_size = strlen(options); boot_header->code32_start = (uint64_t)loaded_image->image_base + (image_header->setup_sects+1) * 512; if (bootm_verbose(data)) { printf("\nStarting kernel at 0x%p", loaded_image->image_base); if (data->initrd_file) printf(", initrd at 0x%08x", boot_header->ramdisk_image); printf("...\n"); } if (data->dryrun) { BS->unload_image(handle); free(boot_header); free(initrd); return 0; } efi_set_variable_usec("LoaderTimeExecUSec", &efi_systemd_vendor_guid, get_time_ns()/1000); linux_efi_handover(handle, boot_header); return 0; }