Backup region creation and contents copying
PATCH 2/17 Backup region creation and contents copying
This patch adds support for reserving space for backup region. Also adds code in purgatory to copy the first 640K to backup region.
Signed-off-by Vivek Goyal <[email protected]>
---
kexec-tools-1.101-root/kexec/arch/i386/crashdump-x86.h | 9 ++ kexec-tools-1.101-root/kexec/arch/i386/kexec-beoboot-x86.c | 2 kexec-tools-1.101-root/kexec/arch/i386/kexec-bzImage.c | 2 kexec-tools-1.101-root/kexec/arch/i386/kexec-elf-x86.c | 19 ++++ kexec-tools-1.101-root/kexec/arch/i386/kexec-multiboot-x86.c | 4 kexec-tools-1.101-root/kexec/arch/i386/kexec-x86.c | 28 +++++- kexec-tools-1.101-root/kexec/arch/i386/kexec-x86.h | 8 - kexec-tools-1.101-root/kexec/arch/i386/x86-linux-setup.c | 3 kexec-tools-1.101-root/kexec/arch/ia64/kexec-elf-ia64.c | 2 kexec-tools-1.101-root/kexec/arch/ia64/kexec-ia64.c | 5 - kexec-tools-1.101-root/kexec/arch/ia64/kexec-ia64.h | 2 kexec-tools-1.101-root/kexec/arch/ppc/kexec-dol-ppc.c | 2 kexec-tools-1.101-root/kexec/arch/ppc/kexec-elf-ppc.c | 2 kexec-tools-1.101-root/kexec/arch/ppc/kexec-ppc.c | 5 - kexec-tools-1.101-root/kexec/arch/ppc/kexec-ppc.h | 4 kexec-tools-1.101-root/kexec/arch/ppc64/kexec-elf-ppc64.c | 2 kexec-tools-1.101-root/kexec/arch/ppc64/kexec-ppc64.h | 2 kexec-tools-1.101-root/kexec/arch/x86_64/kexec-elf-x86_64.c | 2 kexec-tools-1.101-root/kexec/arch/x86_64/kexec-x86_64.c | 5 - kexec-tools-1.101-root/kexec/arch/x86_64/kexec-x86_64.h | 2 kexec-tools-1.101-root/kexec/kexec.c | 20 ++-- kexec-tools-1.101-root/kexec/kexec.h | 10 +- kexec-tools-1.101-root/purgatory/arch/i386/Makefile | 1 kexec-tools-1.101-root/purgatory/arch/i386/crashdump_backup.c | 44 ++++++++++ kexec-tools-1.101-root/purgatory/arch/i386/purgatory-x86.c | 2 kexec-tools-1.101-root/purgatory/arch/i386/purgatory-x86.h | 1 26 files changed, 150 insertions(+), 38 deletions(-)
kexec/arch/i386/crashdump-x86.h new file +9 -0
@@ -0,0 +1,9 @@ +#ifndef CRASHDUMP_X86_H +#define CRASHDUMP_X86_H + +/* Backup Region, First 640K of System RAM. */ +#define BACKUP_START 0x00000000 +#define BACKUP_END 0x0009ffff +#define BACKUP_SIZE (BACKUP_END - BACKUP_START + 1) + +#endif /* CRASHDUMP_X86_H */
kexec/arch/i386/kexec-beoboot-x86.c renamed from kexec/arch/i386/kexec-beoboot-x86.c~kexec-tools-crashdump-backup-x86 +1 -1
@@ -76,7 +76,7 @@ void beoboot_usage(void)#define INITRD_BASE 0x1000000/* 16MB */ int beoboot_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {struct beoboot_header bb_header;const unsigned char *command_line, *kernel, *initrd;
kexec/arch/i386/kexec-bzImage.c renamed from kexec/arch/i386/kexec-bzImage.c~kexec-tools-crashdump-backup-x86 +1 -1
@@ -221,7 +221,7 @@ int do_bzImage_load(struct kexec_info *i }int bzImage_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {const char *command_line;const char *ramdisk;
kexec/arch/i386/kexec-elf-x86.c renamed from kexec/arch/i386/kexec-elf-x86.c~kexec-tools-crashdump-backup-x86 +18 -1
@@ -32,10 +32,12 @@#include <elf.h> #include <x86/x86-linux.h> #include "../../kexec.h" +#include "../../kexec-syscall.h" #include "../../kexec-elf.h" #include "../../kexec-elf-boot.h" #include "x86-linux-setup.h" #include "kexec-x86.h" +#include "crashdump-x86.h" #include <arch/options.h> static const int probe_debug =0 ;
@@ -82,7 +84,7 @@ void elf_x86_usage(void) }int elf_x86_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {struct mem_ehdr ehdr;const char *command_line;
@@ -233,6 +235,21 @@ int elf_x86_load(int argc, char **argv, ramdisk_buf =slurp_file (ramdisk, &ramdisk_length); } +/* If panic kernel is being loaded, additional segments need +* to be created. */ +if (kexec_flags &KEXEC_ON_CRASH ) { +void *tmp; +unsigned long sz; +int nr_ranges, align =1024 ; +/* Create a backup region segment to store first 638K +* memory*/ + sz = (BACKUP_SIZE + align -1 ) & ~(align -1 ); + tmp =xmalloc (sz); +memset (tmp,0 , sz); + info->backup_start =add_buffer (info, tmp, sz, sz,1024 , +0 , max_addr,1 ); + } +/* Tell the kernel what is going on */ setup_linux_bootloader_parameters(info, &hdr->hdr, param_base, offsetof(struct x86_linux_faked_param_header, command_line),
kexec/arch/i386/kexec-multiboot-x86.c renamed from kexec/arch/i386/kexec-multiboot-x86.c~kexec-tools-crashdump-backup-x86 +2 -2
@@ -138,7 +138,7 @@ void multiboot_x86_usage(void) }int multiboot_x86_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags)/* Marshal up a multiboot-style kernel */ {struct multiboot_info *mbi;
@@ -246,7 +246,7 @@ int multiboot_x86_load(int argc, char ** mbi->boot_loader_name =sizeof (*mbi) + command_line_len;/* Memory map */ -if ((get_memory_ranges (&range, &ranges) <0 ) || ranges ==0 ) { +if ((get_memory_ranges (&range, &ranges, kexec_flags) <0 ) || ranges ==0 ) {fprintf (stderr,"Cannot get memory information\n" );return -1 ; }
kexec/arch/i386/kexec-x86.c renamed from kexec/arch/i386/kexec-x86.c~kexec-tools-crashdump-backup-x86 +26 -2
@@ -37,7 +37,8 @@static struct memory_range memory_range[MAX_MEMORY_RANGES ];/* Return a sorted list of memory ranges. */ -int get_memory_ranges (struct memory_range **range,int *ranges) +int get_memory_ranges (struct memory_range **range,int *ranges, +unsigned long kexec_flags) {const char iomem[]="/proc/iomem" ;int memory_ranges =0 ;
@@ -79,6 +80,20 @@ int get_memory_ranges(struct memory_rangelse if (memcmp (str,"ACPI Non-volatile Storage\n" ,26 ) ==0 ) { type =RANGE_ACPI_NVS ; } +else if (memcmp (str,"Crash kernel\n" ,13 ) ==0 ) { +/* Redefine the memory region boundaries if kernel +* exports the limits and if it is panic kernel. +* Override user values only if kernel exported values are +* subset of user defined values. +*/ +if (kexec_flags &KEXEC_ON_CRASH ) { +if (start > mem_min) + mem_min = start; +if (end < mem_max) + mem_max = end; + } +continue ; + }else {continue ; }
@@ -247,8 +262,10 @@ int arch_compat_trampoline(struct kexec_return 0 ; } -void arch_update_purgatory (struct kexec_info *info) +void arch_update_purgatory (struct kexec_info *info,unsigned long kexec_flags) { +uint8_t panic_kernel =0 ; +elf_rel_set_symbol (&info->rhdr,"reset_vga" , &arch_options.reset_vga,sizeof (arch_options.reset_vga)); elf_rel_set_symbol(&info->rhdr, "serial_base",
@@ -259,4 +276,11 @@ void arch_update_purgatory(struct kexec_ &arch_options.console_vga, sizeof(arch_options.console_vga));elf_rel_set_symbol (&info->rhdr,"console_serial" , &arch_options.console_serial,sizeof (arch_options.console_serial)); +if (kexec_flags &KEXEC_ON_CRASH ) { + panic_kernel =1 ; +elf_rel_set_symbol (&info->rhdr,"backup_start" , + &info->backup_start,sizeof (info->backup_start)); + } +elf_rel_set_symbol (&info->rhdr,"panic_kernel" , + &panic_kernel,sizeof (panic_kernel)); }
kexec/arch/i386/kexec-x86.h renamed from kexec/arch/i386/kexec-x86.h~kexec-tools-crashdump-backup-x86 +4 -4
@@ -37,17 +37,17 @@ struct entry16_regs {int multiboot_x86_probe (const char *buf,off_t len);int multiboot_x86_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void multiboot_x86_usage (void );int elf_x86_probe (const char *buf,off_t len);int elf_x86_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void elf_x86_usage (void );int bzImage_probe (const char *buf,off_t len);int bzImage_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void bzImage_usage (void ); int do_bzImage_load(struct kexec_info *info, const char *kernel, off_t kernel_len,
@@ -57,7 +57,7 @@ int do_bzImage_load(struct kexec_info *iint beoboot_probe (const char *buf,off_t len);int beoboot_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void beoboot_usage (void );int nbi_probe (const char *buf,off_t len);
kexec/arch/i386/x86-linux-setup.c renamed from kexec/arch/i386/x86-linux-setup.c~kexec-tools-crashdump-backup-x86 +2 -1
@@ -99,6 +99,7 @@ void setup_linux_system_parameters(struc/* Fill in information the BIOS would usually provide */ struct memory_range *range;int i, ranges; +unsigned long kexec_flags =0 ;/* Default screen size */ real_mode->orig_x =0 ;
@@ -135,7 +136,7 @@ void setup_linux_system_parameters(struc real_mode->aux_device_info =0 ;/* Fill in the memory info */ -if ((get_memory_ranges (&range, &ranges) <0 ) || ranges ==0 ) { +if ((get_memory_ranges (&range, &ranges, kexec_flags) <0 ) || ranges ==0 ) {die ("Cannot get memory information\n" ); }if (ranges >E820MAX ) {
kexec/arch/ia64/kexec-elf-ia64.c renamed from kexec/arch/ia64/kexec-elf-ia64.c~kexec-tools-crashdump-backup-x86 +1 -1
@@ -78,7 +78,7 @@ void elf_ia64_usage(void) }int elf_ia64_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {struct mem_ehdr ehdr;const char *command_line;
kexec/arch/ia64/kexec-ia64.c renamed from kexec/arch/ia64/kexec-ia64.c~kexec-tools-crashdump-backup-x86 +3 -2
@@ -38,7 +38,8 @@static struct memory_range memory_range[MAX_MEMORY_RANGES ];/* Return a sorted list of available memory ranges. */ -int get_memory_ranges (struct memory_range **range,int *ranges) +int get_memory_ranges (struct memory_range **range,int *ranges, +unsigned long kexec_flags) {int memory_ranges;/*
@@ -150,7 +151,7 @@ int arch_compat_trampoline(struct kexec_return 0 ; } -void arch_update_purgatory (struct kexec_info *info) +void arch_update_purgatory (struct kexec_info *info,unsigned long kexec_flags) { }
kexec/arch/ia64/kexec-ia64.h renamed from kexec/arch/ia64/kexec-ia64.h~kexec-tools-crashdump-backup-x86 +1 -1
@@ -3,7 +3,7 @@int elf_ia64_probe (const char *buf,off_t len);int elf_ia64_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void elf_ia64_usage (void );#endif /* KEXEC_IA64_H */
kexec/arch/ppc64/kexec-elf-ppc64.c renamed from kexec/arch/ppc64/kexec-elf-ppc64.c~kexec-tools-crashdump-backup-x86 +1 -1
@@ -95,7 +95,7 @@ int elf_ppc64_probe(const char *buf, off }int elf_ppc64_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {struct mem_ehdr ehdr;
kexec/arch/ppc64/kexec-ppc64.h renamed from kexec/arch/ppc64/kexec-ppc64.h~kexec-tools-crashdump-backup-x86 +1 -1
@@ -3,7 +3,7 @@int elf_ppc64_probe (const char *buf,off_t len);int elf_ppc64_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void elf_ppc64_usage (void );#endif /* KEXEC_PPC_H */
kexec/arch/ppc/kexec-dol-ppc.c renamed from kexec/arch/ppc/kexec-dol-ppc.c~kexec-tools-crashdump-backup-x86 +1 -1
@@ -320,7 +320,7 @@ void dol_ppc_usage(void) }int dol_ppc_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {dol_header header, *h;unsigned long entry;
kexec/arch/ppc/kexec-elf-ppc.c renamed from kexec/arch/ppc/kexec-elf-ppc.c~kexec-tools-crashdump-backup-x86 +1 -1
@@ -124,7 +124,7 @@ static void gamecube_hack_addresses(stru }int elf_ppc_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {struct mem_ehdr ehdr;char *arg_buf;
kexec/arch/ppc/kexec-ppc.c renamed from kexec/arch/ppc/kexec-ppc.c~kexec-tools-crashdump-backup-x86 +3 -2
@@ -23,7 +23,8 @@static struct memory_range memory_range[MAX_MEMORY_RANGES ];/* Return a sorted list of memory ranges. */ -int get_memory_ranges (struct memory_range **range,int *ranges) +int get_memory_ranges (struct memory_range **range,int *ranges, +unsigned long kexec_flags) {int memory_ranges =0 ;#ifdef CONFIG_GAMECUBE
@@ -145,7 +146,7 @@ int arch_compat_trampoline(struct kexec_return 0 ; } -void arch_update_purgatory (struct kexec_info *info) +void arch_update_purgatory (struct kexec_info *info,unsigned long kexec_flags) { }
kexec/arch/ppc/kexec-ppc.h renamed from kexec/arch/ppc/kexec-ppc.h~kexec-tools-crashdump-backup-x86 +2 -2
@@ -17,12 +17,12 @@ extern struct {int elf_ppc_probe (const char *buf,off_t len);int elf_ppc_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void elf_ppc_usage (void );int dol_ppc_probe (const char *buf,off_t len);int dol_ppc_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void dol_ppc_usage (void );#endif /* KEXEC_PPC_H */
kexec/arch/x86_64/kexec-elf-x86_64.c renamed from kexec/arch/x86_64/kexec-elf-x86_64.c~kexec-tools-crashdump-backup-x86 +1 -1
@@ -81,7 +81,7 @@ void elf_x86_64_usage(void) }int elf_x86_64_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info) +struct kexec_info *info,unsigned long kexec_flags) {struct mem_ehdr ehdr;const char *command_line;
kexec/arch/x86_64/kexec-x86_64.c renamed from kexec/arch/x86_64/kexec-x86_64.c~kexec-tools-crashdump-backup-x86 +3 -2
@@ -37,7 +37,8 @@static struct memory_range memory_range[MAX_MEMORY_RANGES ];/* Return a sorted list of memory ranges. */ -int get_memory_ranges (struct memory_range **range,int *ranges) +int get_memory_ranges (struct memory_range **range,int *ranges, +unsigned long kexec_flags) {const char iomem[]="/proc/iomem" ;int memory_ranges =0 ;
@@ -232,7 +233,7 @@ int arch_compat_trampoline(struct kexec_return 0 ; } -void arch_update_purgatory (struct kexec_info *info) +void arch_update_purgatory (struct kexec_info *info,unsigned long kexec_flags) {elf_rel_set_symbol (&info->rhdr,"reset_vga" , &arch_options.reset_vga,sizeof (arch_options.reset_vga));
kexec/arch/x86_64/kexec-x86_64.h renamed from kexec/arch/x86_64/kexec-x86_64.h~kexec-tools-crashdump-backup-x86 +1 -1
@@ -25,7 +25,7 @@ struct entry64_regs {int elf_x86_64_probe (const char *buf,off_t len);int elf_x86_64_load (int argc,char **argv,const char *buf,off_t len, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);void elf_x86_64_usage (void );#endif /* KEXEC_X86_64_H */
kexec/kexec.c renamed from kexec/kexec.c~kexec-tools-crashdump-backup-x86 +13 -7
@@ -38,8 +38,8 @@#include "kexec-elf.h" #include "kexec-sha256.h" -static unsigned long long mem_min =0 ; -static unsigned long long mem_max =ULONG_MAX ; +unsigned long long mem_min =0 ; +unsigned long long mem_max =ULONG_MAX ;void die (char *fmt, ...) {
@@ -445,7 +445,7 @@ char *slurp_decompress_file(const char * }#endif -static void update_purgatory (struct kexec_info *info) +static void update_purgatory (struct kexec_info *info,unsigned long kexec_flags) {static const uint8_t null_buf[256 ];sha256_context ctx;
@@ -456,7 +456,7 @@ static void update_purgatory(struct kexeif (!info->rhdr.e_shdr) {return ; } -arch_update_purgatory (info); +arch_update_purgatory (info, kexec_flags);memset (region,0 ,sizeof (region));sha256_starts (&ctx);/* Compute a hash of the loaded kernel */
@@ -470,6 +470,10 @@ static void update_purgatory(struct kexeif (info->segment[i].mem == (void *)info->rhdr.rel_addr) {continue ; } +/* Don't include backup region in the checksum */ +if (info->segment[i].mem == (void *)info->backup_start) { +continue ; + }sha256_update (&ctx, info->segment[i].buf, info->segment[i].bufsz); nullsz = info->segment[i].memsz - info->segment[i].bufsz;while (nullsz) {
@@ -507,6 +511,7 @@ static int my_load(const char *type, int info.segment =NULL ; info.nr_segments =0 ; info.entry =NULL ; + info.backup_start =0 ; result =0 ;if (argc - fileind <=0 ) {
@@ -522,7 +527,7 @@ static int my_load(const char *type, int kernel_buf, kernel_size);#endif -if (get_memory_ranges (&memory_range, &memory_ranges) <0 ) { +if (get_memory_ranges (&memory_range, &memory_ranges, kexec_flags) <0 ) {fprintf (stderr,"Could not get memory layout\n" );return -1 ; }
@@ -559,7 +564,8 @@ static int my_load(const char *type, int } } } -if (file_type[i].load (argc, argv, kernel_buf, kernel_size, &info) <0 ) { +if (file_type[i].load (argc, argv, kernel_buf, kernel_size, &info, + kexec_flags) <0 ) {fprintf (stderr,"Cannot load %s\n" , kernel);return -1 ; }
@@ -582,7 +588,7 @@ static int my_load(const char *type, intreturn -1 ; }/* if purgatory is loaded update it */ -update_purgatory (&info); +update_purgatory (&info, kexec_flags);#if 0 fprintf (stderr,"kexec_load: entry = %p flags = %lx\n" , info.entry, kexec_flags);
kexec/kexec.h renamed from kexec/kexec.h~kexec-tools-crashdump-backup-x86 +7 -3
@@ -91,6 +91,8 @@ do { \ } while(0)#endif +extern unsigned long long mem_min, mem_max; +struct kexec_segment {const void *buf;size_t bufsz;
@@ -112,10 +114,12 @@ struct kexec_info {int nr_segments;void *entry;struct mem_ehdr rhdr; +unsigned long backup_start; };void usage (void ); -int get_memory_ranges (struct memory_range **range,int *ranges); +int get_memory_ranges (struct memory_range **range,int *ranges, +unsigned long kexec_flags);int valid_memory_range (unsigned long sstart,unsigned long send);int valid_memory_segment (struct kexec_segment *segment);void print_segments (FILE *file,struct kexec_info *info);
@@ -128,7 +132,7 @@ unsigned long locate_hole(struct kexec_itypedef int (probe_t )(const char *kernel_buf,off_t kernel_size);typedef int (load_t )(int argc,char **argv,const char *kernel_buf,off_t kernel_size, -struct kexec_info *info); +struct kexec_info *info,unsigned long kexec_flags);typedef void (usage_t )(void );struct file_type {const char *name;
@@ -189,6 +193,6 @@ extern size_t purgatory_size;void arch_usage (void );int arch_process_options (int argc,char **argv);int arch_compat_trampoline (struct kexec_info *info,unsigned long *flags); -void arch_update_purgatory (struct kexec_info *info); +void arch_update_purgatory (struct kexec_info *info,unsigned long kexec_flags);#endif /* KEXEC_H */
purgatory/arch/i386/crashdump_backup.c new file +44 -0
44 lines not on this page · raw message
purgatory/arch/i386/Makefile renamed from purgatory/arch/i386/Makefile~kexec-tools-crashdump-backup-x86 +1 -0
@@ -12,3 +12,4 @@ PURGATORY_C_SRCS+= purgatory/arch/i386/p PURGATORY_C_SRCS+= purgatory/arch/i386/console-x86.c PURGATORY_C_SRCS+= purgatory/arch/i386/vga.c PURGATORY_C_SRCS+= purgatory/arch/i386/pic.c +PURGATORY_C_SRCS+= purgatory/arch/i386/crashdump_backup.c
purgatory/arch/i386/purgatory-x86.c renamed from purgatory/arch/i386/purgatory-x86.c~kexec-tools-crashdump-backup-x86 +2 -0
@@ -30,6 +30,7 @@ void x86_setup_cpu(void)uint8_t reset_vga =0 ;uint8_t legacy_timer =0 ;uint8_t legacy_pic =0 ; +uint8_t panic_kernel =0 ;void setup_arch (void ) {
@@ -37,4 +38,5 @@ void setup_arch(void)if (reset_vga)x86_reset_vga ();if (legacy_pic)x86_setup_legacy_pic ();/* if (legacy_timer) x86_setup_legacy_timer(); */ +if (panic_kernel)crashdump_backup_memory (); }
purgatory/arch/i386/purgatory-x86.h renamed from purgatory/arch/i386/purgatory-x86.h~kexec-tools-crashdump-backup-x86 +1 -0
@@ -4,5 +4,6 @@void x86_reset_vga (void );void x86_setup_legacy_pic (void );void x86_setup_legacy_timer (void ); +void crashdump_backup_memory (void );#endif /* PURGATORY_X86_H */
_