Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
| 3 | * Trampoline.S Derived from Setup.S by Linus Torvalds |
| 4 | * |
| 5 | * 4 Jan 1997 Michael Chastain: changed to gnu as. |
| 6 | * |
| 7 | * Entry: CS:IP point to the start of our code, we are |
| 8 | * in real mode with no stack, but the rest of the |
| 9 | * trampoline page to make our stack and everything else |
| 10 | * is a mystery. |
| 11 | * |
| 12 | * In fact we don't actually need a stack so we don't |
| 13 | * set one up. |
| 14 | * |
| 15 | * On entry to trampoline_data, the processor is in real mode |
| 16 | * with 16-bit addressing and 16-bit data. CS has some value |
| 17 | * and IP is zero. Thus, data addresses need to be absolute |
| 18 | * (no relocation) and are taken with regard to r_base. |
| 19 | * |
| 20 | * If you work on this file, check the object module with objdump |
| 21 | * --full-contents --reloc to make sure there are no relocation |
| 22 | * entries. For the GDT entry we do hand relocation in smpboot.c |
| 23 | * because of 64bit linker limitations. |
| 24 | */ |
| 25 | |
| 26 | #include <linux/linkage.h> |
| 27 | #include <asm/segment.h> |
| 28 | #include <asm/page.h> |
| 29 | |
| 30 | .data |
| 31 | |
| 32 | .code16 |
| 33 | |
| 34 | ENTRY(trampoline_data) |
| 35 | r_base = . |
| 36 | wbinvd |
| 37 | mov %cs, %ax # Code and data in the same place |
| 38 | mov %ax, %ds |
| 39 | |
| 40 | cli # We should be safe anyway |
| 41 | |
| 42 | movl $0xA5A5A5A5, trampoline_data - r_base |
| 43 | # write marker for master knows we're running |
| 44 | |
| 45 | lidt idt_48 - r_base # load idt with 0, 0 |
| 46 | lgdt gdt_48 - r_base # load gdt with whatever is appropriate |
| 47 | |
| 48 | xor %ax, %ax |
| 49 | inc %ax # protected mode (PE) bit |
| 50 | lmsw %ax # into protected mode |
| 51 | # flaush prefetch and jump to startup_32 in arch/x86_64/kernel/head.S |
| 52 | ljmpl $__KERNEL32_CS, $(startup_32-__START_KERNEL_map) |
| 53 | |
| 54 | # Careful these need to be in the same 64K segment as the above; |
| 55 | idt_48: |
| 56 | .word 0 # idt limit = 0 |
| 57 | .word 0, 0 # idt base = 0L |
| 58 | |
| 59 | gdt_48: |
| 60 | .short __KERNEL32_CS + 7 # gdt limit |
| 61 | .long cpu_gdt_table-__START_KERNEL_map |
| 62 | |
| 63 | .globl trampoline_end |
| 64 | trampoline_end: |