[Closed] Setting VESA/VBE Mode
[Closed] Setting VESA/VBE Mode
As the title suggests I need a way to set some high resolution VES/VBE mode.
After my bootloader topic I decided to use GRUB2 as my bootloader.
Then we (yes two of us guys) implemented GDT, IDT, ISR, IRQ, Protected Mode, Shell, Basic VGA Driver, Drawing, some other C function and types etc...
At this moment, we have 320x200 VGA with 256 (64) colors. That is not really enough.
We decided that we want High Resolution VBE/VESA mode. Our goal is to achieve resolutions like 1024x768, 1360x768, 1920x1080.
Now we have no idea how to do that. After reading all those articles and tutorials, searching this forum for code... Nothing showed up.
I even tried porting already made VESA drivers, but without any luck.
I've also read that since we are using GRUB2 we can ask GRUB to set video mode for us?
Another important note it that we can directly write to BIOS using inportb and outportb functions. Can we set video mode by using them from our C code or we need some extra assembly functions?
Using protected mode makes this a bit difficult right?
Also there is something called V8086 monitor that is really hard to write but it can use BIOS functions that are not usable with protected mode on?
I would really appreciate some working code for setting graphics mode to VESA with some custom high resolutions or defined ones like 0x1018h.
Asking for makes me feel like a beggar, but that is the only way.
After my bootloader topic I decided to use GRUB2 as my bootloader.
Then we (yes two of us guys) implemented GDT, IDT, ISR, IRQ, Protected Mode, Shell, Basic VGA Driver, Drawing, some other C function and types etc...
At this moment, we have 320x200 VGA with 256 (64) colors. That is not really enough.
We decided that we want High Resolution VBE/VESA mode. Our goal is to achieve resolutions like 1024x768, 1360x768, 1920x1080.
Now we have no idea how to do that. After reading all those articles and tutorials, searching this forum for code... Nothing showed up.
I even tried porting already made VESA drivers, but without any luck.
I've also read that since we are using GRUB2 we can ask GRUB to set video mode for us?
Another important note it that we can directly write to BIOS using inportb and outportb functions. Can we set video mode by using them from our C code or we need some extra assembly functions?
Using protected mode makes this a bit difficult right?
Also there is something called V8086 monitor that is really hard to write but it can use BIOS functions that are not usable with protected mode on?
I would really appreciate some working code for setting graphics mode to VESA with some custom high resolutions or defined ones like 0x1018h.
Asking for makes me feel like a beggar, but that is the only way.
Last edited by Octacone on Mon Jul 17, 2017 5:38 am, edited 2 times in total.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Re: Setting VESA/VBE Mode
Hi,
There are 2 parts to this problem - finding a video mode that actually works (that the OS itself, and the video card, and the monitor all support); and setting that video mode.
For finding a video mode I'd:
Now... GRUB can set the video mode for you during boot (if the right "GRUB modules" are installed, etc); but it won't do it properly (e.g. doesn't really know what your software supports, doesn't check if the monitor supports the video mode, etc). Because of this, to get the best results the end user needs to configure GRUB (more end user hassle, more chance of user mis-configuring). It also can't work properly on something like a "live CD" (where it's impossible to configure GRUB to work for all the different computers the CD might be booted on). Finally, GRUB (multi-boot) has no support for multi-monitor or multiple video cards (even when you're booting on a UEFI system that has full support for this).
Basically; GRUB is the easiest form of "use firmware (indirectly) to setup video mode during boot", but it's also the worst option (for end user hassle), the worst option (for reliability), and the worst option (for features - e.g. multiple monitors, etc).
Cheers,
Brendan
It can (but more on that later).thehardcoreOS wrote:I've also read that since we are using GRUB2 we can ask GRUB to set video mode for us?
That's a native video driver (which is possible), but means that you need a different driver for most different video cards and ends up being a lot of work.thehardcoreOS wrote:Another important note it that we can directly write to BIOS using inportb and outportb functions. Can we set video mode by using them from our C code or we need some extra assembly functions?
Using protected mode makes this a bit difficult right?
You can use V8086 (or software emulation); but that's extra work that is useless for modern (UEFI) computers so it's typically not worth bothering with.thehardcoreOS wrote:Also there is something called V8086 monitor that is really hard to write but it can use BIOS functions that are not usable with protected mode on?
There are 2 parts to this problem - finding a video mode that actually works (that the OS itself, and the video card, and the monitor all support); and setting that video mode.
For finding a video mode I'd:
- get a list of all video modes that the video card supports (from UEFI, from VBE, or from native driver)
- remove anything the OS doesn't support
- remove anything the monitor doesn't support (based on EDID information)
- give each video mode a score (representing things like if it's the monitor's native resolution, if it'll gobble too much RAM, if it will look ugly, how much it matches user's preferences if any, etc)
- select the video mode with the best score
- Use a native video driver (and write one for each video card). This probably isn't very practical; but allows you to support multiple monitors, multiple video cards, etc, and allows you to change video modes after boot without much hassle.
- Use the firmware (VBE for BIOS, GOP or UGA for UEFI, etc). This is far more practical; but BIOS/VBE doesn't support multiple monitors or video cards properly and is painful for switching video modes after boot; and UEFI may or may not support multiple monitors or video cards properly (depends on whether there's appropriate UEFI drivers, etc) and can't be used at all for switching video modes after boot.
Now... GRUB can set the video mode for you during boot (if the right "GRUB modules" are installed, etc); but it won't do it properly (e.g. doesn't really know what your software supports, doesn't check if the monitor supports the video mode, etc). Because of this, to get the best results the end user needs to configure GRUB (more end user hassle, more chance of user mis-configuring). It also can't work properly on something like a "live CD" (where it's impossible to configure GRUB to work for all the different computers the CD might be booted on). Finally, GRUB (multi-boot) has no support for multi-monitor or multiple video cards (even when you're booting on a UEFI system that has full support for this).
Basically; GRUB is the easiest form of "use firmware (indirectly) to setup video mode during boot", but it's also the worst option (for end user hassle), the worst option (for reliability), and the worst option (for features - e.g. multiple monitors, etc).
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.
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: Setting VESA/VBE Mode
If you're using GRUB2, the easiest way to do this is indeed requesting a video mode from GRUB. You can't request a specific mode number, but instead you pass the width, height and bits per pixel and GRUB will do the dirty work for you. Anyway, starting with VESA 2.0, no video mode numbers are standard and you should never depend on them.
inportb() and outportb() write to different hardware, not to the BIOS. The BIOS really is just a software that provides basic drivers for you hardware. Setting high resolution modes with port I/O will be very different for each graphics card, and nobody wants to write a driver for every single graphics card they'd like to support.
v8086 is indeed a solution, but it won't work on many real hardware, nor will it work in x86_64. Most real BIOSes switch to protected mode to access high memory, and that crosses the limits of v8086.
Read this section and this section of the multiboot specification. They explain how to request video modes, and then get information of the video mode.
inportb() and outportb() write to different hardware, not to the BIOS. The BIOS really is just a software that provides basic drivers for you hardware. Setting high resolution modes with port I/O will be very different for each graphics card, and nobody wants to write a driver for every single graphics card they'd like to support.
v8086 is indeed a solution, but it won't work on many real hardware, nor will it work in x86_64. Most real BIOSes switch to protected mode to access high memory, and that crosses the limits of v8086.
Read this section and this section of the multiboot specification. They explain how to request video modes, and then get information of the video mode.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: Setting VESA/VBE Mode
Nice to hear that GRUB can do all that. I just really wanted to do a quick switch to VESA so we can code the s*it out of our GUI compositor.omarrx024 wrote:If you're using GRUB2, the easiest way to do this is indeed requesting a video mode from GRUB. You can't request a specific mode number, but instead you pass the width, height and bits per pixel and GRUB will do the dirty work for you. Anyway, starting with VESA 2.0, no video mode numbers are standard and you should never depend on them.
inportb() and outportb() write to different hardware, not to the BIOS. The BIOS really is just a software that provides basic drivers for you hardware. Setting high resolution modes with port I/O will be very different for each graphics card, and nobody wants to write a driver for every single graphics card they'd like to support.
v8086 is indeed a solution, but it won't work on many real hardware, nor will it work in x86_64. Most real BIOSes switch to protected mode to access high memory, and that crosses the limits of v8086.
Read this section and this section of the multiboot specification. They explain how to request video modes, and then get information of the video mode.
Thanks for answering, now I need to study those links and see what I can get out of them. Btw are multiboot definitions inside asm defined by default or I need to define them my self like for e.g vbe_mode_info dd 0?
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Re: Setting VESA/VBE Mode
The most annoying detail is here in this paragraph:
A similar mode? How to prioritize what is important and what is not? Sometimes color depth is far more important than resolution, for example.https://www.gnu.org/software/grub/manual/multiboot/multiboot.html wrote: 3.1.4 The graphics fields of Multiboot header
All of the graphics fields are enabled by flag bit 2. They specify the preferred graphics mode. Note that that is only a recommended mode by the OS image. If the mode exists, the boot loader should set it, when the user doesn't specify a mode explicitly. Otherwise, the boot loader should fall back to a similar mode, if available.
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: Setting VESA/VBE Mode
I don't understand your question. GRUB passes the multiboot information in EBX. What you need to do it preserve EBX and pass it to your kernel. Your kernel should have a multiboot structure, and you use the value that was in EBX as a pointer to the multiboot structure. Then you can access the VBE fields.thehardcoreOS wrote:Nice to hear that GRUB can do all that. I just really wanted to do a quick switch to VESA so we can code the s*it out of our GUI compositor.
Thanks for answering, now I need to study those links and see what I can get out of them. Btw are multiboot definitions inside asm defined by default or I need to define them my self like for e.g vbe_mode_info dd 0?
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: Setting VESA/VBE Mode
Good point, my kernel does not have any multiboot structures. There is just a main function used for initialization of other system components.omarrx024 wrote:I don't understand your question. GRUB passes the multiboot information in EBX. What you need to do it preserve EBX and pass it to your kernel. Your kernel should have a multiboot structure, and you use the value that was in EBX as a pointer to the multiboot structure. Then you can access the VBE fields.thehardcoreOS wrote:Nice to hear that GRUB can do all that. I just really wanted to do a quick switch to VESA so we can code the s*it out of our GUI compositor.
Thanks for answering, now I need to study those links and see what I can get out of them. Btw are multiboot definitions inside asm defined by default or I need to define them my self like for e.g vbe_mode_info dd 0?
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Re: Setting VESA/VBE Mode
I tried the GRUB method too, but for me it wasn't really clear where the LFB address was (I don't think it is passed through the multiboot structure).
So therefore, I wrote some code to temporarily switch back to real mode, detect video modes and switch to the video mode I want (and storing the info block), and switching back to protected mode again.
So therefore, I wrote some code to temporarily switch back to real mode, detect video modes and switch to the video mode I want (and storing the info block), and switching back to protected mode again.
My blog: http://www.rivencove.com/
Re: Setting VESA/VBE Mode
Maybe you weren't returning the right value.dseller wrote:I tried the GRUB method too, but for me it wasn't really clear where the LFB address was (I don't think it is passed through the multiboot structure).
So therefore, I wrote some code to temporarily switch back to real mode, detect video modes and switch to the video mode I want (and storing the info block), and switching back to protected mode again.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
- jeaye
- Posts: 8
- Joined: Tue May 24, 2016 6:48 pm
- Libera.chat IRC: jeaye
- Location: San Francisco
- Contact:
Re: Setting VESA/VBE Mode
There was a forum thread here http://forum.osdev.org/viewtopic.php?f=2&t=30186 which gives some good information on VESA; it's better than what's on the wiki, if I remember correctly. Unfortunately, it hasn't yet made it up onto the wiki; I pinged the author about it a few weeks ago and haven't heard back.
I'd imagine a number of people want to get into higher resolution + fancy graphics before they dig further into the meat of the OS, just for the instant gratification which is so uncommon in osdev. Unfortunately, a lot of the existing documentation for VESA work assumes quite a bit about what's been done so far and there aren't many documents explaining how to fit VESA into something like Bare Bones or Meaty Skeleton.
I'd imagine a number of people want to get into higher resolution + fancy graphics before they dig further into the meat of the OS, just for the instant gratification which is so uncommon in osdev. Unfortunately, a lot of the existing documentation for VESA work assumes quite a bit about what's been done so far and there aren't many documents explaining how to fit VESA into something like Bare Bones or Meaty Skeleton.
- BrightLight
- Member
- Posts: 901
- Joined: Sat Dec 27, 2014 9:11 am
- Location: Maadi, Cairo, Egypt
- Contact:
Re: Setting VESA/VBE Mode
I've completely forgotten I've even written that guide to VESA, and I never noticed your reply. Sorry about that!jeaye wrote:There was a forum thread here http://forum.osdev.org/viewtopic.php?f=2&t=30186 which gives some good information on VESA; it's better than what's on the wiki, if I remember correctly. Unfortunately, it hasn't yet made it up onto the wiki; I pinged the author about it a few weeks ago and haven't heard back.
EDIT: I've put it on the Wiki.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Re: Setting VESA/VBE Mode
Update:
I downloaded and included multiboot header file.
kernel_main(multiboot_info_t *mbit)
{
...
}
Now how do I set mbit.width and mbit.height mbi.mod_type mbi.depth?
I can not do that directly because compiler throws errors.
Is there any special assembly related code I need to do before that?
Update 2: I just discovered that you can set multiboot flags inside assembly and that they co-respond with those declared inside my C file.
Since I am using NASM I can not use stuff like .long and .set and I need to use equ and dd but I can not compiler that.
Update 3: I set all the flags for my graphics mode and trust me nothing happens:
I downloaded and included multiboot header file.
kernel_main(multiboot_info_t *mbit)
{
...
}
Now how do I set mbit.width and mbit.height mbi.mod_type mbi.depth?
I can not do that directly because compiler throws errors.
Is there any special assembly related code I need to do before that?
Update 2: I just discovered that you can set multiboot flags inside assembly and that they co-respond with those declared inside my C file.
Since I am using NASM I can not use stuff like .long and .set and I need to use equ and dd but I can not compiler that.
Update 3: I set all the flags for my graphics mode and trust me nothing happens:
Code: Select all
section .text
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
dd 0
dd 0
dd 0
dd 0
dd 0
dd 0
dd 1360
dd 768
dd 32
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
- DeezRamChips
- Member
- Posts: 132
- Joined: Fri Apr 08, 2016 5:03 am
- Location: atapio.cpp - why won't you work :(
- Contact:
Re: Setting VESA/VBE Mode
Exaclty the same problem !thehardcoreOS wrote:Update:
I downloaded and included multiboot header file.
kernel_main(multiboot_info_t *mbit)
{
...
}
Now how do I set mbit.width and mbit.height mbi.mod_type mbi.depth?
I can not do that directly because compiler throws errors.
Is there any special assembly related code I need to do before that?
Update 2: I just discovered that you can set multiboot flags inside assembly and that they co-respond with those declared inside my C file.
Since I am using NASM I can not use stuff like .long and .set and I need to use equ and dd but I can not compiler that.
Update 3: I set all the flags for my graphics mode and trust me nothing happens:Code: Select all
section .text align 4 dd MAGIC dd FLAGS dd CHECKSUM dd 0 dd 0 dd 0 dd 0 dd 0 dd 0 dd 1360 dd 768 dd 32
i'm sure you use grub legacy do you ?
You need grub 2 or a patched version of grub legacy
My github page: https://github.com/AlexandreRouma
Meme-deving since 420 Bc !
YouTube: https://www.youtube.com/channel/UCyJnOD ... C8Y7pccc6A
Twitter: https://twitter.com/WhatsTheGeekYT
Meme-deving since 420 Bc !
YouTube: https://www.youtube.com/channel/UCyJnOD ... C8Y7pccc6A
Twitter: https://twitter.com/WhatsTheGeekYT
Re: Setting VESA/VBE Mode
Oh, this is a nice long article. I think that we won't be coding anything special at this moment. We just want to set high resolution VESA mode and use that. GRUB is our only option at this moment. We don't care for multiple monitors or graphics cards. This is just a private learning project and we just want to get VESA to work so we can hardcode our GUI compositor. Writing native graphics card drivers is almost impossible since there is no any documentationBrendan wrote:Hi,
It can (but more on that later).thehardcoreOS wrote:I've also read that since we are using GRUB2 we can ask GRUB to set video mode for us?
That's a native video driver (which is possible), but means that you need a different driver for most different video cards and ends up being a lot of work.thehardcoreOS wrote:Another important note it that we can directly write to BIOS using inportb and outportb functions. Can we set video mode by using them from our C code or we need some extra assembly functions?
Using protected mode makes this a bit difficult right?
thehardcoreOS wrote:Also there is something called V8086 monitor that is really hard to write but it can use BIOS functions that are not usable with protected mode on?
You can use V8086 (or software emulation); but that's extra work that is useless for modern (UEFI) computers so it's typically not worth bothering with.
There are 2 parts to this problem - finding a video mode that actually works (that the OS itself, and the video card, and the monitor all support); and setting that video mode.
For finding a video mode I'd:For setting a video mode, there are 2 options:
- get a list of all video modes that the video card supports (from UEFI, from VBE, or from native driver)
- remove anything the OS doesn't support
- remove anything the monitor doesn't support (based on EDID information)
- give each video mode a score (representing things like if it's the monitor's native resolution, if it'll gobble too much RAM, if it will look ugly, how much it matches user's preferences if any, etc)
- select the video mode with the best score
You mostly want to support both options. Essentially; use a native video driver if one exists, and use firmware as a "fallback" (for when you have no native video driver). In this case, for the "no driver fallback" it's not really worth bothering with the hassle of trying to support video mode switching after boot (partly because it's something that the user doesn't care about most of the time anyway).
- Use a native video driver (and write one for each video card). This probably isn't very practical; but allows you to support multiple monitors, multiple video cards, etc, and allows you to change video modes after boot without much hassle.
- Use the firmware (VBE for BIOS, GOP or UGA for UEFI, etc). This is far more practical; but BIOS/VBE doesn't support multiple monitors or video cards properly and is painful for switching video modes after boot; and UEFI may or may not support multiple monitors or video cards properly (depends on whether there's appropriate UEFI drivers, etc) and can't be used at all for switching video modes after boot.
Now... GRUB can set the video mode for you during boot (if the right "GRUB modules" are installed, etc); but it won't do it properly (e.g. doesn't really know what your software supports, doesn't check if the monitor supports the video mode, etc). Because of this, to get the best results the end user needs to configure GRUB (more end user hassle, more chance of user mis-configuring). It also can't work properly on something like a "live CD" (where it's impossible to configure GRUB to work for all the different computers the CD might be booted on). Finally, GRUB (multi-boot) has no support for multi-monitor or multiple video cards (even when you're booting on a UEFI system that has full support for this).
Basically; GRUB is the easiest form of "use firmware (indirectly) to setup video mode during boot", but it's also the worst option (for end user hassle), the worst option (for reliability), and the worst option (for features - e.g. multiple monitors, etc).
Cheers,
Brendan
on that topic. VESA + GRUB2 is our best bet since it supports high resolutions. Also I am using qemu with -kernel for my virtual machine and I already have my set vbe via grub code ready but nothing happens on boot, resolution stays the same.
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
- DeezRamChips
- Member
- Posts: 132
- Joined: Fri Apr 08, 2016 5:03 am
- Location: atapio.cpp - why won't you work :(
- Contact:
Re: Setting VESA/VBE Mode
And add that to your grub.cfg file:DeezRamChips wrote:Exaclty the same problem !thehardcoreOS wrote:Update:
I downloaded and included multiboot header file.
kernel_main(multiboot_info_t *mbit)
{
...
}
Now how do I set mbit.width and mbit.height mbi.mod_type mbi.depth?
I can not do that directly because compiler throws errors.
Is there any special assembly related code I need to do before that?
Update 2: I just discovered that you can set multiboot flags inside assembly and that they co-respond with those declared inside my C file.
Since I am using NASM I can not use stuff like .long and .set and I need to use equ and dd but I can not compiler that.
Update 3: I set all the flags for my graphics mode and trust me nothing happens:Code: Select all
section .text align 4 dd MAGIC dd FLAGS dd CHECKSUM dd 0 dd 0 dd 0 dd 0 dd 0 dd 0 dd 1360 dd 768 dd 32
i'm sure you use grub legacy do you ?
You need grub 2 or a patched version of grub legacy
Code: Select all
insmod vbe
insmod vga
My github page: https://github.com/AlexandreRouma
Meme-deving since 420 Bc !
YouTube: https://www.youtube.com/channel/UCyJnOD ... C8Y7pccc6A
Twitter: https://twitter.com/WhatsTheGeekYT
Meme-deving since 420 Bc !
YouTube: https://www.youtube.com/channel/UCyJnOD ... C8Y7pccc6A
Twitter: https://twitter.com/WhatsTheGeekYT