开发者

Triple fault in home grown kernel

I am trying to write a kernel, mostly for entertainment purposes, and I am running into a problem were I believe it is triple faulting. Everything worked before I attempted to enable paging. The code that is breaking is this:

void switch_page_directory(page_directory_t *dir){

 current_directory = dir;
 asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));

 u32int cr0;
 asm volatile("mov %%cr0, %0": "=r"(cr0));

 cr0 |= 0x80000000;//enable paging
 asm volatile("mov %0, %%cr0":: "r"(cr0)); //this line breaks


}//switch page directory

I have been following a variety of tutorials / documents for this but the one I am using to paging is thus http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html . I am not sure what other code will be useful in figuring this out but if there is more I should provide I will be more than happy to do so.

Edit=====

I believe the CS,DS and SS are selecting correct entries here's the code used to set them

global gdt_flush     
e开发者_开发知识库xtern gp            
gdt_flush:

    lgdt [gp]        ; Load the GDT with our 'gp' which is a special pointer
    mov ax, 0x10      ; 0x10 is the offset in the GDT to our data segment

    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax

    jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!

flush2:
    ret               ; Returns back to the C code!

and here's the gdt struct itself

struct gdt_entry{
    unsigned short limit_low;
    unsigned short base_low;
    unsigned char base_middle;
    unsigned char access;
    unsigned char granularity;
    unsigned char base_high;
} __attribute__((packed));

struct gdt_ptr{
    unsigned short limit;
    unsigned int base;
} __attribute__((packed));

struct gdt_entry gdt[5];
struct gdt_ptr gp;

The IDT is very similar to this.


GDT: you don't say what the contents of the GDT entries are, but the stuff you've shown looks fairly similar to the earlier part of the tutorial you linked to and if you've set up the entries in the same way, then all should be well (i.e. flat segment mapping with a ring 0 code segment for CS, ring 0 data segment for everything else, both with a base of 0 and a limit of 4GB).

IDT: probably doesn't matter anyway if interrupts are disabled and you're not (yet) expecting to cause page faults.

Page tables: incorrect page tables do seem like the most likely suspect. Make sure that your identity mapping covers all of the code, data and stack memory that you're using (at least).

The source code linked to at the bottom of http://www.jamesmolloy.co.uk/tutorial_html/6.-Paging.html definitely builds something that does work correctly with both QEMU and Bochs, so hopefully you can compare what you're doing with what that's doing, and work out what is wrong.

QEMU is good in general, but I would recommend Bochs for developing really low-level stuff - it includes (or can be configured to include) a very handy internal debugger. e.g. set reset_on_triple_fault=0 on the cpu: line of the config file, set a breakpoint in the switch_page_directory() code, run to the breakpoint, then single step instructions and see what happens...


You can link qemu to a gdb debugger session via the remote debugger tools in gdb. This can be done by issuing the following commands:

qemu -s [optional arguments]

Then inside your gdb session, open your kernel executable, and after setting a break-point in your switch_page_directory() function, type in the following command at the gdb prompt:

target remote localhost:1234

You can then single-step through your kernel at the breakpoint, and see where your triple-fault is taking place.

Another step to consider is to actually install some default exception handlers in your IDT ... the reason you are triple-faulting is because an exception is being thrown by the CPU, but there is no proper exception handler available to handle it. Thus with some default handlers installed, especially the double-fault handler, you can effectively stop the kernel without going into a triple-fault that automatically resets the PC.

Finally, make sure you have re-programmed the PIC before going into protected mode ... otherwise the default hardware interrupts it's programmed to trigger from the BIOS in real-mode will now trigger the exception interrupts in protected mode.


I was also facing the same problem with paging tutorial.But after some searching i found the solution it was happening because as soon as paging is enabled, all address become virtual and to solve it we must map the virtual addresses to the same physical addresses so they refer to the same thing and this is called identity mapping.

you can follow this link for further help in implementing Identity Maping.

and one more thing you have memset the newly allocated space to zero because it may contain garbage values and memset was not done in tutorial it will work on bochs because it set the space to zero for you but other emulator(qemu) and real hardware are so kind.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