Example #1
0
static void boot_process(struct load_url_result *result, void *data)
{
	struct boot_task *task = data;
	int rc = -1;

	if (task->cancelled) {
		cleanup_cancellations(task, result);
		return;
	}

	if (load_pending(task->image) ||
			load_pending(task->initrd) ||
			load_pending(task->dtb))
		return;

	if (check_load(task, "kernel image", task->image) ||
			check_load(task, "initrd", task->initrd) ||
			check_load(task, "dtb", task->dtb))
		goto no_load;

	/* we make a copy of the local paths, as the boot hooks might update
	 * and/or create these */
	task->local_image = task->image ? task->image->local : NULL;
	task->local_initrd = task->initrd ? task->initrd->local : NULL;
	task->local_dtb = task->dtb ? task->dtb->local : NULL;

	run_boot_hooks(task);

	update_status(task->status_fn, task->status_arg, BOOT_STATUS_INFO,
			_("performing kexec_load"));

	rc = kexec_load(task);
	if (rc) {
		update_status(task->status_fn, task->status_arg,
				BOOT_STATUS_ERROR, _("kexec load failed"));
	}

no_load:
	cleanup_load(task->image);
	cleanup_load(task->initrd);
	cleanup_load(task->dtb);

	if (!rc) {
		update_status(task->status_fn, task->status_arg,
				BOOT_STATUS_INFO,
				_("performing kexec reboot"));

		rc = kexec_reboot(task);
		if (rc) {
			update_status(task->status_fn, task->status_arg,
					BOOT_STATUS_ERROR,
					_("kexec reboot failed"));
		}
	}
}
Example #2
0
int k_unload (unsigned long kexec_flags)
{
	int result;
	long native_arch;

	/* set the arch */
	native_arch = physical_arch();
	if (native_arch < 0) {
		return -1;
	}
	kexec_flags |= native_arch;

	result = kexec_load(NULL, 0, NULL, kexec_flags);
	if (result != 0) {
		/* The unload failed, print some debugging information */
		fprintf(stderr, "kexec_load (0 segments) failed: %s\n",
			strerror(errno));
	}
	return result;
}
Example #3
0
/*
 *	Load the new kernel
 */
static int my_load(const char *type, int fileind, int argc, char **argv,
	unsigned long kexec_flags)
{
	char *kernel;
	char *kernel_buf;
	off_t kernel_size;
	int i = 0;
	int result;
	struct kexec_info info;
	int guess_only = 0;

	memset(&info, 0, sizeof(info));
	info.segment = NULL;
	info.nr_segments = 0;
	info.entry = NULL;
	info.backup_start = 0;
	info.kexec_flags = kexec_flags;

	result = 0;
	if (argc - fileind <= 0) {
		fprintf(stderr, "No kernel specified\n");
		usage();
		return -1;
	}
	kernel = argv[fileind];
	/* slurp in the input kernel */
	kernel_buf = slurp_decompress_file(kernel, &kernel_size);
#if 0
	fprintf(stderr, "kernel: %p kernel_size: %lx\n", 
		kernel_buf, kernel_size);
#endif

	if (get_memory_ranges(&info.memory_range, &info.memory_ranges,
		info.kexec_flags) < 0) {
		fprintf(stderr, "Could not get memory layout\n");
		return -1;
	}
	/* if a kernel type was specified, try to honor it */
	if (type) {
		for (i = 0; i < file_types; i++) {
			if (strcmp(type, file_type[i].name) == 0)
				break;
		}
		if (i == file_types) {
			fprintf(stderr, "Unsupported kernel type %s\n", type);
			return -1;
		} else {
			/* make sure our file is really of that type */
			if (file_type[i].probe(kernel_buf, kernel_size) < 0)
				guess_only = 1;
		}
	}
	if (!type || guess_only) {
		for (i = 0; i < file_types; i++) {
			if (file_type[i].probe(kernel_buf, kernel_size) >= 0)
				break;
		}
		if (i == file_types) {
			fprintf(stderr, "Cannot determine the file type "
					"of %s\n", kernel);
			return -1;
		} else {
			if (guess_only) {
				fprintf(stderr, "Wrong file type %s, "
					"file matches type %s\n",
					type, file_type[i].name);
				return -1;
			}
		}
	}
	if (file_type[i].load(argc, argv, kernel_buf,
			      kernel_size, &info) < 0) {
		fprintf(stderr, "Cannot load %s\n", kernel);
		return -1;
	}
	/* If we are not in native mode setup an appropriate trampoline */
	if (arch_compat_trampoline(&info) < 0) {
		return -1;
	}
	/* Verify all of the segments load to a valid location in memory */
	for (i = 0; i < info.nr_segments; i++) {
		if (!valid_memory_segment(&info, info.segment +i)) {
			fprintf(stderr, "Invalid memory segment %p - %p\n",
				info.segment[i].mem,
				((char *)info.segment[i].mem) + 
				info.segment[i].memsz);
			return -1;
		}
	}
	/* Sort the segments and verify we don't have overlaps */
	if (sort_segments(&info) < 0) {
		return -1;
	}
	/* if purgatory is loaded update it */
	update_purgatory(&info);
#if 0
	fprintf(stderr, "kexec_load: entry = %p flags = %lx\n", 
		info.entry, info.kexec_flags);
	print_segments(stderr, &info);
#endif
	result = kexec_load(
		info.entry, info.nr_segments, info.segment, info.kexec_flags);
	if (result != 0) {
		/* The load failed, print some debugging information */
		fprintf(stderr, "kexec_load failed: %s\n", 
			strerror(errno));
		fprintf(stderr, "entry       = %p flags = %lx\n", 
			info.entry, info.kexec_flags);
		print_segments(stderr, &info);
	}
	return result;
}
Example #4
-1
int k_unload (unsigned long kexec_flags)
{
	int result;

	result = kexec_load(NULL, 0, NULL, kexec_flags);
	if (result != 0) {
		/* The unload failed, print some debugging information */
		fprintf(stderr, "kexec_load (0 segments) failed: %s\n",
			strerror(errno));
	}
	return result;
}