How to Enter VGA Video Mode (in Real Mode)?

I read about programming an operating system in Rust (for x86_64) on

It was very educational. Sadly, there are still a lot of topics, that the blog hasn't covered (yet). One of them is, how to draw pixels directly on the screen.

I searched a bit and found a tutorial on VGA graphics. It mentions the following:

To set the video mode, call interrupt 10h (BIOS video functions) with 0 (zero) in the AH register and the desired mode number in the AL register. For mode 13h, the code would be as follows:

union REGS regs;

regs.h.ah = 0x00;
regs.h.al = 0x13;
int86(0x10,&regs,&regs);

To return to text mode after the program finishes, simply set the mode number to 3.

union REGS regs;

regs.h.ah = 0x00;
regs.h.al = 0x03;
int86(0x10,&regs,&regs);

I'm a bit lost. How does that translate to Rust?

I haven't tried any asm in Rust so this is all speculative but according to https://doc.rust-lang.org/unstable-book/library-features/asm.html you can do something like

unsafe {
        asm!(
            "mov ax, 0x13",
            "int 0x10");
}

Seems to generate the right code: https://rust.godbolt.org/z/rhd4fK

I guess you can then access the video memory in a similar fashion as the blog describes in https://os.phil-opp.com/vga-text-mode/ except you'll need to use 0xa000 instead of 0xb8000 as your video buffer address. The tutorial seems to cover it well.

There seems to be a llvm_asm! macro as well. There are some crates that use VGA, perhaps you can use them (or check how they implement things), e.g. https://crates.io/crates/vga .

BIOS functions are only accessible in real mode (16bit), blog os runs in long mode (64bit). You will have to patch the bootloader crate to run the asm before entering long mode. Note that it is being rewritten to also support UEFI though. I think this rewrite will use a frame buffer instead of text mode for both BIOS and UEFI.

Huh? How does VGA text mode work in long mode, then? That seems weird.

You can write to the memory mapped buffer used for VGA just fine in long mode. It is just impossible to call into the BIOS to change the VGA configuration without going to real mode.

You can't go into real mode but you can go into v86 mode and back, that's what DOS extenders used to do. That said, I have no idea whether modern CPU support all those features, haven't done any real low level PC stuff for decades.

It is possible to get back to real mode. in fact the bootloader crate goes from real mode to protected mode with a 32bit segment back to real mode so that it can address the full 4GB. This configuration where a 32bit segment is used in real mode is also called unreal mode.

1 Like

Virtual 8086 mode only exists to also be able to use paging., which isn't supported in real mode and to be able to run at lower privilege levels.

Looks like the vga crate access the hardware directly using x86_64 so you don't need to use int 0x10 to call BIOS.

Try to use vga to initialise the mode you need and then access the frame buffer directly. Not sure if 320x200 the create uses is linear or planar. You can read more about planar modes on https://en.wikipedia.org/wiki/Planar_(computer_graphics) and https://en.wikipedia.org/wiki/Mode_X .