예제 #1
0
파일: bootm.c 프로젝트: bluecmd/barebox
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);
}
예제 #2
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;
}
예제 #3
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;
}
예제 #4
0
static int do_of_dump(int argc, char *argv[])
{
	int opt;
	int ret = 0;
	int fix = 0;
	struct device_node *root = NULL, *node, *of_free = NULL;
	char *dtbfile = NULL;
	size_t size;
	const char *nodename;
	int names_only = 0;

	while ((opt = getopt(argc, argv, "Ff:n")) > 0) {
		switch (opt) {
		case 'f':
			dtbfile = optarg;
			break;
		case 'F':
			fix = 1;
			break;
		case 'n':
			names_only = 1;
			break;
		default:
			return COMMAND_ERROR_USAGE;
		}
	}

	if (optind == argc)
		nodename = "/";
	else
		nodename = argv[optind];

	if (dtbfile) {
		void *fdt;

		fdt = read_file(dtbfile, &size);
		if (!fdt) {
			printf("unable to read %s: %s\n", dtbfile, strerror(errno));
			return -errno;
		}

		root = of_unflatten_dtb(fdt);

		free(fdt);

		if (IS_ERR(root)) {
			ret = PTR_ERR(root);
			goto out;
		}

		of_free = root;
	} else {
		root = of_get_root_node();

		if (fix) {
			/* create a copy of internal devicetree */
			void *fdt;
			fdt = of_flatten_dtb(root);
			root = of_unflatten_dtb(fdt);

			free(fdt);

			if (IS_ERR(root)) {
				ret = PTR_ERR(root);
				goto out;
			}

			of_free = root;
		}
	}

	if (fix) {
		ret = of_fix_tree(root);
		if (ret)
			goto out;
	}

	node = of_find_node_by_path_or_alias(root, nodename);
	if (!node) {
		printf("Cannot find nodepath %s\n", nodename);
		ret = -ENOENT;
		goto out;
	}

	if (names_only)
		of_print_nodenames(node);
	else
		of_print_nodes(node, 0);

out:
	if (of_free)
		of_delete_node(of_free);

	return ret;
}