【问题标题】:BIOS Interrupts in protected mode保护模式下的 BIOS 中断
【发布时间】:2014-12-14 10:07:36
【问题描述】:

我正在开发一个操作系统项目,使用 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”

【问题讨论】:

    标签: interrupt bios osdev protected-mode syslinux


    【解决方案1】:

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

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

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

    ;______________________________________________________________________________________________________
    ;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
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2018-11-30
        • 2011-04-07
        • 2011-08-13
        • 2020-09-13
        • 2016-04-06
        • 1970-01-01
        • 1970-01-01
        • 2017-12-09
        • 2021-03-28
        相关资源
        最近更新 更多