Skip to content

VGA video modes #99

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

Closed
RKennedy9064 opened this issue Mar 4, 2020 · 9 comments
Closed

VGA video modes #99

RKennedy9064 opened this issue Mar 4, 2020 · 9 comments

Comments

@RKennedy9064
Copy link
Member

I've finally had some spare time to start working on my OS again and was hoping I might have a chance to give back after all the great work you've done so far. I know there's currently an open issue for VESA video modes #37, but I didn't want to hijack that thread.

Since you have plans for VESA video modes in the future, would you also be interested in adding support for VGA modes? I've just finished a minimal example that has support for switching to 80x25 text mode from the kernel using VGA registers. The current code can be found here https://gist.github.com/RKennedy9064/374ed861f743079e43b1c5da87af63f8.

I was able to successfully boot my OS using the vga_320x200 mode from bootloader, then switch to 80x25 text mode and use the println! macro to display messages again.

I'm not sure if this is on the road map, or even something you're interested in, but if you are I'd love to possible collaborate to include something like this. My plan is to clean up the existing code, add more comments and tests and then try to add more support for additional modes. I figured it would be nice to have the ability to switch video modes from the kernel at run time.

Let me know what you think when you have the time and thanks for all the great work so far on the tutorials!

@phil-opp
Copy link
Member

phil-opp commented Mar 6, 2020

Sounds awesome! I didn't have time to explore VGA/VESA video modes recently, but I think it would be great to have support for them. Being able to switch the video mode from the kernel at run time sounds like an even better approach. So yes, I would love to merge a pull request for this!

If I remember correctly, one reason for exploring additonal video modes was that the VGA text buffer is apparently not supported with UEFI. Since we want to add UEFI support, it would be great to have the same video modes work with both BIOS and UEFI booting. Maybe you know something about this?

@RKennedy9064
Copy link
Member Author

I don't really have much experience with UEFI, but from what I've read it has it's own way of outputting using OutputString, then once you initialize everything and call ExitBootServices you should have full control over the system, with the ability to switch modes by programming the VGA registers. Can anyone with more knowledge of UEFI confirm or deny this?

@RKennedy9064
Copy link
Member Author

I manage to play around with some more modes over the weekend and the results are attached below. One thing to consider if this gets implemented is that we'd need to map some more memory locations in order for the different modes to work. In order to write the font data I needed to access memory locations between 0xb9000 - 0xb9fff. Also, when testing switching modes vga320x200 to any of the test modes, I also had to map 0xb8000 - 0xb9fff since it looks like that location isn't mapped when booting with that feature. My guess is to be safe we'd probably need to map 0xa0000 - 0xbffff if we wanted to be able to support any vga mode.

80x25 Mode
40x25 Mode
40x50 Mode

@phil-opp
Copy link
Member

phil-opp commented Mar 9, 2020

I'm fine with mapping more memory regions. Perhaps we should also export the framebuffer start address in the boot info struct.

@RKennedy9064
Copy link
Member Author

Currently I'm grabbing the framebuffer start address from the miscellaneous register on the graphics controller like so, since the graphics card internally tracks the framebuffer. I was going to store the framebuffer as a field on Vga that gets set anytime a mode is changed so that is always knows which framebuffer to write to.

#[repr(u32)]
enum FrameBuffer {
    GraphicsMode = 0xa0000,
    CgaMode = 0xb8000,
    MdaMode = 0xb0000,
}

fn get_frame_buffer(&mut self) -> *mut u8 {
    let miscellaneous_graphics = self
        .graphics_controller_registers
        .read(GraphicsControllerIndex::Miscellaneous);
    let memory_map_mode = (miscellaneous_graphics >> 0x2) & 0x3;
    let frame_buffer = FrameBuffer::from(memory_map_mode);
    u32::from(frame_buffer) as *mut u8
}

My original plan was to create a trait with a few helper methods such as write_byte and write_pixel, then expose a few methods on Vga that would allow a user to write a character, or pixel data to the screen based on the mode. It could grab the framebuffer from Vga, and based on the mode perform writes as implemented by the trait for each mode.

I'd like to get one graphics mode mapped out, but after that I'd be ready to create an initial PR for review/improvement/cleanup. Do you have any naming conventions you'd like to follow? I know everything is under video_mode currently. Right now I have everything under a vga folder, with files named vga_font, vga_registers, etc.

@phil-opp
Copy link
Member

phil-opp commented Mar 9, 2020

I'd like to get one graphics mode mapped out, but after that I'd be ready to create an initial PR for review/improvement/cleanup.

Sounds great!

Do you have any naming conventions you'd like to follow? I know everything is under video_mode currently. Right now I have everything under a vga folder, with files named vga_font, vga_registers, etc.

I don't think that we have any particular conventions to follow (apart from the Rust typical conventions). Also, we can always clean things up in future PRs if necessary. Thanks a lot for your work!

@RKennedy9064 RKennedy9064 mentioned this issue Mar 11, 2020
@RKennedy9064
Copy link
Member Author

@phil-opp I created my initial PR #102 for feedback/improvements/cleanup when you have a chance to review it.

@RKennedy9064
Copy link
Member Author

I made a PR for mapping the memory regions here #104. If everything looks good I can close this and the PR #102 since it's now its own crate.

@RKennedy9064
Copy link
Member Author

This is now part of https://github.com/rust-osdev/vga

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

No branches or pull requests

2 participants