Commit a24e7851 authored by Rusty Russell's avatar Rusty Russell Committed by Linus Torvalds

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: default avatarJeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Acked-by: default avatarH. 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 214541d1
...@@ -27,13 +27,22 @@ ...@@ -27,13 +27,22 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/boot.h> #include <asm/boot.h>
#include <asm/asm-offsets.h>
.section ".text.head","ax",@progbits .section ".text.head","ax",@progbits
.globl startup_32 .globl startup_32
startup_32: startup_32:
cld /* check to see if KEEP_SEGMENTS flag is meaningful */
cli cmpw $0x207, BP_version(%esi)
jb 1f
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
* us to not reload segments */
testb $(1<<6), BP_loadflags(%esi)
jnz 2f
1: cli
movl $(__BOOT_DS),%eax movl $(__BOOT_DS),%eax
movl %eax,%ds movl %eax,%ds
movl %eax,%es movl %eax,%es
...@@ -41,6 +50,8 @@ startup_32: ...@@ -41,6 +50,8 @@ startup_32:
movl %eax,%gs movl %eax,%gs
movl %eax,%ss movl %eax,%ss
2: cld
/* Calculate the delta between where we were compiled to run /* Calculate the delta between where we were compiled to run
* at and where we were actually loaded at. This can only be done * at and where we were actually loaded at. This can only be done
* with a short local call on x86. Nothing else will tell us what * with a short local call on x86. Nothing else will tell us what
......
...@@ -247,6 +247,9 @@ static void putstr(const char *s) ...@@ -247,6 +247,9 @@ static void putstr(const char *s)
int x,y,pos; int x,y,pos;
char c; char c;
if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
return;
x = RM_SCREEN_INFO.orig_x; x = RM_SCREEN_INFO.orig_x;
y = RM_SCREEN_INFO.orig_y; y = RM_SCREEN_INFO.orig_y;
......
...@@ -119,7 +119,7 @@ _start: ...@@ -119,7 +119,7 @@ _start:
# Part 2 of the header, from the old setup.S # Part 2 of the header, from the old setup.S
.ascii "HdrS" # header signature .ascii "HdrS" # header signature
.word 0x0206 # header version number (>= 0x0105) .word 0x0207 # header version number (>= 0x0105)
# or else old loadlin-1.5 will fail) # or else old loadlin-1.5 will fail)
.globl realmode_swtch .globl realmode_swtch
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
...@@ -214,6 +214,11 @@ cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, ...@@ -214,6 +214,11 @@ cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
#added with boot protocol #added with boot protocol
#version 2.06 #version 2.06
hardware_subarch: .long 0 # subarchitecture, added with 2.07
# default to 0 for normal x86 PC
hardware_subarch_data: .quad 0
# End of setup header ##################################################### # End of setup header #####################################################
.section ".inittext", "ax" .section ".inittext", "ax"
......
...@@ -79,22 +79,30 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_ ...@@ -79,22 +79,30 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_
*/ */
.section .text.head,"ax",@progbits .section .text.head,"ax",@progbits
ENTRY(startup_32) ENTRY(startup_32)
/* check to see if KEEP_SEGMENTS flag is meaningful */
cmpw $0x207, BP_version(%esi)
jb 1f
/* test KEEP_SEGMENTS flag to see if the bootloader is asking
us to not reload segments */
testb $(1<<6), BP_loadflags(%esi)
jnz 2f
/* /*
* Set segments to known values. * Set segments to known values.
*/ */
cld 1: lgdt boot_gdt_descr - __PAGE_OFFSET
lgdt boot_gdt_descr - __PAGE_OFFSET
movl $(__BOOT_DS),%eax movl $(__BOOT_DS),%eax
movl %eax,%ds movl %eax,%ds
movl %eax,%es movl %eax,%es
movl %eax,%fs movl %eax,%fs
movl %eax,%gs movl %eax,%gs
2:
/* /*
* Clear BSS first so that there are no surprises... * Clear BSS first so that there are no surprises...
* No need to cld as DF is already clear from cld above...
*/ */
cld
xorl %eax,%eax xorl %eax,%eax
movl $__bss_start - __PAGE_OFFSET,%edi movl $__bss_start - __PAGE_OFFSET,%edi
movl $__bss_stop - __PAGE_OFFSET,%ecx movl $__bss_stop - __PAGE_OFFSET,%ecx
...@@ -128,6 +136,35 @@ ENTRY(startup_32) ...@@ -128,6 +136,35 @@ ENTRY(startup_32)
movsl movsl
1: 1:
#ifdef CONFIG_PARAVIRT
cmpw $0x207, (boot_params + BP_version - __PAGE_OFFSET)
jb default_entry
/* Paravirt-compatible boot parameters. Look to see what architecture
we're booting under. */
movl (boot_params + BP_hardware_subarch - __PAGE_OFFSET), %eax
cmpl $num_subarch_entries, %eax
jae bad_subarch
movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
subl $__PAGE_OFFSET, %eax
jmp *%eax
bad_subarch:
WEAK(lguest_entry)
WEAK(xen_entry)
/* Unknown implementation; there's really
nothing we can do at this point. */
ud2a
.data
subarch_entries:
.long default_entry /* normal x86/PC */
.long lguest_entry /* lguest hypervisor */
.long xen_entry /* Xen hypervisor */
num_subarch_entries = (. - subarch_entries) / 4
.previous
#endif /* CONFIG_PARAVIRT */
/* /*
* Initialize page tables. This creates a PDE and a set of page * Initialize page tables. This creates a PDE and a set of page
* tables, which are located immediately beyond _end. The variable * tables, which are located immediately beyond _end. The variable
...@@ -140,6 +177,7 @@ ENTRY(startup_32) ...@@ -140,6 +177,7 @@ ENTRY(startup_32)
*/ */
page_pde_offset = (__PAGE_OFFSET >> 20); page_pde_offset = (__PAGE_OFFSET >> 20);
default_entry:
movl $(pg0 - __PAGE_OFFSET), %edi movl $(pg0 - __PAGE_OFFSET), %edi
movl $(swapper_pg_dir - __PAGE_OFFSET), %edx movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment