sebihepp wrote: ↑Tue Sep 03, 2024 4:42 am
Code: Select all
let vga_video_buffer_frame_end = Frame::containing_address((mem_info.vga_vide_start + mem_info.vga_vide_size*3));
Here you assume the video buffer has a size of vga_vide_size*3 - but you didn't check the bpc (bits per color) field of the multiboot2 info. Maybe your Framebuffer is setup to use only 16 bpc or even 32 bpc.
If you use this, you can skip the multiply by 3.
Code: Select all
let vga_video_buffer_frame_end = Frame::containing_address((mem_info.vga_vide_start + <pitch> * <height>));
Also make sure you set the pages to WriteThrough, otherwise you written stuff remains in the processors cache and wont be written to the memory directly.
I did fix this without saying anything here! I now use bpp to calculate how big the buffer is, i did add WRITE_THROUGH though.
Heres the new updated code for the framebuffer remap (the calculation itself was earlier in the execution in mem/mod.rs)
Code: Select all
// mem/mod.rs:152
let vv_info = boot_info.framebuffer_tag().unwrap().unwrap();
let vv_start = vv_info.address();
let vv_size = vv_info.pitch() * vv_info.height();
// mem/heap/paging/mod.rs:211
let vga_video_buffer_frame_start = Frame::containing_address(mem_info.vga_vide_start);
let vga_video_buffer_frame_end = Frame::containing_address(mem_info.vga_vide_start + mem_info.vga_vide_size);
for frame in Frame::range_inclusive(vga_video_buffer_frame_start, vga_video_buffer_frame_end) {
mapper.identity_map(frame, EntryFlags::WRITABLE | EntryFlags::WRITE_THROUGH, allocator);
}
iansjack wrote: ↑Tue Sep 03, 2024 6:01 am
Try this version of set_px:
Code: Select all
pub fn set_px(&self, x: usize, y: usize, c: Color) {
let ptr = self.buf_addr as *mut () as *mut u8;
let px = ptr.wrapping_add(4 * x + 0x1000 * y);
unsafe {
*px.wrapping_add((self.r_ofs % 8) as usize) = c.r;
*px.wrapping_add((self.g_ofs % 8) as usize + 1) = c.g;
*px.wrapping_add((self.b_ofs % 8) as usize + 2) = c.b;
}
}
Obviously you need to work out what the magic numbers should be rather than using the ones I have hard-coded (which should work for the mode you set). I'll leave you to work out why those numbers work.
As an aside, I tried using Rust for a kernel but, in the end, I found it was just too much hard work fighting against the language, particularly;y as it is in such a state of flux. What works today won't work tomorrow. I feel that most of the advantages of Rust are lost because you need to use many "unsafe" blocks, which makes the whole thing more complicated - and harder to debug - than simple C or C++.
Just my opinion.
Oh my god im actually stupid, thank you.
For one, i was mod'ing the offsets instead of dividing for some reason (to be fair it was in the middle of the night)
And the pixel location calculation works now!
This is the updated set_px function:
Code: Select all
pub fn set_px(&self, x: usize, y: usize, c: Color) {
assert!(x <= self.size.x && y <= self.size.x);
let ptr = self.buf_addr as *mut () as *mut u8;
let px = ptr.wrapping_add((self.bpp / 8) as usize * x + self.pitch * y);
unsafe {
*px.wrapping_add((self.r_ofs / 8) as usize) = c.r;
*px.wrapping_add((self.g_ofs / 8) as usize) = c.g;
*px.wrapping_add((self.b_ofs / 8) as usize) = c.b;
}
}
On the rust thing:
I get where youre coming from, i love coding in c, its really nice. Its an amazing language but i just prefer rust because i consider myself better in it.And i love the features i get, especially macros (that are a lot diffrent from C's). Although it gets tiresome to write a lot of the quite verbose syntax in rust. TLDR, both languages are amazing, but they have diffrent places that they fill.
Oh and. One last thing. Thanks you all. Honestly an amazing experience asking my first question here.
(Except the register captcha question. That one sucked)
As always, code is here:
https://git.mcorangehq.xyz/XOR64/poppin/