Example #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);
}
Example #2
0
static int do_bootm_linux(struct image_data *data)
{
	void	(*kernel)(void *, void *, unsigned long,
			unsigned long, unsigned long);

	if (!data->os_res)
		return -EINVAL;

	data->oftree = of_get_fixed_tree(data->of_root_node);
	if (!data->oftree) {
		pr_err("bootm: No devicetree given.\n");
		return -EINVAL;
	}

	fdt_add_reserve_map(data->oftree);

	kernel = (void *)(data->os_address + data->os_entry);

	/*
	 * Linux Kernel Parameters (passing device tree):
	 *   r3: ptr to OF flat tree, followed by the board info data
	 *   r4: physical pointer to the kernel itself
	 *   r5: NULL
	 *   r6: NULL
	 *   r7: NULL
	 */
	kernel(data->oftree, kernel, 0, 0, 0);

	reset_cpu(0);

	/* not reached */
	return -1;
}
Example #3
0
static int do_bootm_linux(struct image_data *data)
{
	void	(*kernel)(void *, void *, unsigned long,
			unsigned long, unsigned long);
	int ret;

	ret = bootm_load_os(data, data->os_address);
	if (ret)
		return ret;

	data->oftree = of_get_fixed_tree(data->of_root_node);
	if (!data->oftree) {
		pr_err("bootm: No devicetree given.\n");
		return -EINVAL;
	}

	/* Relocate the device tree if outside the initial
	 * Linux mapped TLB.
	 */
	if (IS_ENABLED(CONFIG_MPC85xx)) {
		void *addr = data->oftree;

		if ((addr + data->oftree->totalsize) > LINUX_TLB1_MAX_ADDR) {
			addr = (void *)data->os_address;

			if (bootm_relocate_fdt(addr, data))
				goto error;
		}
	}

	fdt_add_reserve_map(data->oftree);

	kernel = (void *)(data->os_address + data->os_entry);

	/*
	 * Linux Kernel Parameters (passing device tree):
	 *   r3: ptr to OF flat tree, followed by the board info data
	 *   r4: physical pointer to the kernel itself
	 *   r5: NULL
	 *   r6: NULL
	 *   r7: NULL
	 */
	kernel(data->oftree, kernel, 0, 0, 0);

	restart_machine();

error:
	return -1;
}
Example #4
0
static int do_bootu(int argc, char *argv[])
{
	int fd;
	void *kernel = NULL;
	void *oftree = NULL;

	if (argc != 2)
		return COMMAND_ERROR_USAGE;

	fd = open(argv[1], O_RDONLY);
	if (fd > 0)
		kernel = (void *)memmap(fd, PROT_READ);

	if (!kernel)
		kernel = (void *)simple_strtoul(argv[1], NULL, 0);

#ifdef CONFIG_OFTREE
	oftree = of_get_fixed_tree(NULL);
#endif

	start_linux(kernel, 0, 0, 0, oftree, ARM_STATE_SECURE);

	return 1;
}
Example #5
0
static int do_bootz_linux_fdt(int fd, struct image_data *data)
{
	struct fdt_header __header, *header;
	void *oftree;
	int ret;

	u32 end;

	if (data->oftree)
		return -ENXIO;

	header = &__header;
	ret = read(fd, header, sizeof(*header));
	if (ret < sizeof(*header))
		return ret;

	if (file_detect_type(header, sizeof(*header)) != filetype_oftree)
		return -ENXIO;

	end = be32_to_cpu(header->totalsize);

	oftree = malloc(end + 0x8000);
	if (!oftree) {
		perror("zImage: oftree malloc");
		return -ENOMEM;
	}

	memcpy(oftree, header, sizeof(*header));

	end -= sizeof(*header);

	ret = read_full(fd, oftree + sizeof(*header), end);
	if (ret < 0)
		goto err_free;
	if (ret < end) {
		printf("premature end of image\n");
		ret = -EIO;
		goto err_free;
	}

	if (IS_BUILTIN(CONFIG_OFTREE)) {
		struct device_node *root;

		root = of_unflatten_dtb(oftree);
		if (IS_ERR(root)) {
			pr_err("unable to unflatten devicetree\n");
			goto err_free;
		}
		data->oftree = of_get_fixed_tree(root);
		if (!data->oftree) {
			pr_err("Unable to get fixed tree\n");
			ret = -EINVAL;
			goto err_free;
		}

		free(oftree);
	} else {
		data->oftree = oftree;
	}

	pr_info("zImage: concatenated oftree detected\n");

	return 0;

err_free:
	free(oftree);

	return ret;
}
Example #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;
}
Example #7
0
static int do_oftree(int argc, char *argv[])
{
	struct fdt_header *fdt = NULL;
	void *fdt_free = NULL;
	int size;
	int opt;
	char *file = NULL;
	const char *node = "/";
	int dump = 0;
	int probe = 0;
	int load = 0;
	int save = 0;
	int free_of = 0;
	int ret;

	while ((opt = getopt(argc, argv, "dpfn:ls")) > 0) {
		switch (opt) {
		case 'l':
			load = 1;
			break;
		case 'd':
			dump = 1;
			break;
		case 'p':
			if (IS_ENABLED(CONFIG_CMD_OFTREE_PROBE)) {
				probe = 1;
			} else {
				printf("oftree device probe support disabled\n");
				return COMMAND_ERROR_USAGE;
			}
			break;
		case 'f':
			free_of = 1;
			break;
		case 'n':
			node = optarg;
			break;
		case 's':
			save = 1;
			break;
		}
	}

	if (free_of) {
		struct device_node *root = of_get_root_node();

		if (root)
			of_free(root);

		return 0;
	}

	if (optind < argc)
		file = argv[optind];

	if (!dump && !probe && !load && !save)
		return COMMAND_ERROR_USAGE;

	if (save) {
		if (!file) {
			printf("no file given\n");
			ret = -ENOENT;

			goto out;
		}

		fdt = of_get_fixed_tree(NULL);
		if (!fdt) {
			printf("no devicetree available\n");
			ret = -EINVAL;

			goto out;
		}

		ret = write_file(file, fdt, fdt_totalsize(fdt));

		goto out;
	}

	if (file) {
		fdt = read_file(file, &size);
		if (!fdt) {
			printf("unable to read %s\n", file);
			return 1;
		}

		fdt_free = fdt;
	}

	if (load) {
		if (!fdt) {
			printf("no fdt given\n");
			ret = -ENOENT;

			goto out;
		}

		ret = of_unflatten_dtb(fdt);
		if (ret) {
			printf("parse oftree: %s\n", strerror(-ret));
			goto out;
		}
	}

	if (dump) {
		if (fdt) {
			ret = fdt_print(fdt, node);
		} else {
			struct device_node *n = of_find_node_by_path(node);

			if (!n) {
				ret = -ENOENT;
				goto out;
			}

			of_print_nodes(n, 0);

			ret = 0;
		}

		goto out;
	}

	if (probe) {
		ret = of_probe();
		if (ret)
			goto out;
	}

	ret = 0;
out:
	free(fdt_free);

	return ret;
}