Page 1 of 1
Writing to the BGA framebuffer doesn't show up on screen
Posted: Thu Oct 07, 2021 3:05 am
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/
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Thu Oct 07, 2021 7:01 am
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.
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Thu Oct 07, 2021 8:18 am
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.
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Thu Oct 07, 2021 9:36 am
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.
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Thu Oct 07, 2021 11:13 am
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
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Fri Oct 08, 2021 6:04 am
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.
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Fri Oct 08, 2021 10:52 am
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.
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Fri Oct 08, 2021 12:54 pm
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.
Re: Writing to the BGA framebuffer doesn't show up on screen
Posted: Sun Oct 17, 2021 4:52 am
by Th3Matt
Thanks, setting the offset to 0x10 fixed it.