From e51a78eba195380e02a28b8dc7e2bfce617fbc08 Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Sun, 19 Jan 2014 21:46:50 +0100 Subject: [PATCH] Tests --- kernel/include/gdt.hpp | 2 ++ kernel/src/boot/boot_16.cpp | 16 +++++++++++----- kernel/src/gdt.cpp | 2 +- kernel/src/interrupts.cpp | 21 ++++++++++----------- kernel/src/shell.cpp | 8 ++++++-- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/kernel/include/gdt.hpp b/kernel/include/gdt.hpp index f80a5cc9..63781c9c 100644 --- a/kernel/include/gdt.hpp +++ b/kernel/include/gdt.hpp @@ -106,6 +106,8 @@ struct task_state_segment_t { uint16_t io_map_base_address; }; +extern task_state_segment_t tss; + void flush_tss(); } //end of namespace gdt diff --git a/kernel/src/boot/boot_16.cpp b/kernel/src/boot/boot_16.cpp index e90afe54..01d4a9f8 100644 --- a/kernel/src/boot/boot_16.cpp +++ b/kernel/src/boot/boot_16.cpp @@ -35,6 +35,9 @@ constexpr const uint16_t DEFAULT_BPP = 32; #define CODE_16 #include "gdt.hpp" +//The Task State Segment +gdt::task_state_segment_t gdt::tss; + #include "e820.hpp" //Just for the address of the e820 map e820::bios_e820_entry e820::bios_e820_entries[e820::MAX_E820_ENTRIES]; @@ -350,9 +353,6 @@ gdt::gdt_descriptor_t user_data_descriptor(){ return descriptor; } -//The Task State Segment -static gdt::task_state_segment_t tss; - //TODO On some machines, this should be aligned to 16 bits static gdt::gdt_descriptor_t gdt[8]; @@ -369,7 +369,7 @@ void setup_gdt(){ //2. Init TSS Descriptor - uint32_t base = reinterpret_cast(&tss); + uint32_t base = reinterpret_cast(&gdt::tss); uint32_t limit = base + sizeof(gdt::task_state_segment_t); auto tss_selector = reinterpret_cast(&gdt[6]); @@ -387,7 +387,7 @@ void setup_gdt(){ tss_selector->base_high = 0; //Top 32 bits are clear tss_selector->limit_low = limit & 0xFFFF; //Low 16 bits - tss_selector->limit_high = (limit&0xF0000) >> 16; //Top 4 bits + tss_selector->limit_high = (limit & 0xF0000) >> 16; //Top 4 bits //3. Init the GDT Pointer @@ -397,6 +397,12 @@ void setup_gdt(){ //4. Load the GDT asm volatile("lgdt [%0]" : : "m" (gdtr)); + + //5. Zero-out the TSS + auto tss_ptr = reinterpret_cast(&gdt::tss); + for(unsigned int i = 0; i < sizeof(gdt::task_state_segment_t); ++i){ + *tss_ptr++ = 0; + } } void protected_mode_enable(){ diff --git a/kernel/src/gdt.cpp b/kernel/src/gdt.cpp index 858aafe2..860e7756 100644 --- a/kernel/src/gdt.cpp +++ b/kernel/src/gdt.cpp @@ -8,5 +8,5 @@ #include "gdt.hpp" void gdt::flush_tss(){ - asm volatile("mov ax, 0x33; ltr ax;" : : : "rax"); + asm volatile("mov ax, %0; ltr ax;" : : "i" (gdt::TSS_SELECTOR + 0x3) : "rax"); } diff --git a/kernel/src/interrupts.cpp b/kernel/src/interrupts.cpp index 697bdfc6..b4940a45 100644 --- a/kernel/src/interrupts.cpp +++ b/kernel/src/interrupts.cpp @@ -154,17 +154,16 @@ void install_irqs(){ } void install_syscalls(){ - idt_set_gate(interrupt::SYSCALL_FIRST, _syscall0, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+1, _syscall1, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+2, _syscall2, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+3, _syscall3, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+4, _syscall4, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+5, _syscall5, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+6, _syscall6, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+7, _syscall7, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+8, _syscall8, gdt::LONG_SELECTOR, 0x8E); - idt_set_gate(interrupt::SYSCALL_FIRST+9, _syscall9, gdt::LONG_SELECTOR, 0x8E); - + idt_set_gate(interrupt::SYSCALL_FIRST, _syscall0, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+1, _syscall1, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+2, _syscall2, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+3, _syscall3, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+4, _syscall4, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+5, _syscall5, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+6, _syscall6, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+7, _syscall7, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+8, _syscall8, gdt::LONG_SELECTOR, 0xEE); + idt_set_gate(interrupt::SYSCALL_FIRST+9, _syscall9, gdt::LONG_SELECTOR, 0xEE); } void enable_interrupts(){ diff --git a/kernel/src/shell.cpp b/kernel/src/shell.cpp index bba6b794..956d31a7 100644 --- a/kernel/src/shell.cpp +++ b/kernel/src/shell.cpp @@ -911,12 +911,16 @@ void exec_command(const std::vector& params){ auto stack_physical = allocate_user_stack(0x500000, paging::PAGE_SIZE * 2, paging::PRESENT | paging::WRITE | paging::USER); if(stack_physical){ - asm volatile("cli; mov ax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;" + uint64_t rsp; + asm volatile("mov %0, rsp;" : "=m" (rsp)); + gdt::tss.rsp0 = rsp; + + asm volatile("mov ax, %0; mov ds, ax; mov es, ax; mov fs, ax; mov gs, ax;" : //No outputs : "i" (gdt::USER_DATA_SELECTOR + 3) : "rax"); - asm volatile("push %0; push %1; pushfq; push %2; push %3; xchg bx, bx; iretq" + asm volatile("push %0; push %1; pushfq; push %2; push %3; iretq" : //No outputs : "i" (gdt::USER_DATA_SELECTOR + 3), "i" (0x500000 + paging::PAGE_SIZE * 2 - 64), "i" (gdt::USER_CODE_SELECTOR + 3), "r" (header->e_entry) : "rax");