aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2007-10-21 19:41:35 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-22 11:13:17 -0400
commita24e785111a32ccb7cebafd24b1b1cb474ea8e5d (patch)
tree63ec9334e60f2b4a50521312a5152071fa339911 /arch/x86/kernel
parent214541d1f30429922727040db3e2e4932ff24f46 (diff)
i386: paravirt boot sequence
This patch uses the updated boot protocol to do paravirtualized boot. If the boot version is >= 2.07, then it will do two things: 1. Check the bootparams loadflags to see if we should reload the segment registers and clear interrupts. This is appropriate for normal native boot and some paravirtualized environments, but inapproprate for others. 2. Check the hardware architecture, and dispatch to the appropriate kernel entrypoint. If the bootloader doesn't set this, then we simply do the normal boot sequence. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Acked-by: H. Peter Anvin <hpa@zytor.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Vivek Goyal <vgoyal@in.ibm.com> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: Zachary Amsden <zach@vmware.com> Cc: Andi Kleen <ak@suse.de> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/head_32.S44
1 files changed, 41 insertions, 3 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 39677965e161..00b1c2c56454 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -79,22 +79,30 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_
79 */ 79 */
80.section .text.head,"ax",@progbits 80.section .text.head,"ax",@progbits
81ENTRY(startup_32) 81ENTRY(startup_32)
82 /* check to see if KEEP_SEGMENTS flag is meaningful */
83 cmpw $0x207, BP_version(%esi)
84 jb 1f
85
86 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
87 us to not reload segments */
88 testb $(1<<6), BP_loadflags(%esi)
89 jnz 2f
82 90
83/* 91/*
84 * Set segments to known values. 92 * Set segments to known values.
85 */ 93 */
86 cld 941: lgdt boot_gdt_descr - __PAGE_OFFSET
87 lgdt boot_gdt_descr - __PAGE_OFFSET
88 movl $(__BOOT_DS),%eax 95 movl $(__BOOT_DS),%eax
89 movl %eax,%ds 96 movl %eax,%ds
90 movl %eax,%es 97 movl %eax,%es
91 movl %eax,%fs 98 movl %eax,%fs
92 movl %eax,%gs 99 movl %eax,%gs
1002:
93 101
94/* 102/*
95 * Clear BSS first so that there are no surprises... 103 * Clear BSS first so that there are no surprises...
96 * No need to cld as DF is already clear from cld above...
97 */ 104 */
105 cld
98 xorl %eax,%eax 106 xorl %eax,%eax
99 movl $__bss_start - __PAGE_OFFSET,%edi 107 movl $__bss_start - __PAGE_OFFSET,%edi
100 movl $__bss_stop - __PAGE_OFFSET,%ecx 108 movl $__bss_stop - __PAGE_OFFSET,%ecx
@@ -128,6 +136,35 @@ ENTRY(startup_32)
128 movsl 136 movsl
1291: 1371:
130 138
139#ifdef CONFIG_PARAVIRT
140 cmpw $0x207, (boot_params + BP_version - __PAGE_OFFSET)
141 jb default_entry
142
143 /* Paravirt-compatible boot parameters. Look to see what architecture
144 we're booting under. */
145 movl (boot_params + BP_hardware_subarch - __PAGE_OFFSET), %eax
146 cmpl $num_subarch_entries, %eax
147 jae bad_subarch
148
149 movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
150 subl $__PAGE_OFFSET, %eax
151 jmp *%eax
152
153bad_subarch:
154WEAK(lguest_entry)
155WEAK(xen_entry)
156 /* Unknown implementation; there's really
157 nothing we can do at this point. */
158 ud2a
159.data
160subarch_entries:
161 .long default_entry /* normal x86/PC */
162 .long lguest_entry /* lguest hypervisor */
163 .long xen_entry /* Xen hypervisor */
164num_subarch_entries = (. - subarch_entries) / 4
165.previous
166#endif /* CONFIG_PARAVIRT */
167
131/* 168/*
132 * Initialize page tables. This creates a PDE and a set of page 169 * Initialize page tables. This creates a PDE and a set of page
133 * tables, which are located immediately beyond _end. The variable 170 * tables, which are located immediately beyond _end. The variable
@@ -140,6 +177,7 @@ ENTRY(startup_32)
140 */ 177 */
141page_pde_offset = (__PAGE_OFFSET >> 20); 178page_pde_offset = (__PAGE_OFFSET >> 20);
142 179
180default_entry:
143 movl $(pg0 - __PAGE_OFFSET), %edi 181 movl $(pg0 - __PAGE_OFFSET), %edi
144 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx 182 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
145 movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ 183 movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */