SVGA in 32bit protected mode ?
-
- Posts: 22
- Joined: Mon Dec 04, 2006 5:34 pm
SVGA in 32bit protected mode ?
Well..
I started with some friends to write an OS «just for fun» (and maybe a little more) and we're wondering what is the best way to handle GFX mode.
Yeah, we're aiming to do a mainly graphical OS, however we want to do it the hard way.
I did some research and found that VESA VBE 2.0 should be called in 16bit mode (or v86), however it's too easy.
Since we all use QEmu for the tests, and since QEmu is used by some people here, I was wondering if someone had tips or code snips about how to enumerate then switch to a gfx mode from 32bit protected mode (seems to simulate a Cirrus Logic GD5446 PCI VGA, from what the manpage says).
Well, btw tips and tricks are welcome. We started last week, and after some difficulties we managed to have a running bootloader, and be able to load and run some C code. I even wrote a minimalistic printf-like function which uses teletype bios interrupt to write text to the screen.
I started with some friends to write an OS «just for fun» (and maybe a little more) and we're wondering what is the best way to handle GFX mode.
Yeah, we're aiming to do a mainly graphical OS, however we want to do it the hard way.
I did some research and found that VESA VBE 2.0 should be called in 16bit mode (or v86), however it's too easy.
Since we all use QEmu for the tests, and since QEmu is used by some people here, I was wondering if someone had tips or code snips about how to enumerate then switch to a gfx mode from 32bit protected mode (seems to simulate a Cirrus Logic GD5446 PCI VGA, from what the manpage says).
Well, btw tips and tricks are welcome. We started last week, and after some difficulties we managed to have a running bootloader, and be able to load and run some C code. I even wrote a minimalistic printf-like function which uses teletype bios interrupt to write text to the screen.
Re: SVGA in 32bit protected mode ?
I don't know Qemu well, but I have played a with some VESA graphics. A solution could be to find and setup the VESA mode, switch to it and query the physical address for the video memory in 16 bit real mode. Then you can switch to protected mode and just write to that memory address (calculated for the pixel). It should show up immediately. It worked for me in Bochs emulator.MagicalTux wrote:Well..
I did some research and found that VESA VBE 2.0 should be called in 16bit mode (or v86), however it's too easy.
But if you read the VESA VBE 2.0 specification it should tell you about protected mode access. The BIOS has to support it though. As far as I know Bochs doesn't do this (a pity), but maybe Qemu does.
Other solutions might exists. I have thought of an pmode-rmode-bridge. But that, I think, may be out of scope of your project.
-
- Posts: 22
- Joined: Mon Dec 04, 2006 5:34 pm
The QEmu bios is bochs'... and the implementations are almost the same. However QEmu have an option documented in the man page :
-std-vga
Simulate a standard VGA card with Bochs VBE extensions (default is Cirrus Logic GD5446 PCI VGA). If your guest OS supports the VESA 2.0 VBE extensions (e.g. Windows XP) and if you want to use high resolution modes (>= 1280x1024x16) then you should use this option.
Dunno if this can be used... Well anyway I'll try to do the gfx init from 16bit mode, but I'm not sure I'll be able to do things like addressing 800x600 resolution in 32bit mode (yeah, I don't have much experience with that).
-std-vga
Simulate a standard VGA card with Bochs VBE extensions (default is Cirrus Logic GD5446 PCI VGA). If your guest OS supports the VESA 2.0 VBE extensions (e.g. Windows XP) and if you want to use high resolution modes (>= 1280x1024x16) then you should use this option.
Dunno if this can be used... Well anyway I'll try to do the gfx init from 16bit mode, but I'm not sure I'll be able to do things like addressing 800x600 resolution in 32bit mode (yeah, I don't have much experience with that).
Try it.MagicalTux wrote:Dunno if this can be used... Well anyway I'll try to do the gfx init from 16bit mode, but I'm not sure I'll be able to do things like addressing 800x600 resolution in 32bit mode (yeah, I don't have much experience with that).
Most possible you get an video address like 0xE0000000 (ie. 3,5 GiB address point), I did. Save it. If you have choosen 32 bit color depth and 800x600 resolution, the thing goes like this in C:
Code: Select all
uint32 * screenBase = 0xE0000000; // or whatever value you get
uint32 screenWidth = 800;
uint32 screenHeight = 600;
void drawPixel(uint32 x, uint32 y, uint32 rgbColor) {
uint32 * address = screenBase + screenWidth * y + x;
*address = rgbColor;
}
// Define some colors (as you know them in HTML):
const uint32 Black = 0x000000;
const uint32 Red = 0xFF0000;
const uint32 Green = 0x00FF00;
const uint32 Blue = 0x0000FF;
const uint32 Gray = 0x999999;
const uint32 White = 0xFFFFFF;
If you know how, then have some fun by drawing the Mandelbrot fractal or similar. It's feels good when it boots up and displays a complex and beautiful picture like that
I just implemented that, so I released a new version of Xenon just now, for Qemu users only. It's avaliable from the link below.
Essentially, you get a big, 1024x768 fat text console.
Enjoy!
Also, look at the qemu source, in hw/cirrus_vga.c, and the linux source, in drivers/video/cirrusfb.c; that is much better code than this.
EDIT: for this one, you need the Cirrus SVGA adapter, so no -std-vga
Essentially, you get a big, 1024x768 fat text console.
Enjoy!
Also, look at the qemu source, in hw/cirrus_vga.c, and the linux source, in drivers/video/cirrusfb.c; that is much better code than this.
EDIT: for this one, you need the Cirrus SVGA adapter, so no -std-vga
Last edited by TheQuux on Tue Dec 05, 2006 1:32 am, edited 1 time in total.
My project: Xenon
Here's a demo i wrote sometime ago, that switch between veas and text mode every 10 seconds in pmode, may help ?.
http://www.dex4u.com/demos/DemoVesa.zip
Note: i was called ASHLEY4 then .
http://www.dex4u.com/demos/DemoVesa.zip
Note: i was called ASHLEY4 then .
Hi,
here is some code i have written sometime ago. It should work with Bochs as well as with Qemu (don't forget -std-vga):
You can access the LFB at 0xe0000000 after calling vbe_set().
I have also written some code for the VMWare video adapter.
I can post it as well, if you want it.
here is some code i have written sometime ago. It should work with Bochs as well as with Qemu (don't forget -std-vga):
Code: Select all
#define VBE_DISPI_IOPORT_INDEX 0x01CE
#define VBE_DISPI_IOPORT_DATA 0x01CF
#define VBE_DISPI_INDEX_ID 0x0
#define VBE_DISPI_INDEX_XRES 0x1
#define VBE_DISPI_INDEX_YRES 0x2
#define VBE_DISPI_INDEX_BPP 0x3
#define VBE_DISPI_INDEX_ENABLE 0x4
#define VBE_DISPI_INDEX_BANK 0x5
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
#define VBE_DISPI_INDEX_X_OFFSET 0x8
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
#define VBE_DISPI_DISABLED 0x00
#define VBE_DISPI_ENABLED 0x01
#define VBE_DISPI_GETCAPS 0x02
#define VBE_DISPI_8BIT_DAC 0x20
#define VBE_DISPI_LFB_ENABLED 0x40
#define VBE_DISPI_NOCLEARMEM 0x80
void vbe_write(USHORT index, USHORT value)
{
WRITE_PORT_USHORT(VBE_DISPI_IOPORT_INDEX, index);
WRITE_PORT_USHORT(VBE_DISPI_IOPORT_DATA, value);
}
void vbe_set(USHORT xres, USHORT yres, USHORT bpp)
{
vbe_write(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
vbe_write(VBE_DISPI_INDEX_XRES, xres);
vbe_write(VBE_DISPI_INDEX_YRES, yres);
vbe_write(VBE_DISPI_INDEX_BPP, bpp);
vbe_write(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
}
I have also written some code for the VMWare video adapter.
I can post it as well, if you want it.
-
- Posts: 22
- Joined: Mon Dec 04, 2006 5:34 pm
Wow, it works in protected mode !
Thanks a lot!!
(btw I had to use outw instead of WRITE_PORT_USHORT)
EDIT: Ok it works great, and I could display some nice images to test the 32 bits
Btw the vmware code is welcome too.
(Now I have to work on 32bit disk driver to avoid switching to 16bit mode while loading images)
Thanks a lot!!
(btw I had to use outw instead of WRITE_PORT_USHORT)
EDIT: Ok it works great, and I could display some nice images to test the 32 bits
Btw the vmware code is welcome too.
(Now I have to work on 32bit disk driver to avoid switching to 16bit mode while loading images)
It would be nice though if vbabios used by Bochs and Qemu supported the VBE3 protected mode entry point. Just found this bug report/feature request (obviously written by an OS developer): http://savannah.nongnu.org/support/?105170 Nobody ever answered it
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
"Severity: 1 - Wish". Thats asking for being forgotten.It would be nice though if vbabios used by Bochs and Qemu supported the VBE3 protected mode entry point. Just found this bug report/feature request (obviously written by an OS developer): http://savannah.nongnu.org/support/?105170 Nobody ever answered it
Suggestion: If somebody has time to spare, he might contribute to the bios and do the PMode entry point. Everything's here
Compiling VGABIOS
I've downloaded the source, but it won't compile. I've installed the Bin86 package, which is needed. It just says:Combuster wrote:Suggestion: If somebody has time to spare, he might contribute to the bios and do the PMode entry point. Everything's here
Code: Select all
% make
gcc -E vgabios.c -DVBE "-DVGABIOS_DATE="`date '+%d %b %Y'`"" > _vgabios_.c
bcc -o vgabios.s -C-c -D__i86__ -S -0 _vgabios_.c
_vgabios_.c:1: error: Unknown preprocessor directive
_vgabios_.c:2: error: Unknown preprocessor directive
_vgabios_.c:3: error: Unknown preprocessor directive
_vgabios_.c:4: error: Unknown preprocessor directive
...
...
I might contribute. It can't be that difficult to code an entrypoint. It is 16 bit protected mode, so it could just call the current implementation I think. Of course I would have to look into that and the VBE3 specification.
You could download windows ddk and there you will find AGP display driver, so you could program graphics chip yourself.
BTW, there is VESA 3.0 by now. There is routine to ask VESA to give you address at start of frame buffer. example he returned to me ed000000h.
Go to vesa site and read specifications.
http://www.vesa.org/public/VBE
That will do it.
BTW, there is VESA 3.0 by now. There is routine to ask VESA to give you address at start of frame buffer. example he returned to me ed000000h.
Go to vesa site and read specifications.
http://www.vesa.org/public/VBE
That will do it.
The problem is that you can't do it only from protected mode right now. You can if the BIOS supports the protected mode entry point as explained in the VBE3 specification, but AFAIK the 'vgabios' used in Bochs and Qemu doesn't support it. My current solution is to jump into real mode every time I need to do a VESA command, but that is not very efficient.AirFlight wrote:You could download windows ddk and there you will find AGP display driver, so you could program graphics chip yourself.
BTW, there is VESA 3.0 by now. There is routine to ask VESA to give you address at start of frame buffer. example he returned to me ed000000h.
Go to vesa site and read specifications.
http://www.vesa.org/public/VBE
That will do it.