acrn hypervisor源码分析 - 第三节

  1. 接着第一节的call relocate地方继续,加载cpu_primary32_gdt_ptr地址到rbx寄存器处。cpu_primary32_gdt_ptr内存出前两个字节是GDT的长度,后八个字节是起始地址。然后加载到GDTR寄存器。

GDTR的用处和为什么使用ebx?

	/* Load temportary GDT pointer value */
    lea     cpu_primary32_gdt_ptr(%rip), %rbx
    lgdt    (%ebx)
cpu_primary32_gdt_ptr:
    .short  (cpu_primary32_gdt_end - cpu_primary32_gdt) - 1
    .quad   cpu_primary32_gdt
cpu_primary32_gdt:
    .quad   0x0000000000000000
    .quad   0x00af9b000000ffff
    .quad   0x00cf93000000ffff
cpu_primary32_gdt_end:
  1. 通过将有效地址放在内存中,实现long jump。执行after函数。这里的rex.w是说明使用了64bit的操作数。因为在64位模式下,intel支持64bit的地址和32bit的操作数。如果要使用64bit操作数,可以通过rex.w覆盖。
    /* Set the correct long jump address */
    lea     jmpbuf(%rip), %rax
    lea     after(%rip), %rbx
    mov     %rbx, (%rax)
    rex.w ljmp  *(%rax)
jmpbuf: .quad 0
	/* 0x0008 = HOST_GDT_RING0_CODE_SEL */
        .word 0x0008
  1. 没看懂,就知道最后调用了init_primary_cpu函数
after:
    /* 0x10 = HOST_GDT_RING0_DATA_SEL*/
    movl    $0x10,%eax
    mov     %eax,%ss  // Was 32bit POC Stack
    mov     %eax,%ds  // Was 32bit POC Data
    mov     %eax,%es  // Was 32bit POC Data
    mov     %eax,%fs  // Was 32bit POC Data
    mov     %eax,%gs  // Was 32bit POC CLS

   /* continue with chipset level initialization */
   call     init_primary_cpu

你可能感兴趣的:(汇编,acrn,hypervisor)