Page 1 of 1

Rust-based kernel isn't drawing anything to the screen

Posted: Fri Nov 25, 2022 4:11 pm
by ThatCodingGuy89
Said kernel is from this repo in src/kernel/core/main.rs

The bit of code that actually draws to the screen is this:

Code: Select all

pub extern "C" fn _start(framebuffer_info: FramebufferInfo, memory_map: *const MemoryDescriptor) -> ! {
    let framebuffer = framebuffer_info.base_address as *mut u32;
    let pitch = framebuffer_info.pitch;

    unsafe {
        *framebuffer.offset((4 * pitch * 20 + 4 * 20) as isize) = 0xFFFFFFFF;
        *framebuffer.offset((4 * pitch * 20 + 4 * 21) as isize) = 0xFFFFFFFF;
        *framebuffer.offset((4 * pitch * 20 + 4 * 22) as isize) = 0xFFFFFFFF;
        *framebuffer.offset((4 * pitch * 20 + 4 * 23) as isize) = 0xFFFFFFFF;
        *framebuffer.offset((4 * pitch * 21 + 4 * 20) as isize) = 0xFFFFFFFF;
        *framebuffer.offset((4 * pitch * 22 + 4 * 21) as isize) = 0xFFFFFFFF;
        *framebuffer.offset((4 * pitch * 23 + 4 * 22) as isize) = 0xFFFFFFFF;
        *framebuffer.offset((4 * pitch * 24 + 4 * 23) as isize) = 0xFFFFFFFF;
    }

    loop {}
}
Which is based on the previous C based kernel (in the same repo and directory mentioned earlier)

Code: Select all

int k_main(framebuffer_info_s framebuffer, memory_descriptor_s* memory_map)
{
    framebuf = framebuffer;
    memMap = memory_map;

    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 20 + 4 * 20)) = 0xFFFFFFFF;
    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 20 + 4 * 21)) = 0xFFFFFFFF;
    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 20 + 4 * 22)) = 0xFFFFFFFF;
    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 20 + 4 * 23)) = 0xFFFFFFFF;
    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 21 + 4 * 20)) = 0xFFFFFFFF;
    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 22 + 4 * 21)) = 0xFFFFFFFF;
    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 23 + 4 * 22)) = 0xFFFFFFFF;
    *((uint32_t*)(framebuf.base_address + 4 * framebuf.pitch * 24 + 4 * 23)) = 0xFFFFFFFF;

    while(true) {}
}
Which does work.

What is it about the Rust code that causes the same operation to not work?
I have genuinely no idea. Is it a toolchain problem? (I've had quite a few of those, so I wouldn't be surprised.) Is it me being an idiot and not understanding how to translate the operation in C into Rust syntax?

Edit: I figured out why it isn't displaying anything. In the "serial0" console in QEMU it's displaying a "Invalid Opcode" error. This sounds like a toolchain problem, but what it could be, I have no idea.
Here's a screenshot of the error:
https://imgur.com/a/jOwo57U

Re: Rust-based kernel isn't drawing anything to the screen

Posted: Sat Nov 26, 2022 12:33 am
by iansjack
Have you done any debugging? Are you sure that framebuffer is really pointing to your frame buffer? If you run under gdb you should be able to check this and try modifying a few addresses in the frame buffer to see what happens.

Re: Rust-based kernel isn't drawing anything to the screen

Posted: Sat Nov 26, 2022 7:18 am
by eekee
Are you sure that code actually runs? A bad jump address or a return with garbage on the stack makes the CPU "jump off into the wild blue yonder," as we used to say. :) gdb can help discover that too, though if you can print to the serial port, that can help too, in this case.

Re: Rust-based kernel isn't drawing anything to the screen

Posted: Sat Nov 26, 2022 7:35 am
by iansjack
Yes, I would doubt that it's a problem in the toolchain. Many people use Rust successfully to do this sort of thing (I certainly never had any problems writing to a frame buffer when I was playing with Rust). But any time you are using "unsafe" code it is very easy to mess things up; even more so if you are using inline assembler.

I know that toolchains do have bugs, but it's sensible to leave that possibility as a last resort when every other potential cause has been investigated. The problem with blaming the tools is that you are giving up and saying "it's not a problem with my code", in which case you are very unlikely to fix the error.