BIOS在保护模式下中断

ama*_*eka 7 interrupt bios protected-mode osdev syslinux

我正在开发一个操作系统项目,使用isolinux(syslinux 4.5)作为引导加载程序,使用组织在0x200000的多引导头加载我的内核.

据我所知,内核已经处于32位保护模式.我的问题:有没有更简单的方法来访问BIOS中断?(基本上我想要0x10:D)

加载后,我的内核设置了自己的GDT和IDT条目,并进一步重新映射IRQ.因此,在内核加载并设置VGA/SVGA模式(VBE 2.0模式)后,是否可以跳转到实模式.然后,我将继续我的内核并跳转到保护模式,我使用VBE 2.0物理缓冲区地址写入屏幕?如果有,怎么样?我尝试了很多,但没有成功:(

旁注:我在互联网上搜索了很多,发现syslinux 1.x +提供了_intcall api,我对此并不是100%肯定.请参阅"syslinux 4.5\com32\lib\sys\initcall.c"

小智 5

BIOS是为16位计算机设计的。但是,仍然有三个选项可以在保护模式下调用BIOS中断。

  1. 切换回实模式并重新进入保护模式(最简单的方法)。
  2. 使用v86模式(在64位长模式下不可用)。
  3. 编写自己的16位x86处理器仿真器(最困难的方法)。

我在操作系统中使用第一种方法通过VBIOS和磁盘访问BIOS。
我的操作系统中用于此目的的代码:

;______________________________________________________________________________________________________
;Switch to 16-bit real Mode
;IN/OUT:  nothing

go16:
    [BITS 32]

    cli         ;Clear interrupts
    pop edx         ;save return location in edx

    jmp 0x20:PM16       ;Load CS with selector 0x20

;For go to 16-bit real mode, first we have to go to 16-bit protected mode
    [BITS 16]
PM16:
    mov ax, 0x28        ;0x28 is 16-bit protected mode selector.
    mov ss, ax  
    mov ds, ax
    mov es, ax
    mov gs, ax
    mov fs, ax
    mov sp, 0x7c00+0x200    ;Stack hase base at 0x7c00+0x200    


    mov eax, cr0
    and eax, 0xfffffffe ;Clear protected enable bit in cr0

    mov cr0, eax    

    jmp 0x50:realMode   ;Load CS and IP


realMode:
;Load segment registers with 16-bit Values.
    mov ax, 0x50
    mov ds, ax
    mov fs, ax
    mov gs, ax
    mov ax, 0
    mov ss, ax
    mov ax, 0
    mov es, ax
    mov sp, 0x7c00+0x200    

    cli
    lidt[.idtR]     ;Load real mode interrupt vector table
    sti

    push 0x50       ;New CS
    push dx         ;New IP (saved in edx)
    retf            ;Load CS, IP and Start real mode

;Real mode interrupt vector table
.idtR:  dw 0xffff       ;Limit
    dd 0            ;Base
Run Code Online (Sandbox Code Playgroud)


Cor*_*ien 3

最简洁的答案是。BIOS 调用被设计为在实模式下运行,并且不遵守保护模式设置的限制,因此您不允许使用它们,如果您尝试使用它们,CPU 将出现三重故障。

但是,x86 处理器提供虚拟 8086 模式,可用于模拟以 16 位实模式运行的 x86 处理器。OSDev wiki 和论坛提供了有关此主题的大量信息。如果您走这条路,通常最好将内核映射到上半部分(Linux 使用 0xC0000000)以避免干扰 VM86 代码。