进入保护模式:三重故障

时间:2017-09-10 02:58:56

标签: x86 kernel real-mode protected-mode smp

我正在向我的内核添加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:

1 个答案:

答案 0 :(得分:2)

我找到了问题的答案。 NASM汇编程序没有警告我需要的地址覆盖。地址(9 * 64 * 1024 + InitSoftwareEnvironment)溢出16位数据大小。所以,我需要使用地址覆盖选项 - 通过更改

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

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