Exemple #1
0
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);
}
Exemple #2
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;
}
Exemple #3
0
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);
}
Exemple #4
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);
}
Exemple #5
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;
}
Exemple #6
0
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;
}
Exemple #7
0
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;
}
Exemple #8
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_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;
}
Exemple #9
0
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;
}