Closed Merlin1846 closed 2 years ago
Also sorry if I'm not supposed to put this here but I couldn't think of a place to write a help message since if I, for example, put it on stack exchange then chances are it would get drowned out and even if someone saw it they probably wouldn't be using this crate/library/tool (never know what to call these things.)
Well I changed the frame_buffer getter to this.
let mut frame_buffer:&mut FrameBuffer = &mut boot_info.framebuffer.as_mut().unwrap();
Ok, so I did this.
let frame_buffer:&mut FrameBuffer = &mut boot_info.framebuffer.as_mut().unwrap();
let frame_buffer_data:&mut [u8] = frame_buffer.buffer_mut();
for i in frame_buffer_data.iter_mut() {
*i = 0xC0 as u8;
}
loop {}
But it appears to be grayscale even though the hexadecimal value should be maxed out Red or Max Blue since I believe it's running in BGR.
The framebuffer probably uses 24bit and not 8bit colors. This means that every group of 3 (or 4 depending on the color format used) bytes represents a single pixel with each byte being a different channel.
But the frame_buffer.buffer_mut() only returns u8, unless I'm misunderstanding and I have to set one u8 then the next to the green channel, and then the next to the blue channel? But that doesn't make sense since if I add a counter that counts how many times it's activated and tell it to stop at 1366 it does a single full-length line, which would mean that each pixel is a single u8 right? I think I am misunderstanding something major.
Ok so I did what you suggested and it almost worked? Only the words changed color. But then I set v2 to 0xFF and then the entire thing changed but it looked odd, I don't know how to describe it.
let v1:u8 = 0xFF as u8;
let v2:u8 = 0x00 as u8;
let v3:u8 = 0x00 as u8;
let mut counter:u8 = 0;
for i in frame_buffer_data.iter_mut() {
match counter {
0 => {*i = v1},
1 => {*i = v2},
2 => {*i = v3},
_ => {counter = 0},
}
counter += 1;
}
This works but now I have a new adventure, make it so that things other than the yellow but now blue words change color.
#[no_mangle]
pub extern "C" fn _start(boot_info: &'static mut BootInfo) -> ! {
let frame_buffer:&mut FrameBuffer = &mut boot_info.framebuffer.as_mut().unwrap(); // Get a mut reference to the frame buffer.
let frame_buffer_data:&mut [u8] = frame_buffer.buffer_mut();
let v1:u8 = 0xFF as u8;
let v2:u8 = 0x00 as u8;
let v3:u8 = 0x00 as u8;
let v4:u8 = 0xFF as u8;
let mut counter:u8 = 0;
for i in frame_buffer_data.iter_mut() {
match counter {
0 => {*i = v1},
1 => {*i = v2},
2 => {*i = v3},
3 => {*i = v4},
_ => {counter = 0},
}
counter += 1;
}
loop {}
}
[...] and I have to set one u8 then the next to the green channel, and then the next to the blue channel?
For the RGB you have to do that. For the BGR the channels are in the opposite order. For the U8 pixel format every byte is a single grayscale pixel.
You can look at the pixel_format
field of frame_buffer.info()
to know which pixel format to use.
But that doesn't make sense since if I add a counter that counts how many times it's activated and tell it to stop at 1366 it does a single full-length line, which would mean that each pixel is a single u8 right?
Maybe the screen is 455 pixels wide? (1366/3 = 455) Note that resizing the qemu window does not resize the framebuffer.
Ok so I did what you suggested and it almost worked? Only the words changed color. But then I set v2 to 0xFF and then the entire thing changed but it looked odd, I don't know how to describe it.
let v1:u8 = 0xFF as u8; let v2:u8 = 0x00 as u8; let v3:u8 = 0x00 as u8; let mut counter:u8 = 0; for i in frame_buffer_data.iter_mut() { match counter { 0 => {*i = v1}, 1 => {*i = v2}, 2 => {*i = v3}, _ => {counter = 0}, } counter += 1; }
That code skips the 0 => { *i = v1 },
arm due to counter
being incremented immediately after setting it to 0. In addition I just read that you have to step bytes_per_pixel
bytes every time with all bytes after the first 3 being ignored. Try
// FIXME move next statement before let frame_buffer_data:&mut [u8] = frame_buffer.buffer_mut();
let bytes_per_pixel = frame_buffer.info().bytes_per_pixel;
let v1:u8 = 0xFF as u8;
let v2:u8 = 0x00 as u8;
let v3:u8 = 0x00 as u8;
for pixel in frame_buffer_data.chunks_mut(bytes_per_pixel) {
*pixel[0] = v1;
*pixel[1] = v2;
*pixel[2] = v3;
}
Ok, I'll try that, also I'm not using qemu I have a physical computer.
Well the code worked perfectly, the entire screen is blue, and now I can get on with writing a graphics driver.
I've been attempting to edit the frame buffer but no matter what I do I can not get a single output from anything it just sits there with yellow words, I'm running this on a physical machine and using UEFI. This is my code hope someone knows what's wrong, or rather what's missing.