linux/arch/i386/kernel/trampoline.S
<<
>>
Prefs
   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 *      This is only used for booting secondary CPUs in SMP machine
   8 *
   9 *      Entry: CS:IP point to the start of our code, we are 
  10 *      in real mode with no stack, but the rest of the 
  11 *      trampoline page to make our stack and everything else
  12 *      is a mystery.
  13 *
  14 *      In fact we don't actually need a stack so we don't
  15 *      set one up.
  16 *
  17 *      We jump into the boot/compressed/head.S code. So you'd
  18 *      better be running a compressed kernel image or you
  19 *      won't get very far.
  20 *
  21 *      On entry to trampoline_data, the processor is in real mode
  22 *      with 16-bit addressing and 16-bit data.  CS has some value
  23 *      and IP is zero.  Thus, data addresses need to be absolute
  24 *      (no relocation) and are taken with regard to r_base.
  25 *
  26 *      If you work on this file, check the object module with
  27 *      objdump --reloc to make sure there are no relocation
  28 *      entries except for:
  29 *
  30 *      TYPE              VALUE
  31 *      R_386_32          startup_32_smp
  32 *      R_386_32          boot_gdt
  33 */
  34
  35#include <linux/linkage.h>
  36#include <asm/segment.h>
  37#include <asm/page.h>
  38
  39.data
  40
  41/* We can free up trampoline after bootup if cpu hotplug is not supported. */
  42#ifndef CONFIG_HOTPLUG_CPU
  43.section ".init.data","aw",@progbits
  44#endif
  45
  46.code16
  47
  48ENTRY(trampoline_data)
  49r_base = .
  50        wbinvd                  # Needed for NUMA-Q should be harmless for others
  51        mov     %cs, %ax        # Code and data in the same place
  52        mov     %ax, %ds
  53
  54        cli                     # We should be safe anyway
  55
  56        movl    $0xA5A5A5A5, trampoline_data - r_base
  57                                # write marker for master knows we're running
  58
  59        /* GDT tables in non default location kernel can be beyond 16MB and
  60         * lgdt will not be able to load the address as in real mode default
  61         * operand size is 16bit. Use lgdtl instead to force operand size
  62         * to 32 bit.
  63         */
  64
  65        lidtl   boot_idt_descr - r_base # load idt with 0, 0
  66        lgdtl   boot_gdt_descr - r_base # load gdt with whatever is appropriate
  67
  68        xor     %ax, %ax
  69        inc     %ax             # protected mode (PE) bit
  70        lmsw    %ax             # into protected mode
  71        # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S
  72        ljmpl   $__BOOT_CS, $(startup_32_smp-__PAGE_OFFSET)
  73
  74        # These need to be in the same 64K segment as the above;
  75        # hence we don't use the boot_gdt_descr defined in head.S
  76boot_gdt_descr:
  77        .word   __BOOT_DS + 7                   # gdt limit
  78        .long   boot_gdt - __PAGE_OFFSET        # gdt base
  79
  80boot_idt_descr:
  81        .word   0                               # idt limit = 0
  82        .long   0                               # idt base = 0L
  83
  84.globl trampoline_end
  85trampoline_end:
  86
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.