wakeup.s

来自「xen虚拟机源代码安装包」· S 代码 · 共 197 行

S
197
字号
        .code16#define wakesym(sym) (sym - wakeup_start)        .align 16ENTRY(wakeup_start)        cli        cld        # setup data segment        movw    %cs, %ax        movw    %ax, %ds        movw    %ax, %ss        # A stack required for BIOS call        movw    $wakesym(early_stack), %sp        pushl   $0              # Kill dangerous flag early        popfl        # check magic number        movl    wakesym(real_magic), %eax        cmpl    $0x12345678, %eax        jne     bogus_real_magic        # for acpi_sleep=s3_bios        testl   $1, wakesym(video_flags)        jz      1f        lcall   $0xc000, $3        movw    %cs, %ax        # In case messed by BIOS        movw    %ax, %ds        movw    %ax, %ss        # Need this? How to ret if clobbered?1:      # for acpi_sleep=s3_mode        testl   $2, wakesym(video_flags)        jz      1f        movl    wakesym(video_mode), %eax        call    mode_setw1:      # Show some progress if VGA is resumed        movw    $0xb800, %ax        movw    %ax, %fs        movw    $0x0e00 + 'L', %fs:(0x10)        # boot trampoline is under 1M, and shift its start into        # %fs to reference symbols in that area        movl    $BOOT_TRAMPOLINE, %eax        shrl    $4, %eax        movl    %eax, %fs        lidt    %fs:bootsym(idt_48)        lgdt    %fs:bootsym(gdt_48)        movw    $1, %ax        lmsw    %ax             # Turn on CR0.PE         jmp     1f1:      ljmpl   $BOOT_CS32, $bootsym_phys(wakeup_32)/* This code uses an extended set of video mode numbers. These include: * Aliases for standard modes *      NORMAL_VGA (-1) *      EXTENDED_VGA (-2) *      ASK_VGA (-3) * Video modes numbered by menu position -- NOT RECOMMENDED because of lack * of compatibility when extending the table. These are between 0x00 and 0xff. */#define VIDEO_FIRST_MENU 0x0000/* Standard BIOS video modes (BIOS number + 0x0100) */#define VIDEO_FIRST_BIOS 0x0100/* VESA BIOS video modes (VESA number + 0x0200) */#define VIDEO_FIRST_VESA 0x0200/* Video7 special modes (BIOS number + 0x0900) */#define VIDEO_FIRST_V7 0x0900# Setting of user mode (AX=mode ID) => CF=successmode_setw:        movw    %ax, %bx        cmpb    $VIDEO_FIRST_VESA>>8, %ah        jnc     check_vesaw        decb    %ahsetbadw: clc        retcheck_vesaw:        subb    $VIDEO_FIRST_VESA>>8, %bh        orw     $0x4000, %bx                    # Use linear frame buffer        movw    $0x4f02, %ax                    # VESA BIOS mode set call        int     $0x10        cmpw    $0x004f, %ax                    # AL=4f if implemented        jnz     _setbadw                        # AH=0 if OK        stc        ret_setbadw: jmp    setbadwbogus_real_magic:        movw    $0x0e00 + 'B', %fs:(0x12)        jmp     bogus_real_magic        .align 4real_magic:     .long 0x12345678         .globl video_mode, video_flagsvideo_mode:     .long 0video_flags:    .long 0        .code32        # Now in protect mode, with paging disabled        # Add offset for any reference to xen specific symbolswakeup_32:        mov     $BOOT_DS, %eax        mov     %eax, %ds        mov     %eax, %ss        mov     $bootsym_phys(early_stack), %esp        # check saved magic again        mov     $sym_phys(saved_magic), %eax        add     bootsym_phys(trampoline_xen_phys_start), %eax        mov     (%eax), %eax        cmp     $0x9abcdef0, %eax        jne     bogus_saved_magic                /* fpu init? */        /* Initialise CR4. */        mov     $X86_CR4_PAE, %ecx        mov     %ecx, %cr4        /* Load pagetable base register */        mov     $sym_phys(idle_pg_table),%eax        add     bootsym_phys(trampoline_xen_phys_start),%eax        mov     %eax,%cr3        /* Will cpuid feature change after resume? */        /* Set up EFER (Extended Feature Enable Register). */        mov     bootsym_phys(cpuid_ext_features),%edi        test    $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */        jz      .Lskip_eferw        movl    $MSR_EFER,%ecx        rdmsr#if CONFIG_PAGING_LEVELS == 4        btsl    $_EFER_LME,%eax /* Long Mode      */        btsl    $_EFER_SCE,%eax /* SYSCALL/SYSRET */#endif        btl     $20,%edi        /* No Execute?    */        jnc     1f        btsl    $_EFER_NX,%eax  /* No Execute     */1:      wrmsr.Lskip_eferw:        wbinvd        mov     $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */        mov     %eax,%cr0        jmp     1f1:#if defined(__x86_64__)        /* Now in compatibility mode. Long-jump to 64-bit mode */        ljmp    $BOOT_CS64, $bootsym_phys(wakeup_64)        .code64        .align  8        .word   0,0,0lgdt_descr:        .word   LAST_RESERVED_GDT_BYTE        .quad   gdt_table - FIRST_RESERVED_GDT_BYTE        wakeup_64:        lgdt    lgdt_descr(%rip)        mov     $(__HYPERVISOR_DS64), %eax        mov     %eax, %ds        # long jump to return point, with cs reload        rex64 ljmp    *ret_point(%rip)        .align 8ret_point:        .quad   __ret_point        .word   __HYPERVISOR_CS64#else /* !defined(__x86_64__) */        lgdt    gdt_descr        mov     $(__HYPERVISOR_DS), %eax        mov     %eax, %ds        ljmp    $(__HYPERVISOR_CS), $__ret_point#endifbogus_saved_magic:        movw    $0x0e00 + 'S', 0xb8014        jmp     bogus_saved_magic

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?