OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 16, 2024 12:21 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: VBE Linear framebuffer - not very linear at all!
PostPosted: Wed Aug 22, 2018 6:36 pm 
Offline

Joined: Tue Jun 05, 2018 4:43 pm
Posts: 13
Hi all,

I've started to write a very basic OS. I'm having some trouble with the linear framebuffer, however. It works fine in Qemu, but in virtualbox, or on real hardware, I can only write to the first 2MB of it. Past that point, things start to get weird - the screen wraps around back to the top, but offset to the right - and then eventually jumps to the bottom of the screen. The framebuffer address is about 10 times bigger on virtualbox/bare metal (About 0xE000000) so I wonder if it's related to an integer overflow of some sort.

Source code: https://git.scd31.com/laptopdude90/SteveOS/

VIdeo is first set up in boot/video.asm
The offending function is in drivers/screen.c (fillrect() - which generates the background)

I have tried a memcpy and memset directly to the framebuffer - both suffer from the same issues. At this point I have no idea how to debug further.

Screenshots:
https://img.scd31.com/up/15349708260cf53f6.png <- shows how screen wraps back up
https://img.scd31.com/up/1534971984396f61e.png <- shows how text wraps

Could it possibly have something to do with the GDT? (boot/gdt.asm)


Top
 Profile  
 
 Post subject: Re: VBE Linear framebuffer - not very linear at all!
PostPosted: Wed Aug 22, 2018 8:22 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

scdown wrote:
The offending function is in drivers/screen.c (fillrect() - which generates the background)


On line 25 and 29 in "putpixel()", and on lines 35, 42 and 43 of "filrect()"; you're doing calculations wrong. Specifically, you're doing "COLOR_BITS/8" to calculate how many bytes a pixel takes up, but (for 15-bpp video mode) with integer arithmetic "15/8 = 1" which is wrong. You need something more like "(COLOR_BITS+7)/8" so that it rounds up and you get the correct result (2 bytes per pixel, not one byte per pixel); or even better you could do a "bytes_per_pixel = (COLOR_BITS+7)/8;" once in "setup_video()" so that you don't have to repeatedly calculate it everywhere.

This bug means that every time you write a pixel it gets put at the wrong place; and I suspect that all of the other code relies on either "putpixel()" (which is very bad for performance) or "fillrect()", so everything gets drawn at the wrong place. I'd also assume that on Qemu you got a 16-bpp video mode (where "16/8 = 2") so it was right and worked by accident.


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject: Re: VBE Linear framebuffer - not very linear at all!
PostPosted: Thu Aug 23, 2018 12:28 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5134
It looks an awful lot like you didn't enable the A20 line.


Top
 Profile  
 
 Post subject: Re: VBE Linear framebuffer - not very linear at all!
PostPosted: Thu Aug 23, 2018 12:39 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 692
Octocontrabass is exactly right.You haven't enabled A20 so all the odd megabyte memory areas are mapped to the even numbered megabyte memory region just below it. On some system A20 is enabled and some it isn't. So it depends on the emulator or the hardware as to what state it is in. You should always enable it. See this OSDev article on enabling A20 line

As well you should really consider creating a linker script and create a BSS section that you can get the beginning and the end - and then initialize that memory to 0 rather than relying on being lucky that the memory is zeroed out. GRUB does the zeroing for you, but since you are using your own bootloader that job is left to you.

Since you are using x87 for floating point to keep BOCHS happy you should consider using the finit instruction to initialize the FPU before calling into your kernel.


Top
 Profile  
 
 Post subject: Re: VBE Linear framebuffer - not very linear at all!
PostPosted: Thu Aug 23, 2018 6:28 am 
Offline

Joined: Tue Jun 05, 2018 4:43 pm
Posts: 13
Brendan wrote:
Hi,

scdown wrote:
The offending function is in drivers/screen.c (fillrect() - which generates the background)


On line 25 and 29 in "putpixel()", and on lines 35, 42 and 43 of "filrect()"; you're doing calculations wrong. Specifically, you're doing "COLOR_BITS/8" to calculate how many bytes a pixel takes up, but (for 15-bpp video mode) with integer arithmetic "15/8 = 1" which is wrong. You need something more like "(COLOR_BITS+7)/8" so that it rounds up and you get the correct result (2 bytes per pixel, not one byte per pixel); or even better you could do a "bytes_per_pixel = (COLOR_BITS+7)/8;" once in "setup_video()" so that you don't have to repeatedly calculate it everywhere.

This bug means that every time you write a pixel it gets put at the wrong place; and I suspect that all of the other code relies on either "putpixel()" (which is very bad for performance) or "fillrect()", so everything gets drawn at the wrong place. I'd also assume that on Qemu you got a 16-bpp video mode (where "16/8 = 2") so it was right and worked by accident.


Cheers,

Brendan


Thanks! I'll keep this in mind if I switch to a 15 bit colour mode in the future. I'll probably implement it sooner than that anyway, because why not?

Also, the putpixel() function isn't being used too much as it is, I've been working to make it obsolete.


Top
 Profile  
 
 Post subject: Re: VBE Linear framebuffer - not very linear at all!
PostPosted: Thu Aug 23, 2018 6:30 am 
Offline

Joined: Tue Jun 05, 2018 4:43 pm
Posts: 13
Octocontrabass wrote:
It looks an awful lot like you didn't enable the A20 line.


MichaelPetch wrote:
Octocontrabass is exactly right.You haven't enabled A20 so all the odd megabyte memory areas are mapped to the even numbered megabyte memory region just below it. On some system A20 is enabled and some it isn't. So it depends on the emulator or the hardware as to what state it is in. You should always enable it. See this OSDev article on enabling A20 line

As well you should really consider creating a linker script and create a BSS section that you can get the beginning and the end - and then initialize that memory to 0 rather than relying on being lucky that the memory is zeroed out. GRUB does the zeroing for you, but since you are using your own bootloader that job is left to you.

Since you are using x87 for floating point to keep BOCHS happy you should consider using the finit instruction to initialize the FPU before calling into your kernel.


THANK YOU BOTH SO MUCH! I'd never even heard of the A20 line, but setting this immediately fixed the issue.


Top
 Profile  
 
 Post subject: Re: VBE Linear framebuffer - not very linear at all!
PostPosted: Thu Aug 23, 2018 5:39 pm 
Offline
Member
Member

Joined: Sat Feb 27, 2010 8:55 pm
Posts: 147
MichaelPetch wrote:
Octocontrabass is exactly right.You haven't enabled A20 so all the odd megabyte memory areas are mapped to the even numbered megabyte memory region just below it. On some system A20 is enabled and some it isn't. So it depends on the emulator or the hardware as to what state it is in. You should always enable it. See this OSDev article on enabling A20 line


If I'm not mistaken a Mac will freak out if you try to enable A20 (it's already enabled). To work on Macs and PCs you should first check to see if it's already enabled, and then enable it only if it isn't already.


Top
 Profile  
 
 Post subject: Re: VBE Linear framebuffer - not very linear at all!
PostPosted: Thu Aug 23, 2018 8:05 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 692
azblue wrote:
If I'm not mistaken a Mac will freak out if you try to enable A20 (it's already enabled). To work on Macs and PCs you should first check to see if it's already enabled, and then enable it only if it isn't already.
The OSDev article we linked to discuss that as well.
.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 69 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group