Assembly 这个hvmloader.c引导加载程序代码是做什么的?
我阅读了xen的代码,找到了下面的代码。但我不知道这是什么意思。是该代码初始化了Assembly 这个hvmloader.c引导加载程序代码是做什么的?,assembly,x86,bootloader,real-mode,Assembly,X86,Bootloader,Real Mode,我阅读了xen的代码,找到了下面的代码。但我不知道这是什么意思。是该代码初始化了idt和gdt?是从实际模式跳到保护模式的代码吗?如果是,则gdt和idt的物理地址在哪里? Hvmloader.c: asm ( " .text \n" " .globl _start \n" "_start: \n" /* C runtime kick
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"
);
谢谢。从代码开始:
cld
-清除方向标志
cli
-清除中断标志以屏蔽中断
lgdt gdt_desr
-将gdt_desr
的值加载到gdt
中。在源代码中查找gdt\u 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
,然后从ax
存储到ds
,es
,fs
,gs
和ss
(存储到除cs
以外的所有段寄存器)
跳远/跳远到STR(SEL\u CODE32):0x1f
,实际上将cs
设置为STR(SEL\u CODE32)
,并将eip
设置为0x1f
如果这是32位代码段,处理器将进入32位保护模式。看见但是,我在这里没有看到用于设置cr0
寄存器的PE
位的代码,如上述示例和中所示
在那行代码之后,cs:eip
移动到该地址(STR(SEL_CODE32):0x1f
),这段代码中没有显示,所以我不能说接下来会发生什么。如果cs:eip
指向下一行(如果这是跳转地址),则它也可能在下一行继续。无论如何,其余的代码和注释看起来像是用于从保护模式切换回真实模式的代码
指令
lidt 1f-trampoline\u start
将1f-trampoline\u start
的值加载到idt
中,以便了解实际使用的值,搜索源代码以查找if-trampoline\u start
在我看来,大多数工作都是将CPU设置回实模式以跳转到BIOS重启地址(实模式内存结束前16个字节=0xFFFF0)。实际工作在main中完成,大约三分之一的时间调用main。至于其余细节,我将把它留给了解此类内容的人。对于感兴趣的人,这里是Xen的源文件,其中包含以下代码:
" ljmp $"STR(SEL_CODE32)",$1f \n"