diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/head_32.S | 44 |
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 |
81 | ENTRY(startup_32) | 81 | ENTRY(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 | 94 | 1: 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 |
100 | 2: | ||
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 |
129 | 1: | 137 | 1: |
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 | |||
153 | bad_subarch: | ||
154 | WEAK(lguest_entry) | ||
155 | WEAK(xen_entry) | ||
156 | /* Unknown implementation; there's really | ||
157 | nothing we can do at this point. */ | ||
158 | ud2a | ||
159 | .data | ||
160 | subarch_entries: | ||
161 | .long default_entry /* normal x86/PC */ | ||
162 | .long lguest_entry /* lguest hypervisor */ | ||
163 | .long xen_entry /* Xen hypervisor */ | ||
164 | num_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 | */ |
141 | page_pde_offset = (__PAGE_OFFSET >> 20); | 178 | page_pde_offset = (__PAGE_OFFSET >> 20); |
142 | 179 | ||
180 | default_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 */ |