--- kexec-tools-1.101/include/x86/x86-linux.h.orig 2004-12-20 05:10:21.000000000 -0500 +++ kexec-tools-1.101/include/x86/x86-linux.h 2007-01-05 11:05:30.000000000 -0500 @@ -141,7 +141,10 @@ struct x86_linux_param_header { uint32_t high_filesz; /* 0x254 */ uint8_t reserved15[0x2d0 - 0x258]; /* 0x258 */ #else - uint8_t reserved15[0x2d0 - 0x230]; /* 0x230 */ + /* 2.04+ */ + uint32_t kernel_alignment; /* 0x230 */ + uint8_t relocatable_kernel; /* 0x234 */ + uint8_t reserved15[0x2d0 - 0x235]; /* 0x230 */ #endif struct e820entry e820_map[E820MAX]; /* 0x2d0 */ /* 0x550 */ @@ -201,12 +204,15 @@ struct x86_linux_header { uint32_t high_filesz; /* 0x254 */ uint32_t tail[32*1024 - 0x258]; /* 0x258 */ #else - uint8_t tail[32*1024 - 0x230]; /* 0x230 */ + uint32_t kernel_alignment; /* 0x230 */ + uint8_t relocatable_kernel; /* 0x234 */ + uint8_t tail[32*1024 - 0x235]; /* 0x230 */ #endif } PACKED; #endif /* ASSEMBLY */ #define DEFAULT_INITRD_ADDR_MAX 0x37FFFFFF +#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF #endif /* X86_LINUX_H */ --- kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c.orig 2007-01-05 11:05:11.000000000 -0500 +++ kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c 2007-01-05 11:05:30.000000000 -0500 @@ -680,7 +680,9 @@ int load_crashdump_segments(struct kexec tmp = xmalloc(sz); memset(tmp, 0, sz); info->backup_start = add_buffer(info, tmp, sz, sz, align, - 0, max_addr, 1); + 0, max_addr, -1); + dfprintf(stdout, "Created backup segment at 0x%lx\n", + info->backup_start); if (delete_memmap(memmap_p, info->backup_start, sz) < 0) return -1; @@ -719,7 +721,8 @@ int load_crashdump_segments(struct kexec * This is a makeshift solution until it is fixed in kernel. */ elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, - max_addr, 1); + max_addr, -1); + dfprintf(stdout, "Created elf header segment at 0x%lx\n", elfcorehdr); if (delete_memmap(memmap_p, elfcorehdr, sz) < 0) return -1; cmdline_add_memmap(mod_cmdline, memmap_p); --- kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c.orig 2007-01-05 11:05:11.000000000 -0500 +++ kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c 2007-01-05 11:05:30.000000000 -0500 @@ -59,6 +59,7 @@ void setup_linux_bootloader_parameters( initrd_addr_max = DEFAULT_INITRD_ADDR_MAX; if (real_mode->protocol_version >= 0x0203) { initrd_addr_max = real_mode->initrd_addr_max; + dfprintf(stdout, "initrd_addr_max is 0x%lx\n", initrd_addr_max); } /* Load the initrd if we have one */ @@ -66,6 +67,8 @@ void setup_linux_bootloader_parameters( initrd_base = add_buffer(info, initrd_buf, initrd_size, initrd_size, 4096, INITRD_BASE, initrd_addr_max, -1); + dfprintf(stdout, "Loaded initrd at 0x%lx size 0x%lx\n", + initrd_base, initrd_size); } else { initrd_base = 0; initrd_size = 0; --- kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c.orig 2007-01-05 11:05:11.000000000 -0500 +++ kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c 2007-01-05 11:07:04.000000000 -0500 @@ -34,8 +34,10 @@ #include #include "../../kexec.h" #include "../../kexec-elf.h" +#include "../../kexec-syscall.h" #include "kexec-x86.h" #include "x86-linux-setup.h" +#include "crashdump-x86.h" #include static const int probe_debug = 0; @@ -109,6 +111,7 @@ int do_bzImage_load(struct kexec_info *i unsigned long setup_base, setup_size; struct entry32_regs regs32; struct entry16_regs regs16; + char *modified_cmdline; /* * Find out about the file I am about to load. @@ -128,6 +131,45 @@ int do_bzImage_load(struct kexec_info *i return -1; } + /* Can't use bzImage for crash dump purposes with real mode entry */ + if((info->kexec_flags & KEXEC_ON_CRASH) && real_mode_entry) { + fprintf(stderr, "Can't use bzImage for crash dump purposes" + " with real mode entry\n"); + return -1; + } + + if((info->kexec_flags & KEXEC_ON_CRASH) && !relocatable_kernel) { + fprintf(stderr, "BzImage is not relocatable. Can't be used" + " as capture kernel.\n"); + return -1; + } + + /* Need to append some command line parameters internally in case of + * taking crash dumps. + */ + if (info->kexec_flags & KEXEC_ON_CRASH) { + modified_cmdline = xmalloc(COMMAND_LINE_SIZE); + memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); + if (command_line) { + strncpy(modified_cmdline, command_line, + COMMAND_LINE_SIZE); + modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; + } + + /* If panic kernel is being loaded, additional segments need + * to be created. load_crashdump_segments will take care of + * loading the segments as high in memory as possible, hence + * in turn as away as possible from kernel to avoid being + * stomped by the kernel. + */ + if (load_crashdump_segments(info, modified_cmdline, -1, 0) < 0) + return -1; + + /* Use new command line buffer */ + command_line = modified_cmdline; + command_line_len = strlen(command_line) +1; + } + /* Load the trampoline. This must load at a higher address * the the argument/parameter segment or the kernel will stomp * it's gdt. @@ -139,7 +181,16 @@ int do_bzImage_load(struct kexec_info *i setup_size = kern16_size + command_line_len; real_mode = xmalloc(setup_size); memcpy(real_mode, kernel, kern16_size); - if (real_mode->protocol_version >= 0x0200) { + + if (info->kexec_flags & KEXEC_ON_CRASH) { + /* If using bzImage for capture kernel, then we will not be + * executing real mode code. setup segment can be loaded + * anywhere as we will be just reading command line. + */ + setup_base = add_buffer(info, real_mode, setup_size, setup_size, + 16, 0x3000, -1, 1); + } + else if (real_mode->protocol_version >= 0x0200) { /* Careful setup_base must be greater than 8K */ setup_base = add_buffer(info, real_mode, setup_size, setup_size, 16, 0x3000, 640*1024, -1); --- kexec-tools-1.101/kexec/kexec.h.orig 2007-01-05 11:05:11.000000000 -0500 +++ kexec-tools-1.101/kexec/kexec.h 2007-01-05 11:05:30.000000000 -0500 @@ -197,4 +197,11 @@ int arch_compat_trampoline(struct kexec_ void arch_update_purgatory(struct kexec_info *info); #define MAX_LINE 160 + +#ifdef DEBUG +#define dfprintf(args...) do {fprintf(args);} while(0) +#else +#define dfprintf(args...) do { } while(0) +#endif + #endif /* KEXEC_H */