Writing to the BGA framebuffer doesn't show up on screen

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.
Post Reply
Th3Matt
Posts: 5
Joined: Tue Jul 06, 2021 2:18 am

Writing to the BGA framebuffer doesn't show up on screen

Post by Th3Matt »

This is the BGA initialization code:

Code: Select all

InitBGA:
    mov ax, 0x4
    mov dx, 0x01CE
    out dx, ax ;0x1CE

    xor ax, ax		; Screen disable
    inc dx
    out dx, ax ;0x1CF

    mov ax, 0x1
    dec dx
    out dx, ax ;0x1CE

    mov ax, 720		; X
    inc dx
    out dx, ax ;0x1CF

    mov ax, 0x2
    dec dx
    out dx, ax ;0x1CE

    mov ax, 400		;	Y
    inc dx
    out dx, ax ;0x1CF

    mov ax, 0x3
    dec dx
    out dx, ax ;0x1CE

    mov ax, 32		; BPP
    inc dx
    out dx, ax ;0x1CF

    mov ax, 0x4
    dec dx
    out dx, ax ;0x1CE

    mov ax, 0x41	; Linear famebuffer and screen enable
    inc dx
    out dx, ax ;0x1CF

    iret
After initialising the BGA, I use a GDT segment which starts at the BAR0 address of the BGA PCI device and write 720*400 dwords of 0x00FFFFFF:

Code: Select all

mov ecx, 720*400
mov ax, 0x38
mov gs, ax
xor edi, edi

.loop:
	mov dword [gs:edi], 0x00FFFFFF
	add edi, 4
	loop .loop
Yet the screen remains black.
I'm using Bochs to test my OS.
Github: https://github.com/Th3Matt/FlameOS-Rewrite3/
Klakap
Member
Member
Posts: 297
Joined: Sat Mar 10, 2018 10:16 am

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by Klakap »

What value you got from BAR0? Are you sure this is not bug in your PCI driver? I can not found it on git. In your GDT I see that you map memory for your graphic mode on 0xA0000-0xE6500. I don’t deal with BGA, but are you sure that video ram have to be there? From my experience with VESA, it is rather somewhere like 0xE0000000 And also, from another side of this problematic, it is easy to implement VESA, and your OS will have graphic mode on all emulators, and also on legacy real hardware.
Th3Matt
Posts: 5
Joined: Tue Jul 06, 2021 2:18 am

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by Th3Matt »

BAR0 is 0x02000000. My GDT entry 0x38 only points to 0xA0000-0xE6500 if VGA Hardware driver is selected, otherwise it should point from BAR0 to BAR0+0x119fff, which it does in Bochs. It also seems to work in VirtualBox. My early driver code still hasn't been split off from Kernel.asm, it starts a bit after the GDT definition. I'm currently updating the Github, previously the driver only had one function, so, along with some unimportant changes to the selection dialog, I've split the function in half so it would be easier to understand (one half checks BGA ID, the other one finds BGA in PCI).
I'm using BGA because it you can control it from protected mode and don't have to switch back to real mode, so even though it doesn't work on real hardware, it's supported on Bochs, QEMU and VirtualBox, so it's still useful to implement as one of the drivers. Once I finish this driver I will move on to writing the VBE 2.0+ driver so I can support real hardware.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by Octocontrabass »

Th3Matt wrote:BAR0 is 0x02000000.
I'm pretty sure it isn't.
Th3Matt wrote:My GDT entry 0x38 only points to 0xA0000-0xE6500 if VGA Hardware driver is selected,
That range is too large. The VGA framebuffer is limited to 128kiB (0xA0000-0xBFFFF), and typical VGA modes only allow 64kiB (0xA0000-0xAFFFF or 0xB0000-0xBFFFF) to leave room for a second display adapter. If the framebuffer doesn't fit in that space, you must use bank switching.

Out of curiosity, have you dumped GS (using "info sreg" in the Bochs debugger) to make sure it actually points to BAR0 instead of 0xA0000? According to the wiki, some virtual machines will allow you to access the framebuffer at 0xA0000 when you request a linear framebuffer, but Bochs won't.
StaticSaga
Posts: 1
Joined: Thu Aug 12, 2021 8:00 am

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by StaticSaga »

Using segmentation for storing the framebuffer base address is not really a portable choice. You're reserving the GS register for it, which is generally used for storing per-CPU kernel information (x86_64 has SWAPGS for that purpose).

There is no clean way to access GS and FS in C (GCC and Clang have named address spaces, but they're a nonstandard feature which is not supported in older compiler versions either), and other architectures have no concept of segmentation at all.
Storing it in a global variable results in more concise code too, no need to touch the GDT

Code: Select all

fbAddr: resd 1
InitGraphics: ; graphics init code, addr in eax
    mov [fbAddr], eax
    ret
DoSomething: ; example function using the address: fill the first pixel with white (32bpp)
    mov edi, [fbAddr]
    mov [edi], 0xFFFFFFFF 
    ret
Th3Matt
Posts: 5
Joined: Tue Jul 06, 2021 2:18 am

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by Th3Matt »

Octocontrabass wrote:I'm pretty sure it isn't.
I've manually checked all PCI device functions and there is only one that matches the vendor ID and the device ID of the BGA card, so the BAR0 should be correct.
Octocontrabass wrote:That range is too large. The VGA framebuffer is limited to 128kiB (0xA0000-0xBFFFF), and typical VGA modes only allow 64kiB (0xA0000-0xAFFFF or 0xB0000-0xBFFFF) to leave room for a second display adapter. If the framebuffer doesn't fit in that space, you must use bank switching.
I'm just too lazy to implement a seperate size just for the VGA framebuffer, so I'm just using the same size as the BGA framebuffer.
Octocontrabass wrote:Out of curiosity, have you dumped GS (using "info sreg" in the Bochs debugger) to make sure it actually points to BAR0 instead of 0xA0000? According to the wiki, some virtual machines will allow you to access the framebuffer at 0xA0000 when you request a linear framebuffer, but Bochs won't.
See the attached screenshot.
Attachments
Screenshot_2021-10-07_19-10-08.png
Th3Matt
Posts: 5
Joined: Tue Jul 06, 2021 2:18 am

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by Th3Matt »

StaticSaga wrote:There is no clean way to access GS and FS in C (GCC and Clang have named address spaces, but they're a nonstandard feature which is not supported in older compiler versions either), and other architectures have no concept of segmentation at all.
I don't plan to use C or any higher level language for my OS. Also I'm currently not planning to develop my OS for other architectures.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by Octocontrabass »

Th3Matt wrote:I've manually checked all PCI device functions and there is only one that matches the vendor ID and the device ID of the BGA card, so the BAR0 should be correct.
But you're not reading BAR0. You're reading the command and status registers.
Th3Matt
Posts: 5
Joined: Tue Jul 06, 2021 2:18 am

Re: Writing to the BGA framebuffer doesn't show up on screen

Post by Th3Matt »

Thanks, setting the offset to 0x10 fixed it.
Post Reply