aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/boot/head.S
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-06-11 15:15:28 +0100
committerJan Beulich <jbeulich@suse.com>2012-06-11 15:15:28 +0100
commit46fce9fd2b3557c97e6ce9beec9ed17ad87d6f94 (patch)
tree65e982332204cd38bd19dbef11cdd82e2db42c2b /xen/arch/x86/boot/head.S
parent035a14476e384494a9c70139dd1747d6e9fd448e (diff)
downloadxen-46fce9fd2b3557c97e6ce9beec9ed17ad87d6f94.tar.gz
xen-46fce9fd2b3557c97e6ce9beec9ed17ad87d6f94.tar.bz2
xen-46fce9fd2b3557c97e6ce9beec9ed17ad87d6f94.zip
x86: get rid of BOOT_TRAMPOLINE
We recently saw a machine that has the EBDA extending as low as 0x7c000, so that Xen fails to boot after relocating the trampoline. To fix this, I removed BOOT_TRAMPOLINE and bootsym_phys completely. Here are the parts: 1) the trampoline segment is set to 64k below the EBDA. head.S grows the ability to relocate the trampoline segment 2) reloc.c is made position-independent. It allocates data below the trampoline, whose address is passed in _eax. 3) cmdline.S is called before relocating, so all bootsym_phys there become sym_phys. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> jb: - fall back to low memory size (instead of segment 0x7c00) if EBDA value is out of range - also add upper limit check on EBDA value - fix and simplify inline assembly operands in reloc_mbi_struct() - use lret instead of retf - renamed early_stack to wakeup_stack, defined and used now only in wakeup.S - aligned reloc.bin's end of .text to 16 bytes, so that checking __bss_start == end works reliably Signed-off-by: Jan Beulich <jbeulich@suse.com> Committed-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/boot/head.S')
-rw-r--r--xen/arch/x86/boot/head.S48
1 files changed, 38 insertions, 10 deletions
diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index d92ce64b44..47b9861c4f 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -9,9 +9,7 @@
.text
.code32
-#define BOOT_TRAMPOLINE 0x7c000
#define sym_phys(sym) ((sym) - __XEN_VIRT_START)
-#define bootsym_phys(sym) ((sym) - trampoline_start + BOOT_TRAMPOLINE)
#define BOOT_CS32 0x0008
#define BOOT_CS64 0x0010
@@ -79,6 +77,23 @@ __start:
cmp $0x2BADB002,%eax
jne not_multiboot
+ /* Set up trampoline segment 64k below EBDA */
+ movzwl 0x40e,%eax /* EBDA segment */
+ cmp $0xa000,%eax /* sanity check (high) */
+ jae 0f
+ cmp $0x4000,%eax /* sanity check (low) */
+ jae 1f
+0:
+ movzwl 0x413,%eax /* use base memory size on failure */
+ shl $10-4,%eax
+1:
+ sub $0x1000,%eax
+
+ /* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
+ xor %al, %al
+ shl $4, %eax
+ mov %eax,sym_phys(trampoline_phys)
+
/* Save the Multiboot info struct (after relocation) for later use. */
mov $sym_phys(cpu0_stack)+1024,%esp
push %ebx
@@ -190,7 +205,7 @@ __start:
#endif
/* Apply relocations to bootstrap trampoline. */
- mov $BOOT_TRAMPOLINE,%edx
+ mov sym_phys(trampoline_phys),%edx
mov $sym_phys(__trampoline_rel_start),%edi
mov %edx,sym_phys(trampoline_phys)
1:
@@ -200,22 +215,35 @@ __start:
cmp $sym_phys(__trampoline_rel_stop),%edi
jb 1b
+ /* Patch in the trampoline segment. */
+ shr $4,%edx
+ mov $sym_phys(__trampoline_seg_start),%edi
+1:
+ mov (%edi),%eax
+ mov %dx,(%edi,%eax)
+ add $4,%edi
+ cmp $sym_phys(__trampoline_seg_stop),%edi
+ jb 1b
+
+ call cmdline_parse_early
+
+ /* Switch to low-memory stack. */
+ mov sym_phys(trampoline_phys),%edi
+ lea 0x10000(%edi),%esp
+ lea trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
+ pushl $BOOT_CS32
+ push %eax
+
/* Copy bootstrap trampoline to low memory, below 1MB. */
mov $sym_phys(trampoline_start),%esi
- mov %edx,%edi
mov $trampoline_end - trampoline_start,%ecx
rep movsb
- lea early_stack-trampoline_start(%edx),%esp
- call cmdline_parse_early
-
/* Jump into the relocated trampoline. */
- jmp $BOOT_CS32,$bootsym_phys(trampoline_boot_cpu_entry)
+ lret
#include "cmdline.S"
-#undef bootsym_phys
-
reloc:
#include "reloc.S"