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")); } } }
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; }
/* * 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; }
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; }