diff options
author | Jan Beulich <jbeulich@suse.com> | 2012-06-11 15:15:28 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2012-06-11 15:15:28 +0100 |
commit | 46fce9fd2b3557c97e6ce9beec9ed17ad87d6f94 (patch) | |
tree | 65e982332204cd38bd19dbef11cdd82e2db42c2b /xen/arch/x86/boot/head.S | |
parent | 035a14476e384494a9c70139dd1747d6e9fd448e (diff) | |
download | xen-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.S | 48 |
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" |