我正在向我的内核添加SMP,其中AP应该启动。它以实时模式启动,并在进入保护模式时出现故障。要清楚,它在JMP 0x8上出现故障:......加载CR0后。我确信AP正在获取其代码,因为在它之间的任何地方循环可以防止出现故障。将代码区域APBoot-APBootSequenceEnd复制到9 * 64KB的物理内存位置。我已经尝试了多种方法对其进行编码,并在代码中的注释中提供 -
; +============================================================================ =
; File: APBoot.asm
; =
; Summary: This file contains the code for initializing APs (application processors)
; on a SMP system.
;
; The code is copyed to 9*64*1024 before sending INIT-SIPI-SIPI
;
; Copyright (C) 2017 - Shukant Pal
;=============================================================================+
global APBoot
global apSetupInfo
global APBootSequenceStart
[bits 16]
SECTION .TEXT
ALIGN 4
APBoot: ; Page-aligned Booting File (copyed and filled by PROCESSOR_SETUP_INFO.BootManager)
XOR EAX, EAX
MOV AX, CS ; Load CS into AX
MOV DS, AX ; Copy CS into DS
CLI
MOV ES, AX ; Copy CS into ES
MOV GS, AX ; Copy CS into GS
MOV FS, AX ; Copy CS into FS
XOR EAX, EAX
MOV AX, CS
SHL EAX, 4
ADD EAX, defaultBootGDTPointer-APBoot
LGDT [EAX] ; Even LGDT [9*64*1024+defaultBootGDTPointer-APBoot] doesn't work (why?)
MOV EAX, CR0 ; Load CR0 into EDX
OR AL, 0x1 ; Set PM-bit in EDX
MOV CR0, EAX ; Enable Protected-Mode
;[bits 32]; Even if I turn this off, still triple-faults
JMP 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot) ; Triple Fault
ALIGN 4
apSetupInfo: ; (ALIGNED) PROCESSOR_SETUP_INFO
apBootManager: DD 0x00000000 ; PROCESSOR_SETUP_INFO.BootManager
apBootAddress: DD 0x00000000 ; PROCESSOR_SETUP_INFO.BootAddress
apBootStack: DD 0x00000000 ; PROCESSOR_SETUP_INFO.BootStack
apStatus: DD 0x00000002 ; PROCESSOR_SETUP_INFO.StatusCounter
apErrorReg: DD 0xE0000000 ; PROCESSOR_SETUP_INFO.ErrorRegister (equ AP_NO_BOOT_ERR)
apErrorReg1: DD 0
apErrorReg2: DD 0
apErrorReg4: DD 0
defaultBootGDT: ; PROCESSOR_SETUP_INFO.DefaultBootGDT
defaultBootGDTStart:
DQ 0x0000000000000000 ; NULL GDT_ENTRY
; GDT_ENTRY - KernelCode
DW 0xFFFF ; KernelCode.Limit
DW 0x0000 ; KernelCode.BaseLow
DB 0x00 ; KernelCode.BaseMiddle
DB 0x9A ; KernelCode.Access
DB 0xCF ; KernelCode.Granularity
DB 0x00 ; KernelCode.BaseHigh
; GDT_ENTRY - KernelData
DW 0xFFFF ; KernelData.Limit
DW 0x0000 ; KernelData.BaseLow
DB 0x00 ; KernelData.BaseMiddle
DB 0x92 ; KernelData.Access
DB 0xCF ; KernelData.Granularity
DB 0x00 ; KernelCode.BaseHigh
DQ 0
DQ 0
defaultBootGDTEnd:
defaultBootGDTPointer: ; PROCESSOR_SETUP_INFO.DefaultBootGDTPointer
DW 23 ; defaultBootGDTPointer.Limit (loaded at Runtime)
DD (9*64*1024+defaultBootGDT-APBoot) ; defaultBootGDTPointer.Base (loaded at Runtime)
APBootSequenceStart:
ALIGN 4
[bits 32]
InitSoftwareEnvironment:
JMP $
MOV AX, 0x10
MOV DS, AX
MOV GS, AX
MOV ES, AX
MOV FS, AX
MOV SS, AX
; MOV EBX, 632 * 1024 + apStatus - APBoot
; MOV DWORD [EBX], 0x1
; MOV DWORD [0xB8000], 0xFFFFFFFF
JMP $
global APBootSequenceEnd
APBootSequenceEnd:
答案 0 :(得分:2)
我找到了问题的答案。 NASM汇编程序没有警告我需要的地址覆盖。地址(9 * 64 * 1024 + InitSoftwareEnvironment)溢出16位数据大小。所以,我需要使用地址覆盖选项 - 通过更改
JMP 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot)
到
JMP DWORD 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot)