*/
.code16
-#.text
-#.section .ap_boot, "ax", @progbits
.global ap_boot_bgn
.global ap_boot_end
.align 0x1000
movl %ebx, %esp
addl $0x1000, %esp
- # 算出gdt的线性地址
- leal (ap_gdt - ap_realmode_base)(%ebx), %eax
- # 把这个地址填入gdtr的base位置
- movl %eax, (ap_gdtr_base - ap_realmode_base)
-
-
- # 算出ap_code32_entry的线性地址
- leal (ap_code32_entry - ap_realmode_base)(%ebx), %eax
- # 把这个地址填入ap_code32_entry_address
- mov %eax, (ap_code32_entry_address - ap_realmode_base)
-
-
lgdt ap_gdtr - ap_realmode_base
# enable PE
.align 32
-ap_code32_entry_address: .long 0x00000000 # 等待动态写入
+.global ap_code32_entry_address
+ap_code32_entry_address: .long ap_code32_entry - ap_realmode_base # 在BSP复制代码的时候会动态调整
.word 0x0008, 0x0000
+.align 32
+.global ap_gdtr_base
+ap_gdtr:
+ ap_gdtr_limit: .word ap_gdt_end-ap_gdt
+ ap_gdtr_base: .long ap_gdt - ap_realmode_base # 在BSP复制代码的时候会动态调整
+
.align 32
ap_gdt:
empty: .long 0x00000000, 0x00000000
code_desc: .long 0x0000FFFF, 0x00CF9B00
data_desc: .long 0x0000FFFF, 0x00CF9300
+pad0: .long 0x00000000, 0x00000000
+pad1: .long 0x00000000, 0x00000000
+pad2: .long 0x00000000, 0x00000000
ap_gdt_end:
-ap_gdtr:
- ap_gdtr_limit: .word ap_gdt_end-ap_gdt
- ap_gdtr_base: .long 0 # 等待动态写入
ap_boot_end:
extern char ap_boot_bgn;
extern char ap_boot_end;
uint32_t bytes = &ap_boot_end - &ap_boot_bgn;
- // memcpy((void*)paddr, &ap_boot_bgn, bytes);
+
for(int i=0; i<bytes; i++) {
((uint8_t*)paddr)[i] = ((uint8_t*)&ap_boot_bgn)[i];
}
+
+ // 修正代码里跳入保护模式的地址和gdtr里的gdt的base地址
+ extern uint8_t ap_code32_entry_address;
+ extern uint8_t ap_gdtr_base;
+
+ uint32_t *dst = 0;
+
+ //
+ dst = (uint32_t *)(paddr + (uint32_t)(&ap_code32_entry_address) - (uint32_t)(&ap_boot_bgn));
+ (*dst) += (paddr - KERNEL_VADDR_BASE);
+
+ //
+ dst = (uint32_t *)(paddr + (uint32_t)(&ap_gdtr_base) - (uint32_t)(&ap_boot_bgn));
+ (*dst) += (paddr - KERNEL_VADDR_BASE);
}
void wakeup_ap(paddr_t paddr) {