summaryrefslogtreecommitdiffstats
path: root/purgatory
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2008-10-29 11:24:25 +0800
committerSimon Horman <horms@verge.net.au>2008-10-31 12:58:16 +1100
commitceb04ae1223ba5cdd40df744aa73a32b2cc7d879 (patch)
tree993024edfe07b9cd7150fb2131175104e4948ad4 /purgatory
parent802a8a5e396e06a514251c44454c982bff3c5073 (diff)
downloadkexec-tools-ceb04ae1223ba5cdd40df744aa73a32b2cc7d879.tar.gz
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.c14
-rw-r--r--purgatory/arch/i386/setup-x86.S3
-rw-r--r--purgatory/include/purgatory.h1
-rw-r--r--purgatory/printf.c38
4 files changed, 49 insertions, 7 deletions
diff --git a/purgatory/arch/i386/purgatory-x86.c b/purgatory/arch/i386/purgatory-x86.c
index 4d2c5c7d..030b465f 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 f0719d4c..201bb2cb 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 79ed5bfe..ed50dc43 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 962683d6..9a78243d 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);
}