Unable to Write/Read from Framebuffer multiboot2
Posted: Sun Jan 19, 2025 7:28 am
Hello,
I've encountered a problem when trying to access the framebuffer address `0xFD000000`, which is parsed from the boot_info from the EBX register.
My OS seems to halt when trying to execute a read/write operation on the pointer.
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... in.rs#L172)
I've identity mapped the whole framebuffer to virtual addresses in a manner like this:
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... fer.rs#L95)
As of my research, the multiboot2 is responsible for allocating the physical memory. Mapping it to virtual should be enough to access it accordingly.
My header.asm file:
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... header.asm)
At some point while testing with the embedded_graphics framebuffer i managed to get a PageFault like this:
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... in.rs#L198)
Any comments on the topic would be highly appreciated,
Thank you in advanced!
I've encountered a problem when trying to access the framebuffer address `0xFD000000`, which is parsed from the boot_info from the EBX register.
My OS seems to halt when trying to execute a read/write operation on the pointer.
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... in.rs#L172)
Code: Select all
unsafe { // halts on the first println
println!("Pixel value before: {:#x}", *(framebuffer_virt_addr.as_mut_ptr::<u32>()));
*(framebuffer_virt_addr.as_mut_ptr::<u32>()) = 0x00FF00; // Set to green
println!("Pixel value after: {:#x}", *(framebuffer_virt_addr.as_mut_ptr::<u32>()));
}
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... fer.rs#L95)
Code: Select all
pub fn map_framebuffer(
framebuffer_phys_addr: PhysAddr,
framebuffer_size: u64,
framebuffer_virt_addr: VirtAddr,
mapper: &mut OffsetPageTable,
frame_allocator: &mut BootInfoFrameAllocator,
) -> Result<(), &'static str> {
if framebuffer_phys_addr.as_u64() % 4096 != 0 || framebuffer_virt_addr.as_u64() % 4096 != 0 {
panic!("Framebuffer addresses must be 4KiB aligned.");
}
let framebuffer_start_page: Page<Size4KiB> = Page::containing_address(framebuffer_virt_addr);
let framebuffer_end_page: Page<Size4KiB> = Page::containing_address(
framebuffer_virt_addr + framebuffer_size as u64 - 1u64
);
let mut current_page = framebuffer_start_page;
while current_page <= framebuffer_end_page {
let frame = PhysFrame::containing_address(framebuffer_phys_addr + (current_page.start_address().as_u64() - framebuffer_virt_addr.as_u64()));
let flags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE | PageTableFlags::NO_CACHE;
unsafe {
mapper.map_to(current_page, frame, flags, frame_allocator)
.expect("Frame allocation failed in map_framebuffer")
.flush();
}
current_page += 1;
}
Ok(())
}
My header.asm file:
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... header.asm)
Code: Select all
SECTION .multiboot_header
ALIGN 8
header_start:
; Multiboot2 magic number
DD 0xE85250D6 ; Magic number
; Architecture (protected mode i386)
DD 0
; Header length
DD header_end - header_start
; Checksum
DD -(0xE85250D6 + 0 + (header_end - header_start))
; Console Flags Tag
ALIGN 8
DW 4 ; Tag type: Console flags
DW 0 ; Flags: Optional
DD 12 ; Size of this tag
DD 1 ; Console flags (Bit 0 set)
; Framebuffer Tag
ALIGN 8
DW 5 ; Tag type: Framebuffer
DW 0 ; Flags: Optional
DD 20 ; Size of this tag
DD 1280 ; Preferred framebuffer width
DD 720 ; Preferred framebuffer height
DD 32 ; Preferred bits per pixel
; End Tag
ALIGN 8
DD 0 ; Tag type: End tag
DD 8 ; Size of end tag
header_end:
At some point while testing with the embedded_graphics framebuffer i managed to get a PageFault like this:
(referenced from here - https://github.com/Mrgoblings/AnasOS/bl ... in.rs#L198)
Code: Select all
EXCEPTION: PAGE FAULT
Accessed Address: VirtAddr(0xfd0466e0)
Error Code: PageFaultErrorCode(CAUSED_BY_WRITE)
InterruptStackFrame {
instruction_pointer: VirtAddr(
0x12122c,
),
code_segment: 8,
cpu_flags: 0x200206,
stack_pointer: VirtAddr(
0x12e648,
),
stack_segment: 0,
}
Any comments on the topic would be highly appreciated,
Thank you in advanced!