cfenollosa / os-tutorial

How to create an OS from scratch
BSD 3-Clause "New" or "Revised" License
27.25k stars 3.3k forks source link

How about loading a C++ kernel #144

Open pa5h1nh0 opened 4 years ago

pa5h1nh0 commented 4 years ago

Hi, hope you're well in this rough period. First of all let me thank you for your amazing tutorial, it's just so great.

Now back to the question. This is my issue, there's nothing wrong with your code, but I'd really really appreciate any help or hint. So, I successfully followed and replicated your #13 "kernel-barebones" tutorial, and then I tried to do the same exact thing but with C++ code, unfortunately failing in that Qemu doesn't print the debug string from the C++ kmain() function. I obviously don't expect you to know what may be wrong here, but if in any case you or someone does have an explanation, please let me know.

Follows the C++ code:

extern "C"
{

void dummy_test_entrypoint() {}

void kmain(void)
{
    static const void *video_buf{ (void*)0xb8000 };

    static constexpr short color{ 0x0f00 };
    static constexpr char hello[]{
        "Hello kernel from cpp!" };
    short *vga{ (short *)video_buf };
    unsigned len{ sizeof(hello) };

    // max chars per row
    static constexpr unsigned max_row_chars{ 80 };

    // print at the 2nd line
    static constexpr int row{ 1 };

    for (unsigned i = 0; i < len; i++)
    {
        unsigned vga_idx{ (row*max_row_chars) + i };
        vga[vga_idx] = (color | hello[i]);
    }
}

}

It successfully builds with the follwing cmd:

g++ -m32 kmain.cpp -o kernel.o -nostdlib -ffreestanding -std=c++17 -mno-red-zone -fno-exceptions -fno-rtti

Then proceeding with the same exact steps as in your tutorial. However, when running the kernel image with Qemu, there's no "Hello kernel from cpp!" string printed. Any idea what might be wrong here? Oh, and I obviously updated kernel_entry.asm as:

extern kmain
call kmain

Thank you

Menotdan commented 4 years ago

Ok so, step one. Launch GDB. Step two, break on the call. Then figure out where the call goes to. Then report back here. Also, this tutorial compiles everything to a flat binary (which is annoying, you should follow bare-bones on the OSdev wiki, use the GRUB bootstrap here and the rest of the stuff here, also you should really use a cross-compiler. After that, you should do x86_64 and paging and whatnot.), so you can x/<n>i in GDB to figure out what instruction the call is on. Then from there, you can keep stepping in the kmain, if you even get there, until the print, etc. until you find the problem.