[x86] Did some various fixes to the ATA driver

[dummy] Removed useless code files from dummy
[x86] Moved Tasks to ring 3.
This commit is contained in:
Morten Delenk 2016-04-15 22:04:01 +02:00
parent 2104685d55
commit fe979e8774
17 changed files with 73 additions and 226 deletions

View file

@ -1,15 +0,0 @@
.section multiboot
#define MB_MAGIC 0x1BADB002
#define MB_FLAGS 0x0
#define MB_CHECKSUM -(MB_MAGIC + MB_FLAGS)
.align 4
.int MB_MAGIC
.int MB_FLAGS
.int MB_CHECKSUM
.section .text
.extern init
.global _start
_start:
.section .bss
.space 8192
kernel_stack:

View file

@ -8,6 +8,7 @@ namespace MTGosHAL {
class Screen; class Screen;
class Keyboard; class Keyboard;
class Multitasking; class Multitasking;
class BlockDevice;
enum class BG_color: uint16_t; enum class BG_color: uint16_t;
enum class FG_color: uint16_t; enum class FG_color: uint16_t;
extern Serial debug; extern Serial debug;
@ -15,5 +16,6 @@ namespace MTGosHAL {
extern Screen err; extern Screen err;
extern Keyboard in; extern Keyboard in;
extern Multitasking tasks; extern Multitasking tasks;
extern BlockDevice disk;
} }
#endif #endif

View file

