x86 - 进入保护模式: Triple-Fault

标签 x86 kernel real-mode protected-mode smp

我正在将 SMP 添加到我的内核中,AP 应在其中启动。它以实模式启动,并在进入保护模式时出错。需要明确的是,加载 CR0 后,JMP 0x8:... 出现故障。我确信 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)

关于x86 - 进入保护模式: Triple-Fault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46136889/

相关文章:

assembly - 为什么这些实模式代码在虚拟机中可以运行,但在我的真机上却不能运行?

assembly - 为什么我的引导加载程序不能正确地从内存中加载一个字节?

c++ - 是否可以将线程执行转移到另一个线程?

c++ - 对返回前仅对 EAX 的低字节进行异或运算的虚方法进行逆向工程

c - while循环不写入显存

c - 在内核空间中存储结构数组,Linux

linux - tcpdump 捕获的数据包是否有可能在 tcp 内核中丢失?

assembly - 为什么在使用 PUSH 或 POP 指令时不鼓励使用 ESP 寄存器?

linux - 释放克隆的 skb(使用 skb_clone)将释放原始 skb?

assembly - 引导加载程序堆栈配置