I can't get my VGA driver to work

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Caffeine
Member
Member
Posts: 79
Joined: Mon Nov 15, 2021 9:48 pm

I can't get my VGA driver to work

Post by Caffeine »

Hi, I can't seem to get my VGA driver to work. The problem is that the program seems to be hanging (see attached screenshot) when initializeVga() is called:

vga.c:

Code: Select all

#include "../Kernel/system.h"
#include "vga.h"

unsigned char *VGA;
unsigned short offset;

extern void enableVideoMode();
extern void disableVideoMode();

void initializeVGA() {
    enableVideoMode();

    *VGA = (unsigned char*)0xA0000;
}

void plotPixle(int x, int y, char color) {
    offset = (y << 8) + (y << 6) + x;
    VGA[offset] = color;
}

void test() {
    for (int y = 3; y < 180; y++) { for (int i = 0; i < 319; i++) { offset = (y << 8) + (y << 6) + i; VGA[offset] = 1; } }
}
vga.asm:

Code: Select all

global enableVideoMode
global disableVideoMode

enableVideoMode:
    mov ah, 0x00
    mov al, 0x13
    int 0x10


disableVideoMode:
    mov ah, 0x00
    mov al, 0x03
    int 0x10
I am using qemu to emulate:

Code: Select all

qemu-system-i386 -cdrom Binaries/caffieneOS.iso
Sorry if the answerer is very obvious. I am not sure what to do here. I have been following this guide: http://web.archive.org/web/201402180128 ... ac/vga.htm I found on the VGA recourses page.
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: I can't get my VGA driver to work

Post by klange »

You are trying to call BIOS interrupts, but I would guess you're in protected mode. That doesn't make a lick of sense.
Caffeine
Member
Member
Posts: 79
Joined: Mon Nov 15, 2021 9:48 pm

Re: I can't get my VGA driver to work

Post by Caffeine »

klange wrote:You are trying to call BIOS interrupts, but I would guess you're in protected mode. That doesn't make a lick of sense.
Thank you for pointing that out for me. Sorry for the beginner mistake.

How should I be implementing a VGA driver if I am in protected mode?
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: I can't get my VGA driver to work

Post by klange »

You have a few options with various tradeoffs.

