Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VESA video mode - 800x600x16bit #60

Closed
wants to merge 4 commits into from
Closed

Conversation

jabedude
Copy link

@jabedude jabedude commented Jun 23, 2019

Hello all, this PR checks if VESA 2.0 or 3.0 is supported and then enables it with fixed 800x600. This is very rough, so please let me know what else we need to do.

TODO:

  • Proper color handling
  • Query the framebuffer address from hardware instead of hardcoding it (if possible)
  • Pass the framebuffer address in BootInfo

@phil-opp
Copy link
Member

Thanks a lot for tackling this!

We don't want to hard code the video mode for the user, but instead make it configurable through cargo features. We currently support vga text mode and a simple vga graphics mode (320x200). Could you place the VESA code in a new file in src/video_mode and add a cargo feature for enabling it, like it is done for the other video modes?

@jabedude
Copy link
Author

Sure thing!

@phil-opp
Copy link
Member

phil-opp commented Jul 1, 2019

Thanks, looks good now!

Were you able to print something to the screen through this? I just tried to update the src/printer/mod.rs module (used for printing panic messages) with a new vesa printer, but I didn't know the framebuffer location.

@jabedude
Copy link
Author

jabedude commented Jul 1, 2019

I meant to ping you, I actually was hoping to get some help with testing printing with the new video mode. I should be able to get you the framebuffer address.

@phil-opp
Copy link
Member

phil-opp commented Jul 2, 2019

Sure!

Printing should work similar to the vga_320x200 module, we only need the framebuffer address and the pixel format (i.e. how many bytes per pixel, how are the RGB channels encoded).

@jabedude
Copy link
Author

jabedude commented Jul 2, 2019

I found the framebuffer address for qemu: 0xFD000000. The pixel format is 5 red bits, 6 green, and 5 blue bits. I'm still having issues trying to modify vga_320x200 to print correctly

@phil-opp
Copy link
Member

phil-opp commented Jul 6, 2019

@jabedude Thanks! The problem was that we need to add a page table mapping for the physical address 0xFD000000 to the page table. I pushed a commit (I hope that is fine with you) that maps the framebuffer to the 500th entry of the level 2 page table. It also adds a new printer, which is the vga_320x200 printer with some modifications. Now it looks like this:

image

I didn't add any code for color handling, so the colors are a bit strange. I deliberately didn't paint the screen back in clear_screen so that we see that really the whole screen is blanked.

@ethindp
Copy link
Contributor

ethindp commented Jul 6, 2019 via email

@phil-opp
Copy link
Member

phil-opp commented Jul 6, 2019

@ethindp For me the bootloader already works on real hardware. What problems do you have exactly?

Also, could you elaborate your statement about "virtualized/emulated addresses"? Since you replied to this pull request, I assume that you mean using the address 0xFD000000? This is just a stop-gap solution for experimentation, the plan is to query this address from the VESA later.

@ethindp
Copy link
Contributor

ethindp commented Jul 6, 2019 via email

@phil-opp
Copy link
Member

phil-opp commented Jul 7, 2019

Have you tried the instructions at https://os.phil-opp.com/minimal-rust-kernel/#real-machine? The bootimage tool already creates a hard disk image, so you don't need mkisofs for this (I'm not sure about CD images though).

As a side note: Can we continue the conversation in a new issue? This issue issue is about adding support for the VESA video mode, so I think a separate issue would fit better.

@jabedude
Copy link
Author

jabedude commented Jul 7, 2019

@phil-opp That is awesome! Of course, I was hoping to collaborate in this PR (I have no prior experience with VESA/BIOS printing).

@phil-opp
Copy link
Member

phil-opp commented Jul 9, 2019

@jabedude Great! I updated the PR description with a todo list. Do you think anything else is missing?

@jabedude
Copy link
Author

The TODOs look good to me! I pushed a commit to query the framebuffer address, but I'm not sure the best way to test that.

Related to the third TODO, how can I get access to the VESAfb variable from load_elf()?

@phil-opp
Copy link
Member

I think we can do the same as in

bootloader/src/main.rs

Lines 66 to 77 in b5d43ca

// Symbols defined in `linker.ld`
extern "C" {
static mmap_ent: usize;
static _memory_map: usize;
static _kernel_start_addr: usize;
static _kernel_end_addr: usize;
static _kernel_size: usize;
static __page_table_start: usize;
static __page_table_end: usize;
static __bootloader_end: usize;
static __bootloader_start: usize;
}
to get access to VESAfb and then pass as argument to load_elf. To use it in the printer, we need to initialize it at runtime with the given framebuffer address, e.g. through an init method.

}
}
}
_ => panic!("unprintable character"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please dont panic in this case. Maybe print ? or something like that.

Copy link

@adeadman adeadman Aug 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.
I realise this code doesn't actually contain a Mutex lock on the writer, so my previous comment is misguided, but generally yes - a substitute character is probably the way to go.

@adeadman
Copy link

I think we can do the same as in

bootloader/src/main.rs

Lines 66 to 77 in b5d43ca

// Symbols defined in `linker.ld`
extern "C" {
static mmap_ent: usize;
static _memory_map: usize;
static _kernel_start_addr: usize;
static _kernel_end_addr: usize;
static _kernel_size: usize;
static __page_table_start: usize;
static __page_table_end: usize;
static __bootloader_end: usize;
static __bootloader_start: usize;
}

to get access to VESAfb and then pass as argument to load_elf. To use it in the printer, we need to initialize it at runtime with the given framebuffer address, e.g. through an init method.

Thinking about this, for flexibility we probably want to load an entire VBEModeInfo struct into the kernel space so we have flexibility for choosing different modes in the bootloader.

The framebuffer mapping to virtual memory currently hardcodes the framebuffer address for qemu and the size for an 800x600x16 mode, so getting it to work with an arbitrary framebuffer address (e.g. from real hardware) using the vbe mode info is a bit harder. I've been working on it on and off for the last couple weeks and am wondering if it would be easier or even possible to do the memory mapping from the rust code, or if it has to be done while in protected mode stage 3 before we jump to the kernel loading.

@ethindp
Copy link
Contributor

ethindp commented Aug 11, 2019 via email

@phil-opp
Copy link
Member

@ethindp See https://github.com/rust-osdev/bootloader/blob/master/doc/chainloading.md and #49. In the future, please just open a new issue instead of commenting on an unrelated issue.

@phil-opp
Copy link
Member

@adeadman

I've been working on it on and off for the last couple weeks and am wondering if it would be easier or even possible to do the memory mapping from the rust code, or if it has to be done while in protected mode stage 3 before we jump to the kernel loading.

If we don't access it before the mapping, we can probably map it later. However, we need to adjust our panic printer for that (i.e. it shouldn't try to print to the VESA framebuffer before it is mapped).

Base automatically changed from master to main February 5, 2021 12:27
@phil-opp
Copy link
Member

phil-opp commented May 22, 2021

Given that the bootloader was changed significantly since this PR (e.g. in #130), I'm going to give this a close. We still don't support choosing custom framebuffer resolutions though, so if anyone wants to tackle this, please let me know!

Thank you @jabedude for all your work!

@phil-opp phil-opp closed this May 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants