2014-10-19 63 views
6

我正在使用isolinux(syslinux 4.5)作为引导加载程序,使用组织为0x200000的多引导头加载我的内核,从事操作系统项目。保护模式中的BIOS中断

据我所知,内核已经处于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”

回答

2

简短的回答是没有,BIOS调用被设计在实模式下运行,不尊重保护模式设置的限制,所以你不允许使用它们,如果你尝试,CPU将会出现三重故障

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

2

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

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

我在操作系统中使用第一种方法进行VBE和通过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