Page 2 of 3

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

Posted: Fri Jan 21, 2022 6:47 pm
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.

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

Posted: Fri Jan 21, 2022 6:51 pm
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.

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

Posted: Fri Jan 21, 2022 7:21 pm
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.

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

Posted: Fri Jan 21, 2022 8:07 pm
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.

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

Posted: Fri Jan 21, 2022 9:51 pm
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.

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

Posted: Mon Jan 24, 2022 8:34 am
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!

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

Posted: Mon Jan 24, 2022 12:42 pm
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
.

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

Posted: Mon Jan 24, 2022 12:47 pm
by Octocontrabass
The pointer to the Multiboot information structure is in EBX, not EAX.

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

Posted: Mon Jan 24, 2022 3:21 pm
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.

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

Posted: Mon Jan 24, 2022 3:42 pm
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;
    }
}

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

Posted: Mon Jan 24, 2022 5:03 pm
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;
    }

}

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

Posted: Mon Jan 24, 2022 5:14 pm
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.)

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

Posted: Mon Jan 24, 2022 5:17 pm
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?

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

Posted: Mon Jan 24, 2022 5:52 pm
by Octocontrabass
Have you tried adding 1 to the array index to set the second byte?

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

Posted: Tue Jan 25, 2022 11:45 am
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.