BIOS Protected Mode Interrupts

I am working on an operating system project using isolinux (syslinux 4.5) as the bootloader, loading my kernel with a multiboot header organized in 0x200000.

As I know, the kernel is already in 32-bit protected mode. My question is: is there an easier way to access BIOS interrupts? (Mostly I want 0x10: D)

After booting, my kernel configures its own GDT and IDT records and further redirects the IRQ. Thus, you can go into real mode immediately after loading the kernel and configure the VGA / SVGA modes (VBE 2.0 mode). Then after I continue my kernel and go into protected mode, where do I use the address of the VBE 2.0 physical buffer to write to the screen? If so, how? I tried a lot, but did not succeed :(

Side note: I searched a lot on the Internet and found that syslinux 1.x + provides _intcall api, I'm not 100% sure. See "Syslinux 4.5 \ com32 \ lib \ sys \ initcall.c"

+6
source share
2 answers

The short answer is no . BIOS calls are designed to work in real mode and do not take into account the restrictions set by protected mode, so you are not allowed to use them, and the CPU will triple 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. OSDev wikis and forums provide great information on this topic. If you go this route, it is usually recommended that you map the kernel to a higher half (Linux uses 0xC0000000) to avoid interference with VM86 code.

+2
source

The BIOS was designed for 16-bit machines. However, you have three options for invoking BIOS interrupts in protected mode.

  • Return to real mode and re-enter protected mode (easy approach).
  • Use v86 mode (not available in 64-bit mode).
  • Write your own 16-bit x86 processor emulator (the toughest approach).

I used the first approach in my operating system for VBE and disk access via BIOS.
The code used for this purpose in my operating system is:

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

Source: https://habr.com/ru/post/976931/


All Articles