输入保护模式:三重故障



我将SMP添加到我的内核中,其中AP应该引导。它以现代模式开始,并在输入保护模式的情况下出现故障。需要明确的是,它在JMP 0x8上的故障:...加载CR0后。我确信AP正在获取其代码,因为在两者之间的任何地方循环都会阻止故障。将代码区域apboot-apbootSequenceence将其复制到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)

to

JMP DWORD 0x8:(9*64*1024+InitSoftwareEnvironment-APBoot)

最新更新