rust-osdev/bootloader

After timer interrupt i have double fault.

Fidius-jko opened this issue · 4 comments

code:
https://github.com/Fidius-jko/catium_os/tree/master
I combined code from the third edition and from the second (before memory managment)

This issue is not caused by the bootloader so the issue tracker for the bootloader is probably not the correct place to ask for help.

That said, your GDT is lacking a data segment for the stack segment register. After the interrupt handler finishes serving the first timer interrupt, it exits with iretq. Among other things, iretq loads the previous stack segment selector from the stack and implicitly reloads the corresponding segment from the GDT. In your case, this fails because you don't have a data segment in the GDT. This can be fixed by adding a data segment to the GDT and setting up the ss stack segment selector. The following patches fix this issue:

diff --git a/kernel/src/arch/x86_64/gdt.rs b/kernel/src/arch/x86_64/gdt.rs
index c07b310..5f82e62 100644
--- a/kernel/src/arch/x86_64/gdt.rs
+++ b/kernel/src/arch/x86_64/gdt.rs
@@ -1,4 +1,5 @@
 use lazy_static::lazy_static;
+use x86_64::registers::segmentation::SS;
 use x86_64::structures::tss::TaskStateSegment;
 use x86_64::VirtAddr;
 
@@ -26,11 +27,13 @@ lazy_static! {
     static ref GDT: (GlobalDescriptorTable, Selectors) = {
         let mut gdt = GlobalDescriptorTable::new();
         let code_selector = gdt.add_entry(Descriptor::kernel_code_segment());
+        let data_selector = gdt.add_entry(Descriptor::kernel_data_segment());
         let tss_selector = gdt.add_entry(Descriptor::tss_segment(&TSS));
         (
             gdt,
             Selectors {
                 code_selector,
+                data_selector,
                 tss_selector,
             },
         )
@@ -39,6 +42,7 @@ lazy_static! {
 
 struct Selectors {
     code_selector: SegmentSelector,
+    data_selector: SegmentSelector,
     tss_selector: SegmentSelector,
 }
 
@@ -48,6 +52,7 @@ pub fn init() {
     GDT.0.load();
     unsafe {
         CS::set_reg(GDT.1.code_selector);
+        SS::set_reg(GDT.1.data_selector);
         load_tss(GDT.1.tss_selector);
     }
 }

Thank you, where can I post questions about rust osdev?

Thank you, where can I post questions about rust osdev?

If you have questions closely related to the content of the blog OS, there's https://github.com/phil-opp/blog_os/discussions. For more general questions, there's also the OSDev Forum and the r/osdev subreddit. Last but not least, you can ask questions on StackOverflow.