BIOS Interrupts in protected mode
Asked Answered
G

2

8

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"

Gorlovka answered 19/10, 2014 at 7:46 Comment(0)
M
3

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.

Moral answered 21/10, 2014 at 15:1 Comment(0)
R
7

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
Regurgitate answered 27/10, 2014 at 12:47 Comment(0)
M
3

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.

Moral answered 21/10, 2014 at 15:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.