aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/x86/boot/compressed/head_32.S15
-rw-r--r--arch/x86/boot/compressed/misc_32.c3
-rw-r--r--arch/x86/boot/header.S7
-rw-r--r--arch/x86/kernel/head_32.S44
4 files changed, 63 insertions, 6 deletions
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index f35ea2237522..a0ae2e7f6cec 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -27,13 +27,22 @@
27#include <asm/segment.h> 27#include <asm/segment.h>
28#include <asm/page.h> 28#include <asm/page.h>
29#include <asm/boot.h> 29#include <asm/boot.h>
30#include <asm/asm-offsets.h>
30 31
31.section ".text.head","ax",@progbits 32.section ".text.head","ax",@progbits
32 .globl startup_32 33 .globl startup_32
33 34
34startup_32: 35startup_32:
35 cld 36 /* check to see if KEEP_SEGMENTS flag is meaningful */
36 cli 37 cmpw $0x207, BP_version(%esi)
38 jb 1f
39
40 /* test KEEP_SEGMENTS flag to see if the bootloader is asking
41 * us to not reload segments */
42 testb $(1<<6), BP_loadflags(%esi)
43 jnz 2f
44
451: cli
37 movl $(__BOOT_DS),%eax 46 movl $(__BOOT_DS),%eax
38 movl %eax,%ds 47 movl %eax,%ds
39 movl %eax,%es 48 movl %eax,%es
@@ -41,6 +50,8 @@ startup_32:
41 movl %eax,%gs 50 movl %eax,%gs
42 movl %eax,%ss 51 movl %eax,%ss
43 52
532: cld
54
44/* Calculate the delta between where we were compiled to run 55/* Calculate the delta between where we were compiled to run
45 * at and where we were actually loaded at. This can only be done 56 * at and where we were actually loaded at. This can only be done
46 * with a short local call on x86. Nothing else will tell us what 57 * with a short local call on x86. Nothing else will tell us what
diff --git a/arch/x86/boot/compressed/misc_32.c b/arch/x86/boot/compressed/misc_32.c
index 1dc1e19c0a9f..b74d60d1b2fa 100644
--- a/arch/x86/boot/compressed/misc_32.c
+++ b/arch/x86/boot/compressed/misc_32.c
@@ -247,6 +247,9 @@ static void putstr(const char *s)
247 int x,y,pos; 247 int x,y,pos;
248 char c; 248 char c;
249 249
250 if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
251 return;
252
250 x = RM_SCREEN_INFO.orig_x; 253 x = RM_SCREEN_INFO.orig_x;
251 y = RM_SCREEN_INFO.orig_y; 254 y = RM_SCREEN_INFO.orig_y;
252 255
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index f3140e596d40..8353c81c41c0 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -119,7 +119,7 @@ _start:
119 # Part 2 of the header, from the old setup.S 119 # Part 2 of the header, from the old setup.S
120 120
121 .ascii "HdrS" # header signature 121 .ascii "HdrS" # header signature
122 .word 0x0206 # header version number (>= 0x0105) 122 .word 0x0207 # header version number (>= 0x0105)
123 # or else old loadlin-1.5 will fail) 123 # or else old loadlin-1.5 will fail)
124 .globl realmode_swtch 124 .globl realmode_swtch
125realmode_swtch: .word 0, 0 # default_switch, SETUPSEG 125realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
@@ -214,6 +214,11 @@ cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
214 #added with boot protocol 214 #added with boot protocol
215 #version 2.06 215 #version 2.06
216 216
217hardware_subarch: .long 0 # subarchitecture, added with 2.07
218 # default to 0 for normal x86 PC
219
220hardware_subarch_data: .quad 0
221
217# End of setup header ##################################################### 222# End of setup header #####################################################
218 223
219 .section ".inittext", "ax" 224 .section ".inittext", "ax"
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 */