1. Don't. Let your bootloader configure a framebuffer for you. A bootloader like Grub will do this with the right config options; if you are writing your own loader, you just do what you were trying to do here before you jump to protected mode (and don't forget to pass some information on the video mode).
2. Write drivers for display devices. This is, of course, quite time-consuming and complicated and most display devices are poorly documented.
3. Use one of a few methods to call the BIOS APIs from protected mode: v8086 mode (won't work in long mode), return to real mode temporarily (flaky), or provide an emulator to run BIOS code and pass through io instructions (none of these options will work on EFI)
Caffeine
Member
Member
Posts: 79
Joined: Mon Nov 15, 2021 9:48 pm

Re: I can't get my VGA driver to work

Post by Caffeine »

klange wrote:You have a few options with various tradeoffs.

1. Don't. Let your bootloader configure a framebuffer for you. A bootloader like Grub will do this with the right config options; if you are writing your own loader, you just do what you were trying to do here before you jump to protected mode (and don't forget to pass some information on the video mode).
2. Write drivers for display devices. This is, of course, quite time-consuming and complicated and most display devices are poorly documented.
3. Use one of a few methods to call the BIOS APIs from protected mode: v8086 mode (won't work in long mode), return to real mode temporarily (flaky), or provide an emulator to run BIOS code and pass through io instructions (none of these options will work on EFI)
How would I configure GRUB to do this?
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: I can't get my VGA driver to work

Post by alexfru »

Caffeine wrote:

Code: Select all

unsigned char *VGA;
...
    *VGA = (unsigned char*)0xA0000;
So, VGA starts out as NULL (unless that's also somehow broken in your build).
Then *VGA dereferences it.
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: I can't get my VGA driver to work

Post by klange »

You can tell Grub you want to have a framebuffer at boot through the 'graphics' fields in a multiboot1 header or the framebuffer request tag in multiboot2, or more flexibly by setting the gfxpayload variable in Grub after loading your kernel, immediately before booting. Use set gfxpayload=keep to maintain the resolution set if Grub was running in graphical mode, otherwise you can pass WIDTHxHEIGHT or WIDTHxHEIGHTxBPP (eg 1024x768 or 1440x900x32) and Grub will make an effort to set that mode if possible. You can also set it to text to get VGA text mode instead.
alexfru wrote:So, VGA starts out as NULL (unless that's also somehow broken in your build).
Then *VGA dereferences it.
Didn't even notice that issue...
Caffeine
Member
Member
Posts: 79
Joined: Mon Nov 15, 2021 9:48 pm

Re: I can't get my VGA driver to work

Post by Caffeine »

klange wrote:You can tell Grub you want to have a framebuffer at boot through the 'graphics' fields in a multiboot1 header or the framebuffer request tag in multiboot2, or more flexibly by setting the gfxpayload variable in Grub after loading your kernel, immediately before booting. Use set gfxpayload=keep to maintain the resolution set if Grub was running in graphical mode, otherwise you can pass WIDTHxHEIGHT or WIDTHxHEIGHTxBPP (eg 1024x768 or 1440x900x32) and Grub will make an effort to set that mode if possible. You can also set it to text to get VGA text mode instead.
alexfru wrote:So, VGA starts out as NULL (unless that's also somehow broken in your build).
Then *VGA dereferences it.
Didn't even notice that issue...
How do I implement the graphics in the multiboot header?
Caffeine
Member
Member
Posts: 79
Joined: Mon Nov 15, 2021 9:48 pm

Re: I can't get my VGA driver to work

Post by Caffeine »

alexfru wrote:
Caffeine wrote:

Code: Select all

unsigned char *VGA;
...
    *VGA = (unsigned char*)0xA0000;
So, VGA starts out as NULL (unless that's also somehow broken in your build).
Then *VGA dereferences it.
Thanks for pointing this out, I'll fix this right now.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: I can't get my VGA driver to work

Post by Octocontrabass »

Caffeine wrote:How do I implement the graphics in the multiboot header?
That depends on which version of Multiboot you're using.

If you're using the first version of Multiboot, you need to set bit 2 of the flags, set mode_type to 0, and pick a reasonable default width, height, and depth. Many example Multiboot headers don't include anything after checksum, so you might need to add the missing fields to your Multiboot header.

If you're using Multiboot2, you need to add a framebuffer tag to your Multiboot2 header. Make sure your tags are 8-byte aligned: the framebuffer tag is 20 bytes long, so you must tell your assembler to align the following tag or it won't work.

(Once your Multiboot header is set up for a graphics mode, you can choose a different graphics mode by setting gfxpayload in your GRUB configuration. This way, you don't need to compile a different kernel for each screen resolution!)
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: I can't get my VGA driver to work

Post by klange »

Caffeine
Member
Member
Posts: 79
Joined: Mon Nov 15, 2021 9:48 pm

Re: I can't get my VGA driver to work

Post by Caffeine »

This worked! Video mode is enabled now! But I'm still not able to put a pixel on the screen. Here is my code:

Code: Select all

void plotPixle(int x, int y, unsigned char color) {
    unsigned char* location = (unsigned char*)0xA0000 + (320 * y + x);
    *location = color;
}
It has just been displaying a black screen.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: I can't get my VGA driver to work

Post by Octocontrabass »

The framebuffer address is not 0xA0000. You need to get the framebuffer address from the Multiboot information structure.

Also, the framebuffer is probably not 8bpp. You need to get the bit depth from the Multiboot information structure too.
Caffeine
Member
Member
Posts: 79
Joined: Mon Nov 15, 2021 9:48 pm

Re: I can't get my VGA driver to work

Post by Caffeine »

Octocontrabass wrote:The framebuffer address is not 0xA0000. You need to get the framebuffer address from the Multiboot information structure.

Also, the framebuffer is probably not 8bpp. You need to get the bit depth from the Multiboot information structure too.
How do I get the framebuffer address and bit depth from the Multiboot information structure? I have been looking at the documentation for multiboot and can't figure it out.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: I can't get my VGA driver to work

Post by Octocontrabass »

The Multiboot specifications include example code. Which part do you not understand?
Post Reply