2013-01-08 55 views
2

我讀了xen的代碼並找到下面的代碼。但我不知道它的意義。它是初始化idtgdt的代碼嗎?它是從實模式跳轉到保護模式的代碼嗎?如果是,那麼gdtidt的物理地址在哪裏? Hvmloader.c:這個hvmloader.c bootloader代碼是做什麼的?

asm (
    " .text      \n" 
    " .globl _start    \n" 
    "_start:       \n" 
    /* C runtime kickoff. */ 
    " cld       \n" 
    " cli       \n" 
    " lgdt gdt_desr    \n" 
    " mov $"STR(SEL_DATA32)",%ax \n" 
    " mov %ax,%ds    \n" 
    " mov %ax,%es    \n" 
    " mov %ax,%fs    \n" 
    " mov %ax,%gs    \n" 
    " mov %ax,%ss    \n" 
    " ljmp $"STR(SEL_CODE32)",$1f \n" 
    "1: movl $stack_top,%esp  \n" 
    " movl %esp,%ebp    \n" 
    " call main     \n" 
    /* Relocate real-mode trampoline to 0x0. */ 
    " mov $trampoline_start,%esi \n" 
    " xor %edi,%edi    \n" 
    " mov $trampoline_end,%ecx \n" 
    " sub %esi,%ecx    \n" 
    " rep movsb     \n" 
    /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */ 
    " mov $"STR(SEL_DATA16)",%ax \n" 
    " mov %ax,%ds    \n" 
    " mov %ax,%es    \n" 
    " mov %ax,%fs    \n" 
    " mov %ax,%gs    \n" 
    " mov %ax,%ss    \n" 
    /* Initialise all 32-bit GPRs to zero. */ 
    " xor %eax,%eax    \n" 
    " xor %ebx,%ebx    \n" 
    " xor %ecx,%ecx    \n" 
    " xor %edx,%edx    \n" 
    " xor %esp,%esp    \n" 
    " xor %ebp,%ebp    \n" 
    " xor %esi,%esi    \n" 
    " xor %edi,%edi    \n" 
    /* Enter real mode, reload all segment registers and IDT. */ 
    " ljmp $"STR(SEL_CODE16)",$0x0\n" 
    "trampoline_start: .code16  \n" 
    " mov %eax,%cr0    \n" 
    " ljmp $0,$1f-trampoline_start\n" 
    "1: mov %ax,%ds    \n" 
    " mov %ax,%es    \n" 
    " mov %ax,%fs    \n" 
    " mov %ax,%gs    \n" 
    " mov %ax,%ss    \n" 
    " lidt 1f-trampoline_start \n" 
    " ljmp $0xf000,$0xfff0  \n" 
    "1: .word 0x3ff,0,0    \n" 
    "trampoline_end: .code32  \n" 
    "        \n" 
    "gdt_desr:      \n" 
    " .word gdt_end - gdt - 1  \n" 
    " .long gdt     \n" 
    "        \n" 
    " .align 8     \n" 
    "gdt:       \n" 
    " .quad 0x0000000000000000 \n" 
    " .quad 0x008f9a000000ffff \n" /* Ring 0 16b code, base 0 limit 4G */ 
    " .quad 0x008f92000000ffff \n" /* Ring 0 16b data, base 0 limit 4G */ 
    " .quad 0x00cf9a000000ffff \n" /* Ring 0 32b code, base 0 limit 4G */ 
    " .quad 0x00cf92000000ffff \n" /* Ring 0 32b data, base 0 limit 4G */ 
    " .quad 0x00af9a000000ffff \n" /* Ring 0 64b code */ 
    "gdt_end:      \n" 
    "        \n" 
    " .bss      \n" 
    " .align 8     \n" 
    "stack:       \n" 
    " .skip 0x4000    \n" 
    "stack_top:      \n" 
    " .text      \n" 
    ); 

謝謝。

+0

在我看來,大部分工作是將CPU設置回實模式,以跳轉到BIOS重啓地址(實模式存儲器結束前的16個字節= 0xFFFF0)。真正的工作主要是完成的,這是大約三分之一的時間。至於其他細節,我會留給那些知道這種東西的人。 – siride

+0

對於那些有興趣的人,這裏是來自Xen的源代碼文件,其中包含以下代碼:http://svn.openfoundry.org/xenids/xen-4.0.0/tools/firmware/hvmloader/hvmloader.c – siride

回答

1

從代碼的開頭:

cld - 明確方向標誌。

cli - 清除中斷標誌來屏蔽中斷。

lgdt gdt_desr - 將gdt_desr的值加載到gdt中。在源代碼中查找gdt_desr以查找加載到gdt的值。

" mov $"STR(SEL_DATA32)",%ax \n" 
" mov %ax,%ds    \n" 
" mov %ax,%es    \n" 
" mov %ax,%fs    \n" 
" mov %ax,%gs    \n" 
" mov %ax,%ss    \n" 

存儲該值STR(SEL_DATA32)ax,然後從axdsesfsgsss(所有段寄存器除了cs)。

" ljmp $"STR(SEL_CODE32)",$1f \n" 

做了跳遠/遠跳轉至STR(SEL_CODE32):0x1f,切實將csSTR(SEL_CODE32)eip0x1f

如果這是一個32位代碼段,則處理器進入32位保護模式。見Stackoverflow question: bootloader - switching processor to protected mode。但是,在這裏我沒有看到用於設置PEcr0寄存器的代碼,如上例和Wikipedia article on protected mode所示。

之後,代碼行cs:eip移動到該地址(STR(SEL_CODE32):0x1f)沒有顯示在這段代碼,所以我不能說那會發生什麼。如果cs:eip指向那裏(如果這是跳轉地址),它也可能繼續下一行。無論如何,代碼和註釋的其餘部分看起來像用於從保護模式切換回實模式的代碼。

Intruction lidt 1f-trampoline_start1f-trampoline_start的值加載到idt中,因此要了解實際使用的值,請搜索源if-trampoline_start

+0

謝謝,這就是我想要的是。 – Jimmy