@ -0,0 +1,20 @@
#ifndef __HAL_BLOCKDEV_HPP
#define __HAL_BLOCKDEV_HPP
#include <stdint.h>
namespace MTGosHAL {
class BlockDevice {
private:
uint8_t numDevices;
public:
BlockDevice();
~BlockDevice();
auto getDriveCnt() -> int32_t;
auto getDriveNumByName(const char *) -> int32_t; //Returns -1 if device is not existent
auto readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void; //Has to be at least 512 bytes big!
auto readSectors(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
};
}
#endif /* end of include guard: __HAL_BLOCKDEV_HPP */

View file

@ -1,36 +0,0 @@
#include <base.hpp>
#include <textDISP.hpp>
#include <Multitasking.h>
#include <serial.hpp>
/*auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
return MTGosHAL::tasks.schedule(cpu);
}*/
namespace MTGosHAL {
Multitasking::Multitasking(): current_task(-1), num_tasks(2)
{
task_states[0] = initTask(stack_a, task_a);
task_states[1] = initTask(stack_b, task_b);
}
auto Multitasking::initTask(uint8_t* stck, void(* entry)()) -> struct cpu_state*
{
return nullptr;
}
auto Multitasking::task_a() -> void
{
while(true)
out << "A";
}
auto Multitasking::task_b() -> void
{
while(true)
out << "B";
}
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
{
return nullptr;
}
} // namespace MTGosHAL

View file

@ -1,32 +0,0 @@
#include <base.hpp>
#include <output.hpp>
#include <serial.hpp>
#include <textDISP.hpp>
#include <keyboard.hpp>
#include <Multitasking.h>
extern "C" void intr_stub_0(void);
namespace MTGosHAL {
Serial debug;
Screen out;
Screen err;
Keyboard in;
Multitasking tasks;
void main() {
out << BG_color::BLACK << FG_color::WHITE << "Loading MTGos...\n";
err << BG_color::BLACK << FG_color::RED;
debug << "Hello debugger! This is MTGos v00r01\nThese logs are probably very long, so please redirect the output to a file.\n";
for(;;);
}
}
typedef void (*constructor)();
extern "C" constructor start_ctors;
extern "C" constructor end_ctors;
extern "C" void init() {
for(constructor* i = &start_ctors; i != &end_ctors; ++i)
(*i)();
MTGosHAL::main();
}
extern "C" void __cxa_pure_virtual() {
MTGosHAL::debug << "A pure virtual function just got called.\n";
}

View file

@ -1,20 +0,0 @@
#include <base.hpp>
#include <output.hpp>
#include <serial.hpp>
#include <keyboard.hpp>
#include <keymap_DE.hpp>
auto handleIRQ(struct cpu_state* cpu) -> struct cpu_state* {
return cpu;
}
namespace MTGosHAL {
auto Keyboard::getChar() -> char {
return '\0';
}
auto Keyboard::sendCommand(uint8_t command) -> void {
}
auto Keyboard::handleIRQ1(struct cpu_state* cpu) -> struct cpu_state* {
return cpu;
}
Keyboard::Keyboard(): numlock(true), capslock(false), scrolllock(false), response(false) {
}
}

View file

@ -1,39 +0,0 @@
#include <base.hpp>
#include <output.hpp>
#include <serial.hpp>
#include <textDISP.hpp>
namespace MTGosHAL {
auto Output::puts(const char* s) -> void {
int i=0;
while(s[i]!='\0')
putChar(s[i++]);
}
template <>
auto Output::operator<<<Base>(Base output) -> Output & {
base=static_cast<int>(output);
return *this;
}
template <>
auto Output::operator<<<int>(int output) -> Output & {
const char* chars="0123456789ABCDEF";
char buf[33];
buf[32]='\0';
char* ptr=buf+31;
do {
*(ptr--)=chars[output%base];
output/=base;
} while(output && (ptr!=buf));
puts(ptr+1);
return *this;
}
template <>
auto Output::operator<<<char>(char output) -> Output & {
putChar(output);
return *this;
}
template <>
auto Output::operator<<<char*>(char* output) -> Output & {
puts(output);
return *this;
}
}

View file

@ -1,19 +0,0 @@
#include <base.hpp>
#include <serial.hpp>
namespace MTGosHAL {
auto Serial::isTransmitEmpty() -> int {
return 0;
}
auto Serial::putChar(char chr) -> void {
}
auto Serial::serial_received() -> int {
return 0;
}
auto Serial::getChar() -> char {
return '\0';
}
Serial::Serial(): works(true) {
}
auto Serial::debug() -> void {
}
}

View file

@ -1,32 +0,0 @@
#include <base.hpp>
#include <textDISP.hpp>
int x=0, y=0;
namespace MTGosHAL {
auto Screen::putChar(char c) -> void {
}
auto Screen::clrscr() -> void {
}
auto Screen::scroll() -> void {
}
template <>
auto Screen::operator<<<FG_color>(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
template <>
auto Screen::operator<<<BG_color>(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg) -> Screen &{
this->fg=fg;
return *this;
}
auto Screen::setColor(BG_color bg) -> Screen &{
this->bg=bg;
return *this;
}
auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{
return (*this).setColor(fg).setColor(bg);
}
}

View file

@ -1,12 +0,0 @@
#include <string.h>
__attribute__((optimize(0))) void memmove(void* dst, void* src, uint32_t size) {
uint8_t* from=(uint8_t*)src;
uint8_t* to=(uint8_t*)dst;
if((src<dst)&&((src+size)>dst)) {
for(int i=size-1;i>=0;i--)
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
} else if(src != dst) {
for(int i=0;i<size;i++)
to[i]=from[i]; //This would get optimized by gcc to memmove(dst, src, size); if optimizations are enabled.
}
}

View file

@ -303,9 +303,17 @@ intr_common_handler:
push %ecx push %ecx
push %ebx push %ebx
push %eax push %eax
//Load kernel datasegs
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
push %esp push %esp
call handleINT call handleINT
mov %eax, %esp mov %eax, %esp
//Load user datasegs
mov $0x23, %ax
mov %ax, %ds
mov %ax, %es
pop %eax pop %eax
pop %ebx pop %ebx
pop %ecx pop %ecx
@ -313,7 +321,7 @@ intr_common_handler:
pop %esi pop %esi
pop %edi pop %edi
pop %ebp pop %ebp
// Fehlercode und Interruptnummer vom Stack nehmen // Take error code and interrupt number from stack
add $8, %esp add $8, %esp
// Ruecksprung zum unterbrochenen Code // Exit interrupt
iret iret

View file

@ -8,13 +8,16 @@ namespace MTGosHAL {
public: public:
Multitasking(); Multitasking();
auto schedule(struct cpu_state* cpu) -> struct cpu_state*; auto schedule(struct cpu_state* cpu) -> struct cpu_state*;
uint32_t tss[32];
protected: protected:
private: private:
auto initTask(uint8_t* stck, void(*entry)()) -> struct cpu_state*; auto initTask(uint8_t* stck, uint8_t* user_stck, void(*entry)()) -> struct cpu_state*;
static auto task_a() -> void; static auto task_a() -> void;
static auto task_b() -> void; static auto task_b() -> void;
uint8_t stack_a[4096]; uint8_t stack_a[4096];
uint8_t stack_b[4096]; uint8_t stack_b[4096];
uint8_t user_stack_a[4096];
uint8_t user_stack_b[4096];
struct cpu_state* task_states[2]; struct cpu_state* task_states[2];
int current_task, num_tasks; int current_task, num_tasks;
}; };

View file

@ -1,7 +1,8 @@
#include <base.hpp> #include <base.hpp>
#include <textDISP.hpp> #include <textDISP.hpp>
#include <Multitasking.h> #include <Multitasking.hpp>
#include <serial.hpp> #include <serial.hpp>
#include <blockdev.hpp>
auto schedule(struct cpu_state* cpu) -> struct cpu_state* { auto schedule(struct cpu_state* cpu) -> struct cpu_state* {
return MTGosHAL::tasks.schedule(cpu); return MTGosHAL::tasks.schedule(cpu);
} }
@ -9,15 +10,21 @@ namespace MTGosHAL {
Multitasking::Multitasking(): current_task(-1), num_tasks(2) Multitasking::Multitasking(): current_task(-1), num_tasks(2)
{ {
task_states[0] = initTask(stack_a, task_a); for(int i=0;i<32;i++) {
task_states[1] = initTask(stack_b, task_b); if(i==2)
continue;
tss[i]=0;
}
tss[2]=0x10;
task_states[0] = initTask(stack_a, user_stack_a, task_a);
task_states[1] = initTask(stack_b, user_stack_b, task_b);
if(!idt.request(0x20,::schedule)) { if(!idt.request(0x20,::schedule)) {
err << "Could not start multitasking\nFatal error; Kernel halted!\n"; err << "Could not start multitasking\nFatal error; Kernel halted!\n";
while(true); while(true);
asm volatile("cli; hlt"); asm volatile("cli; hlt");
} }
} }
auto Multitasking::initTask(uint8_t* stck, void(* entry)()) -> struct cpu_state* auto Multitasking::initTask(uint8_t* stck, uint8_t* user_stck, void(* entry)()) -> struct cpu_state*
{ {
struct cpu_state new_state = { struct cpu_state new_state = {
0, //EAX 0, //EAX
@ -30,10 +37,10 @@ auto Multitasking::initTask(uint8_t* stck, void(* entry)()) -> struct cpu_state*
0, //INTR 0, //INTR
0, //ERROR 0, //ERROR
(uint32_t) entry, //EIP (uint32_t) entry, //EIP
0x08, //CS 0x18 | 0x03, //CS
0x202, // EFLAGS 0x202, // EFLAGS
(uint32_t) stck, //ESP (uint32_t) user_stck+4096, //ESP
0x10 //SS 0x20 | 0x03 //SS
}; };
struct cpu_state* state = (struct cpu_state*)(stck+4096-sizeof(new_state)); struct cpu_state* state = (struct cpu_state*)(stck+4096-sizeof(new_state));
*state = new_state; *state = new_state;
@ -42,14 +49,22 @@ auto Multitasking::initTask(uint8_t* stck, void(* entry)()) -> struct cpu_state*
auto Multitasking::task_a() -> void auto Multitasking::task_a() -> void
{ {
while(true) while(true) {
out << "A"; char arr[513];
arr[512]=0;
disk.readSector(disk.getDriveNumByName("ATA0m"),0,(uint8_t*)arr);
out << arr;
}
} }
auto Multitasking::task_b() -> void auto Multitasking::task_b() -> void
{ {
while(true) while(true) {
out << "B"; char arr[513];
arr[512]=0;
disk.readSector(disk.getDriveNumByName("ATA0m"),1,(uint8_t*)arr);
out << arr;
}
} }
auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state* auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
{ {
@ -59,6 +74,7 @@ auto Multitasking::schedule(struct cpu_state* cpu) -> struct cpu_state*
current_task++; current_task++;
current_task%= num_tasks; current_task%= num_tasks;
cpu=task_states[current_task]; cpu=task_states[current_task];
tss[1]=(uint32_t)(cpu+1);
return cpu; return cpu;
} }

View file

@ -5,7 +5,7 @@
#include <gdt.hpp> #include <gdt.hpp>
#include <idt.hpp> #include <idt.hpp>
#include <keyboard.hpp> #include <keyboard.hpp>
#include <Multitasking.h> #include <Multitasking.hpp>
#include <multiboot.h> #include <multiboot.h>
#include <blockdev.hpp> #include <blockdev.hpp>
extern "C" void intr_stub_0(void); extern "C" void intr_stub_0(void);
@ -30,9 +30,10 @@ namespace MTGosHAL {
gdt.setEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); gdt.setEntry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
gdt.setEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3); gdt.setEntry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
gdt.setEntry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3); gdt.setEntry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
gdt.setEntry(5, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_TSS | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); gdt.setEntry(5, (uint32_t)tasks.tss, sizeof(tasks.tss), GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT | GDT_FLAG_TSS | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT); gdt.setEntry(6, 0, 0xfffff, GDT_FLAG_RING3 | GDT_FLAG_TSS | GDT_FLAG_PRESENT);
gdt.apply(); gdt.apply();
asm volatile("ltr %%ax" : : "a"(5<<3));
debug << "We are now creating the IDT.\n"; debug << "We are now creating the IDT.\n";
for(int i=0;i<256;i++) { for(int i=0;i<256;i++) {
idt.setEntry(i, (void *)((uint32_t)&intr_stub_0+i*16), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED); idt.setEntry(i, (void *)((uint32_t)&intr_stub_0+i*16), SEG_KERNEL, IDT_INTERRUPT_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
@ -40,8 +41,8 @@ namespace MTGosHAL {
idt.setEntry(48, (void *)((uint32_t)&intr_stub_0+768), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED); idt.setEntry(48, (void *)((uint32_t)&intr_stub_0+768), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
idt.setEntry(8, (void *)((uint32_t)&intr_stub_0+128), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED); idt.setEntry(8, (void *)((uint32_t)&intr_stub_0+128), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
idt.apply(); idt.apply();
sti();
::main(); ::main();
sti();
for(;;); for(;;);
} }
} }

View file

@ -10,7 +10,7 @@ PMM::PMM(struct multiboot_info * mb_info) {
struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length); struct multiboot_mmap_entry* mmap_end = (struct multiboot_mmap_entry*) ((unsigned int) mb_info->mmap_addr + mb_info->mmap_length);
while (mmap < mmap_end) { while (mmap < mmap_end) {
if (mmap->type == 1) { if (mmap->type == 1) {
// Der Speicherbereich ist frei, entsprechend markieren // Memory is free
uintptr_t addr = mmap->addr; uintptr_t addr = mmap->addr;
uintptr_t end_addr = addr + mmap->len; uintptr_t end_addr = addr + mmap->len;
while (addr < end_addr) { while (addr < end_addr) {
@ -57,4 +57,4 @@ auto PMM::operator << (const void * addr) -> PMM & {
bitmap[index]|=bit; bitmap[index]|=bit;
return *this; return *this;
} }
} }

View file

@ -4,6 +4,8 @@
#include <textDISP.hpp> #include <textDISP.hpp>
#include <keyboard.hpp> #include <keyboard.hpp>
#include <Multitasking.h> #include <Multitasking.h>
#include <blockdev.hpp>
using namespace MTGosHAL;
void main() { void main() {
MTGosHAL::out << "Initializing Kernel!\n"; MTGosHAL::out << "Initializing Kernel!\n";
} }