进入保护模式:三重故障
Entering Protected Mode: Triple-Fault
我正在将 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:
我找到了问题的答案。 NASM 汇编程序没有警告我需要覆盖地址。地址(9*64*1024+InitSoftwareEnvironment)溢出16位数据大小。所以,我需要使用地址覆盖选项 - 通过更改
JMP 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot)
至
JMP DWORD 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot)
我正在将 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:
我找到了问题的答案。 NASM 汇编程序没有警告我需要覆盖地址。地址(9*64*1024+InitSoftwareEnvironment)溢出16位数据大小。所以,我需要使用地址覆盖选项 - 通过更改
JMP 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot)
至
JMP DWORD 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot)