我阅读了xen的代码,找到了下面的代码。但我不知道这是什么意思。是初始化idt和gdt的代码吗?是代码从实模式跳转到保护模式吗?如果是,gdt和idt的物理地址在哪里?Hvmloader.c:
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"
);谢谢。
发布于 2013-01-08 18:42:16
从代码的开头开始:
cld -清除方向标志。
" 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中,然后从ax存储到ds、es、fs、gs和ss (存储到除cs之外的所有段寄存器)。
" ljmp $"STR(SEL_CODE32)",$1f \n"对STR(SEL_CODE32):0x1f执行跳远/远跳,实际上将cs设置为STR(SEL_CODE32),将eip设置为0x1f。
如果这是一个32位代码段,处理器将进入32位保护模式。参见Stackoverflow question: bootloader - switching processor to protected mode。但是,我在这里看不到上面示例和Wikipedia article on protected mode中用于设置cr0寄存器的PE位的代码。
在这行代码之后,cs:eip移到了这段代码中没有显示的那个地址(STR(SEL_CODE32):0x1f),所以我不能说接下来会发生什么。如果cs:eip指向下一行(如果那是跳转地址),它也可能在下一行继续。无论如何,其余的代码和注释看起来像是用于从保护模式切换回真实模式的代码。
Intruction lidt 1f-trampoline_start将1f-trampoline_start的值加载到idt中,因此要了解实际使用的值,请搜索if-trampoline_start的源代码。
https://stackoverflow.com/questions/14207629
复制相似问题