diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-21 21:03:36 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2007-10-23 01:49:54 -0400 |
commit | 47436aa4ad054c1c7c8231618e86ebd9305308dc (patch) | |
tree | a9ba6e0521f9116442144a86e781a3164ec86094 /arch/x86/lguest/i386_head.S | |
parent | c18acd73ffc209def08003a1927473096f66c5ad (diff) |
Boot with virtual == physical to get closer to native Linux.
1) This allows us to get alot closer to booting bzImages.
2) It means we don't have to know page_offset.
3) The Guest needs to modify the boot pagetables to create the
PAGE_OFFSET mapping before jumping to C code.
4) guest_pa() walks the page tables rather than using page_offset.
5) We don't use page_offset to figure out whether to emulate: it was
always kinda quesationable, and won't work for instructions done
before remapping (bzImage unpacking in particular).
6) We still want the kernel address for tlb flushing: have the initial
hypercall give us that, too.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'arch/x86/lguest/i386_head.S')
-rw-r--r-- | arch/x86/lguest/i386_head.S | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index 6d7a74f07c41..ba4282eba5bf 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/linkage.h> | 1 | #include <linux/linkage.h> |
2 | #include <linux/lguest.h> | 2 | #include <linux/lguest.h> |
3 | #include <asm/lguest_hcall.h> | ||
3 | #include <asm/asm-offsets.h> | 4 | #include <asm/asm-offsets.h> |
4 | #include <asm/thread_info.h> | 5 | #include <asm/thread_info.h> |
5 | #include <asm/processor-flags.h> | 6 | #include <asm/processor-flags.h> |
@@ -8,18 +9,48 @@ | |||
8 | * looks for. The plan is that the Linux boot protocol will be extended with a | 9 | * looks for. The plan is that the Linux boot protocol will be extended with a |
9 | * "platform type" field which will guide us here from the normal entry point, | 10 | * "platform type" field which will guide us here from the normal entry point, |
10 | * but for the moment this suffices. The normal boot code uses %esi for the | 11 | * but for the moment this suffices. The normal boot code uses %esi for the |
11 | * boot header, so we do too. We convert it to a virtual address by adding | 12 | * boot header, so we do too. |
12 | * PAGE_OFFSET, and hand it to lguest_init() as its argument (ie. %eax). | 13 | * |
14 | * WARNING: be very careful here! We're running at addresses equal to physical | ||
15 | * addesses (around 0), not above PAGE_OFFSET as most code expectes | ||
16 | * (eg. 0xC0000000). Jumps are relative, so they're OK, but we can't touch any | ||
17 | * data. | ||
13 | * | 18 | * |
14 | * The .section line puts this code in .init.text so it will be discarded after | 19 | * The .section line puts this code in .init.text so it will be discarded after |
15 | * boot. */ | 20 | * boot. */ |
16 | .section .init.text, "ax", @progbits | 21 | .section .init.text, "ax", @progbits |
17 | .ascii "GenuineLguest" | 22 | .ascii "GenuineLguest" |
18 | /* Set up initial stack. */ | 23 | /* Make initial hypercall now, so we can set up the pagetables. */ |
19 | movl $(init_thread_union+THREAD_SIZE),%esp | 24 | movl $LHCALL_LGUEST_INIT, %eax |
25 | movl $lguest_data - __PAGE_OFFSET, %edx | ||
26 | int $LGUEST_TRAP_ENTRY | ||
27 | |||
28 | /* Set up boot information pointer to hand to lguest_init(): it wants | ||
29 | * a virtual address. */ | ||
20 | movl %esi, %eax | 30 | movl %esi, %eax |
21 | addl $__PAGE_OFFSET, %eax | 31 | addl $__PAGE_OFFSET, %eax |
22 | jmp lguest_init | 32 | |
33 | /* The Host put the toplevel pagetable in lguest_data.pgdir. The movsl | ||
34 | * instruction uses %esi, so we needed to save it above. */ | ||
35 | movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi | ||
36 | |||
37 | /* Copy first 32 entries of page directory to __PAGE_OFFSET entries. | ||
38 | * This means the first 128M of kernel memory will be mapped at | ||
39 | * PAGE_OFFSET where the kernel expects to run. This will get it far | ||
40 | * enough through boot to switch to its own pagetables. */ | ||
41 | movl $32, %ecx | ||
42 | movl %esi, %edi | ||
43 | addl $((__PAGE_OFFSET >> 22) * 4), %edi | ||
44 | rep | ||
45 | movsl | ||
46 | |||
47 | /* Set up the initial stack so we can run C code. */ | ||
48 | movl $(init_thread_union+THREAD_SIZE),%esp | ||
49 | |||
50 | |||
51 | /* Jumps are relative, and we're running __PAGE_OFFSET too low at the | ||
52 | * moment. */ | ||
53 | jmp lguest_init+__PAGE_OFFSET | ||
23 | 54 | ||
24 | /*G:055 We create a macro which puts the assembler code between lgstart_ and | 55 | /*G:055 We create a macro which puts the assembler code between lgstart_ and |
25 | * lgend_ markers. These templates are put in the .text section: they can't be | 56 | * lgend_ markers. These templates are put in the .text section: they can't be |