diff options
author | Huang Ying <ying.huang@intel.com> | 2008-10-29 11:24:25 +0800 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-10-31 12:58:16 +1100 |
commit | ceb04ae1223ba5cdd40df744aa73a32b2cc7d879 (patch) | |
tree | 993024edfe07b9cd7150fb2131175104e4948ad4 /purgatory | |
parent | 802a8a5e396e06a514251c44454c982bff3c5073 (diff) |
kexec jump support for kexec-tools
To support memory backup/restore an option named
--load-preserve-context is added to kexec. When it is specified
toggether with --mem-max, most segments for crash dump support are
loaded, and the memory range between mem_min to mem_max which has no
segments loaded are loaded as backup segments. To support jump back
from kexeced, options named --load-jump-back-helper and --entry are
added to load a helper image with specified entry to jump back.
Signed-off-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'purgatory')
-rw-r--r-- | purgatory/arch/i386/purgatory-x86.c | 14 | ||||
-rw-r--r-- | purgatory/arch/i386/setup-x86.S | 3 | ||||
-rw-r--r-- | purgatory/include/purgatory.h | 1 | ||||
-rw-r--r-- | purgatory/printf.c | 38 |
4 files changed, 49 insertions, 7 deletions
diff --git a/purgatory/arch/i386/purgatory-x86.c b/purgatory/arch/i386/purgatory-x86.c index 4d2c5c7..030b465 100644 --- a/purgatory/arch/i386/purgatory-x86.c +++ b/purgatory/arch/i386/purgatory-x86.c @@ -31,6 +31,8 @@ uint8_t reset_vga = 0; uint8_t legacy_timer = 0; uint8_t legacy_pic = 0; uint8_t panic_kernel = 0; +unsigned long jump_back_entry = 0; +char *cmdline_end = 0; void setup_arch(void) { @@ -40,8 +42,18 @@ void setup_arch(void) /* if (legacy_timer) x86_setup_legacy_timer(); */ } +extern void x86_setup_jump_back_entry(); + /* This function can be used to execute after the SHA256 verification. */ void post_verification_setup_arch(void) { - if (panic_kernel) crashdump_backup_memory(); + if (panic_kernel) crashdump_backup_memory(); + if (jump_back_entry) x86_setup_jump_back_entry(); +} + +void x86_setup_jump_back_entry() +{ + if (cmdline_end) + sprintf(cmdline_end, " kexec_jump_back_entry=0x%x", + jump_back_entry); } diff --git a/purgatory/arch/i386/setup-x86.S b/purgatory/arch/i386/setup-x86.S index f0719d4..201bb2c 100644 --- a/purgatory/arch/i386/setup-x86.S +++ b/purgatory/arch/i386/setup-x86.S @@ -41,6 +41,9 @@ purgatory_start: ljmp $0x10,$1f 1: + movl 0(%esp), %eax + movl %eax, jump_back_entry + /* Setup a stack */ movl $lstack_end, %esp diff --git a/purgatory/include/purgatory.h b/purgatory/include/purgatory.h index 79ed5bf..ed50dc4 100644 --- a/purgatory/include/purgatory.h +++ b/purgatory/include/purgatory.h @@ -2,6 +2,7 @@ #define PURGATORY_H void putchar(int ch); +void sprintf(char *buffer, const char *fmt, ...); void printf(const char *fmt, ...); void setup_arch(void); void post_verification_setup_arch(void); diff --git a/purgatory/printf.c b/purgatory/printf.c index 962683d..9a78243 100644 --- a/purgatory/printf.c +++ b/purgatory/printf.c @@ -33,19 +33,23 @@ PRINTF and friends %s - string Note: width specification not supported **************************************************************************/ -void printf(const char *fmt, ...) +void vsprintf(char *buffer, const char *fmt, va_list args) { - va_list args; char *p; - va_start(args, fmt); for ( ; *fmt != '\0'; ++fmt) { if (*fmt != '%') { - putchar(*fmt); + if (buffer) + *buffer++ = *fmt; + else + putchar(*fmt); continue; } if (*++fmt == 's') { for(p = va_arg(args, char *); *p != '\0'; p++) - putchar(*p); + if (buffer) + *buffer++ = *p; + else + putchar(*p); } else { /* Length of item is bounded */ char tmp[40], *q = tmp; @@ -121,8 +125,30 @@ void printf(const char *fmt, ...) *q++ = *fmt; /* now output the saved string */ for (p = tmp; p < q; ++p) - putchar(*p); + if (buffer) + *buffer++ = *p; + else + putchar(*p); } } + if (buffer) + *buffer = '\0'; +} + +void sprintf(char *buffer, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsprintf(buffer, fmt, args); + va_end(args); +} + +void printf(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsprintf(0, fmt, args); va_end(args); } |