BIOS Interrupts in protected mode

*爱你&永不变心* 提交于 2019-12-08 17:20:47

问题


I'm working on an operating system project, using isolinux (syslinux 4.5) as bootloader, loading my kernel with multiboot header organised at 0x200000.

As I know the kernel is already in 32-bit protected mode. My question: Is there any easier way to get access to BIOS Interrupts? (Basically I want 0x10 :D)

After loading, my kernel sets up its own GDT and IDT entries and further remaps IRQs. So, is it possible to jump into real mode just after the kernel is loaded and set up VGA/SVGA modes (VBE 2.0 mode). Then after I'll proceed with my kernel and jump into protected mode where I use VBE 2.0 physical buffer address to write onto screen? If yes how? I tried a lot but didn't get success :(

Side note: I searched a lot on internet and found that syslinux 1.x+ provides _intcall api, I'm not 100% sure about it. Refer to "syslinux 4.5\com32\lib\sys\initcall.c"


回答1:


The short answer is no. BIOS calls are designed to operate in real mode and don't respect restraints set by protected mode, so you're not allowed to use them and the CPU will triple-fault if you try.

However, x86 processors provide Virtual 8086 mode, which can be used to emulate an x86 processor running in 16-bit real mode. The OSDev wiki and forums provide a wealth of information on this topic. If you go this route, it is generally a good idea to map the kernel to the higher half (Linux uses 0xC0000000) to avoid interfering with VM86 code.




回答2:


BIOS was designed for 16-bit machines. However, still you have three options to call BIOS interrupts in protected mode.

  1. Switch back to real mode and re-enter protected mode (Easiest approach).
  2. Use v86 mode (not available in 64-bit long mode).
  3. Write your own 16-bit x86 processor emulator (Hardest approach).

I used first approach in my operating system for VBE and disk access through BIOS.
Code used for this purpose in my operating system:

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


来源:https://stackoverflow.com/questions/26448480/bios-interrupts-in-protected-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!