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

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

Post by Caffeine »

Octocontrabass wrote:The Multiboot specifications include example code. Which part do you not understand?
The part I am mainly confused on (at least right now) is what the argument addr would be and how I would find out addr in the function cmain() in the Kernel example code found here: https://www.gnu.org/software/grub/manua ... ot-kernels.

I am sorry for all the confusion.
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 »

Caffeine wrote:
Octocontrabass wrote:The Multiboot specifications include example code. Which part do you not understand?
The part I am mainly confused on (at least right now) is what the argument addr would be and how I would find out addr in the function cmain() in the Kernel example code found here: https://www.gnu.org/software/grub/manua ... ot-kernels.

I am sorry for all the confusion.
EDIT:
After doing some more reading, what I need to know is how to get the address of the multiboot header.
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 »

When GRUB jumps to your kernel's entry point, the address is in the EBX register. You need to write assembly code that will take the address in EBX and put it somewhere so you can use it.

In the i386 psABI, parameters are passed to functions by pushing them on the stack. The example boot.S code pushes EBX onto the stack to pass the address as a parameter to the cmain function.
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:When GRUB jumps to your kernel's entry point, the address is in the EBX register. You need to write assembly code that will take the address in EBX and put it somewhere so you can use it.

In the i386 psABI, parameters are passed to functions by pushing them on the stack. The example boot.S code pushes EBX onto the stack to pass the address as a parameter to the cmain function.
How do you push EBX onto the stack so the c function can see it? Sorry, I am a little lost. Here is my bootloader, I got it from a beginner tutorial to set up GRUB (But I forgot where it was). https://pastebin.com/ZcrGQ3q2

All I can find online is passing c functions to assembly, not the other way around.
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:All I can find online is passing c functions to assembly, not the other way around.
The sample code in the Multiboot specification demonstrates how to call a C function from assembly.

There are also plenty of other examples out there. Perhaps you need to change the keywords you use when you search.

And it's a good idea to check the i386 psABI for the details.
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:
Caffeine wrote:All I can find online is passing c functions to assembly, not the other way around.
The sample code in the Multiboot specification demonstrates how to call a C function from assembly.

There are also plenty of other examples out there. Perhaps you need to change the keywords you use when you search.

And it's a good idea to check the i386 psABI for the details.
I'll try this right now, thanks for your help!
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:
Caffeine wrote:All I can find online is passing c functions to assembly, not the other way around.
The sample code in the Multiboot specification demonstrates how to call a C function from assembly.

There are also plenty of other examples out there. Perhaps you need to change the keywords you use when you search.

And it's a good idea to check the i386 psABI for the details.
Here is my bootloader, I am having issues getting the register. The screen is still empty: https://pastebin.com/ZcrGQ3q2

The change was made at line 94 where I added

Code: Select all

push eax
.
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 pointer to the Multiboot information structure is in EBX, not EAX.
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 pointer to the Multiboot information structure is in EBX, not EAX.
I changed it to ebx but it still is not working. I am passing the address to the VGA driver and trying to plot a pixel at (100, 100) using this code:

Code: Select all

void initializeVGA(unsigned long addr) {
    unsigned char* location = (unsigned char*)addr + (320 * 100 + 100);
    *location = 4;

}
But it still does not work.
Sorry for the beginner questions.
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 address is the address of the Multiboot information structure, not the address of the framebuffer. You need to parse the multiboot information structure to find the framebuffer address.

For example:

Code: Select all

void example( uintptr_t addr )
{
    multiboot_info_t * mbi = (multiboot_info_t *)addr;
    uint8_t * framebuffer = (uint8_t *)mbi->framebuffer_addr;
    switch( mbi->framebuffer_bpp )
    {
        case 8:
            framebuffer[mbi->framebuffer_pitch * 100 + 1 * 100] = 4;
            break;
        case 15:
        case 16:
            framebuffer[mbi->framebuffer_pitch * 100 + 2 * 100] = 0xff;
            break;
        case 24:
            framebuffer[mbi->framebuffer_pitch * 100 + 3 * 100] = 0xff;
            break;
        case 32:
            framebuffer[mbi->framebuffer_pitch * 100 + 4 * 100] = 0xff;
            break;
        default:
            // error
            break;
    }
}
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 address is the address of the Multiboot information structure, not the address of the framebuffer. You need to parse the multiboot information structure to find the framebuffer address.

For example:

Code: Select all

void example( uintptr_t addr )
{
    multiboot_info_t * mbi = (multiboot_info_t *)addr;
    uint8_t * framebuffer = (uint8_t *)mbi->framebuffer_addr;
    switch( mbi->framebuffer_bpp )
    {
        case 8:
            framebuffer[mbi->framebuffer_pitch * 100 + 1 * 100] = 4;
            break;
        case 15:
        case 16:
            framebuffer[mbi->framebuffer_pitch * 100 + 2 * 100] = 0xff;
            break;
        case 24:
            framebuffer[mbi->framebuffer_pitch * 100 + 3 * 100] = 0xff;
            break;
        case 32:
            framebuffer[mbi->framebuffer_pitch * 100 + 4 * 100] = 0xff;
            break;
        default:
            // error
            break;
    }
}
It works!! Thank you so much for your help!! One more question though, how do I change the color of the pixel? Do I change the hex values in the last few cases in the switch statement or is it something else?

Here is my code - this works:

Code: Select all

unsigned int *framebuffer;
multiboot_info_t *mbi;

void initializeVGA(unsigned long addr) {
    mbi = (multiboot_info_t *)addr;  // Get the multiboot information from the address
    framebuffer = (unsigned int *)mbi->framebuffer_addr;  // Get the framebuffer address

}

void plotPixle(int x, int y, unsigned char color) {
    switch (mbi->framebuffer_bpp) {
    case 8:
        framebuffer[mbi->framebuffer_pitch * y + 1 * x] = 4;
        break;
    case 15:
        break;
    case 16:
        framebuffer[mbi->framebuffer_pitch * y + 2 * x] = 0xff;
        break;
    case 24:
        framebuffer[mbi->framebuffer_pitch * y + 3 * x] = 0xff;
        break;
    case 32:
        framebuffer[mbi->framebuffer_pitch * y + 4 * x] = 0xff;
        break;
    default:
        // error
        break;
    }

}
Last edited by Caffeine on Mon Jan 24, 2022 5:15 pm, edited 1 time in total.
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 »

Yes, those hex values determine the color. However, this example code only sets one byte, and pixels are usually more than one byte. (Most common seems to be 32bpp, which is four bytes per pixel.)
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:Yes, those hex values determine the color. However, this example code only sets one byte, and pixels are usually more than one byte. (Most common seems to be 32bpp, which is four bytes per pixel.)
How should I set more than one byte?
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 »

Have you tried adding 1 to the array index to set the second byte?
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:Have you tried adding 1 to the array index to set the second byte?
Sorry, but I am a little confused as to how to do this. Again, sorry for the beginner questions.
Post Reply