#include #include #include #include #include #include "xc_kexec.h" extern unsigned long image; extern unsigned long image_end; int main(void) { xc_interface *xch; unsigned long start, size; size_t image_size; DECLARE_HYPERCALL_BUFFER(xen_kexec_segment_t, segments); DECLARE_HYPERCALL_BUFFER(void, image_buf); xen_kexec_load_v2_t load; int ret; xch = xc_interface_open(NULL, NULL, 0); if ( !xch ) { perror("xc_open"); exit(1); } ret = xc_kexec_get_range(xch, KEXEC_RANGE_MA_CRASH, 0, &start, &size); if ( ret ) { perror("xc_kexec_get_range"); exit(1); } printf("Crash region: 0x%08lx-0x%08lx\n", start, start + size); image_size = (void *)&image_end - (void *)ℑ printf("Image %p-%p\n", &image, (void *)&image + image_size); image_buf = xc_hypercall_buffer_alloc(xch, image_buf, image_size); if ( !image_buf ) { perror("xc_hypercall_buffer_alloc"); exit(1); } segments = xc_hypercall_buffer_alloc(xch, segments, sizeof(*segments) * 1); if ( !segments ) { perror("xc_hypercall_buffer_alloc"); exit(1); } memcpy(image_buf, &image, image_size); set_xen_guest_handle(segments[0].buf, image_buf); segments[0].size = image_size; segments[0].dest_maddr = start; load.type = KEXEC_TYPE_DEFAULT; load.class = KEXEC_CLASS_32; load.nr_segments = 1; set_xen_guest_handle(load.segments, segments); load.entry_maddr = start; ret = xc_kexec_load(xch, &load); if ( ret ) { perror("xc_kexec_load"); exit(1); } xc_hypercall_buffer_free(xch, image_buf); xc_hypercall_buffer_free(xch, segments); ret = xc_kexec(xch, KEXEC_TYPE_DEFAULT); if ( ret ) { perror("xc_kexec_exec"); exit(1); } xc_interface_close(xch); return 0; } /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * indent-tabs-mode: nil * End: */