Move to own ISR solution rather than using GCC ISRs. Lots of changes to accomodate that.
This commit is contained in:
parent
aba8a0a8c9
commit
2825c1ff5e
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@
|
|||||||
*.o
|
*.o
|
||||||
img.d/
|
img.d/
|
||||||
build/
|
build/
|
||||||
|
isr.S
|
@ -5,6 +5,7 @@ int main() {
|
|||||||
uint32_t PID = getPID();
|
uint32_t PID = getPID();
|
||||||
char intbuffer[32];
|
char intbuffer[32];
|
||||||
uint32_t index = int_to_decimal(PID, intbuffer);
|
uint32_t index = int_to_decimal(PID, intbuffer);
|
||||||
|
uint32_t x = *(uint32_t*)0xdeadbeef;
|
||||||
while (1) {
|
while (1) {
|
||||||
counter++;
|
counter++;
|
||||||
if (counter == 312500) {
|
if (counter == 312500) {
|
@ -1,14 +1,14 @@
|
|||||||
OUTPUT_FORMAT(binary)
|
OUTPUT_FORMAT(binary)
|
||||||
OUTPUT_ARCH(i386:i386)
|
OUTPUT_ARCH(i386:i386)
|
||||||
|
|
||||||
OUTPUT(build/program/hello.bin)
|
OUTPUT(build/hello/hello.bin)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x8020;
|
. = 0x8020;
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
build/program_code_entry.o(.text)
|
build/program_code_entry.o(.text)
|
||||||
build/program/hello.o(.text)
|
build/hello/hello.o(.text)
|
||||||
build/common/common.o(.text)
|
build/common/common.o(.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
25
src/kernel/gen_isr_asm.sh
Executable file
25
src/kernel/gen_isr_asm.sh
Executable file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
|
test -f isr.S && rm isr.S
|
||||||
|
cp isr.S.base isr.S
|
||||||
|
|
||||||
|
for i ({0..255}); do
|
||||||
|
cat >> isr.S << EOF
|
||||||
|
isr$i:
|
||||||
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
push $i
|
||||||
|
jmp catchall
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
|
||||||
|
x=""
|
||||||
|
for i ({0..255}); do
|
||||||
|
if [ $i = 255 ]; then
|
||||||
|
x="$x isr$i"
|
||||||
|
else
|
||||||
|
x="$x isr$i,"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "isrs dd $x" >> isr.S
|
@ -5,6 +5,7 @@ namespace Global {
|
|||||||
Kernel* kernel = 0;
|
Kernel* kernel = 0;
|
||||||
Process* currentProc = 0;
|
Process* currentProc = 0;
|
||||||
tss_struct* tss = 0;
|
tss_struct* tss = 0;
|
||||||
|
bool currentProcValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size) {
|
void* operator new (uint32_t size) {
|
||||||
|
@ -13,6 +13,7 @@ namespace Global {
|
|||||||
extern Kernel* kernel;
|
extern Kernel* kernel;
|
||||||
extern Process* currentProc;
|
extern Process* currentProc;
|
||||||
extern tss_struct* tss;
|
extern tss_struct* tss;
|
||||||
|
extern bool currentProcValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size);
|
void* operator new (uint32_t size);
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
|
|
||||||
GateEntry idt[256];
|
GateEntry idt[256];
|
||||||
|
|
||||||
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type, uint8_t privilege) {
|
void(*gates[256])(frame_struct*);
|
||||||
|
|
||||||
|
extern void(*isrs[256])(void);
|
||||||
|
|
||||||
|
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void(*handler)(), uint8_t type, uint8_t privilege) {
|
||||||
uint32_t handler_addr = (uint32_t)handler;
|
uint32_t handler_addr = (uint32_t)handler;
|
||||||
uint16_t* handler_halves = (uint16_t*)&handler_addr;
|
uint16_t* handler_halves = (uint16_t*)&handler_addr;
|
||||||
idt[interrupt_number] = (GateEntry) {
|
idt[interrupt_number] = (GateEntry) {
|
||||||
@ -17,28 +21,41 @@ void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, u
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void interrupt_20(interrupt_frame* frame) {
|
void page_fault(frame_struct* frame, uint32_t err_code) {
|
||||||
// printf("Interrupt 20 received!!\n");
|
|
||||||
outb(0x20, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((interrupt)) void page_fault(interrupt_frame* frame, uint32_t err_code) {
|
|
||||||
uint32_t problem_address;
|
uint32_t problem_address;
|
||||||
asm("mov %%cr2, %0" : "=a" (problem_address) :);
|
asm("mov %%cr2, %0" : "=a" (problem_address) :);
|
||||||
printf("(EIP %x): Page Fault at %x\n", frame->eip, problem_address);
|
Global::kernel->terminal->printf("(EIP %x): Page Fault at %x\n", frame->eip, problem_address);
|
||||||
|
if (frame->cs & 3 == 0) {
|
||||||
|
Global::kernel->terminal->printf("[FATAL] Kernel Page Fault!!!\n");
|
||||||
while (1) asm("hlt");
|
while (1) asm("hlt");
|
||||||
|
} else {
|
||||||
|
// Print an error message.
|
||||||
|
Global::kernel->terminal->printf("PID %d Terminated due to page fault!\n", Global::currentProc->PID);
|
||||||
|
// We are currently in the kernel stack for the current process so we need to load the main kernel stack in to esp.
|
||||||
|
//Global::kernel->loadPrimaryStack();
|
||||||
|
|
||||||
|
asm volatile ("mov %0, %%esp" ::"m"(Global::kernel->stack));
|
||||||
|
|
||||||
|
// We can now safely delete the current process
|
||||||
|
Global::kernel->destroyProcess(Global::currentProc);
|
||||||
|
|
||||||
|
// We want to load the kernel's page directory too.
|
||||||
|
//Global::kernel->PD->select();
|
||||||
|
|
||||||
|
//Global::currentProcValid = false;
|
||||||
|
asm ("int $0x20"); // Call context switch.
|
||||||
|
while (1) asm("hlt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void ignore_interrupt(interrupt_frame* frame) {
|
void ignore_interrupt(frame_struct* frame) {}
|
||||||
outb(0x20, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((interrupt)) void gpf(interrupt_frame* frame, uint32_t err_code) {
|
void gpf(frame_struct* frame, uint32_t err_code) {
|
||||||
printf("General Protection Fault %x\n", err_code);
|
printf("General Protection Fault %x\n", err_code);
|
||||||
while (1) asm("hlt");
|
while (1) asm("hlt");
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
|
void context_switch(frame_struct* frame) {
|
||||||
// When any interrupt occurs (including context_switch), SS:ESP is set to
|
// When any interrupt occurs (including context_switch), SS:ESP is set to
|
||||||
// the values of SS0:ESP0 in Global::tss
|
// the values of SS0:ESP0 in Global::tss
|
||||||
//
|
//
|
||||||
@ -53,22 +70,27 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
|
|||||||
// to iret
|
// to iret
|
||||||
|
|
||||||
asm ("cli"); // Disable interrupts whilst handling the context switch.
|
asm ("cli"); // Disable interrupts whilst handling the context switch.
|
||||||
asm ("pusha"); // Push registers to the stack
|
|
||||||
//asm ("pushf"); // Push flags to the stack
|
|
||||||
|
|
||||||
Process* currentProc = Global::currentProc;
|
// Restore eax
|
||||||
|
asm ("mov %0, %%eax"::"r"(frame->eax));
|
||||||
|
|
||||||
|
Process* currentProc = 0;
|
||||||
Process* nextProc = 0;
|
Process* nextProc = 0;
|
||||||
|
|
||||||
|
if (Global::currentProcValid) {
|
||||||
|
currentProc = Global::currentProc;
|
||||||
// Write current esp to currentProc->kernelStackPtr
|
// Write current esp to currentProc->kernelStackPtr
|
||||||
asm ("mov %%esp, %0" : "=a" (currentProc->kernelStackPtr):);
|
asm ("mov %%esp, %0" : "=a" (currentProc->kernelStackPtr):);
|
||||||
|
}
|
||||||
|
|
||||||
if (currentProc) {
|
if (currentProc || !Global::currentProcValid) {
|
||||||
xnoe::linkedlist<Process*>* processes = &Global::kernel->processes;
|
xnoe::linkedlist<Process*>* processes = &Global::kernel->processes;
|
||||||
|
|
||||||
// This cursed bit of code first determines if the processes list is longer than 1 and if it is
|
// This cursed bit of code first determines if the processes list is longer than 1 and if it is
|
||||||
// - Determines if it has 2 or more elements
|
// - Determines if it has 2 or more elements
|
||||||
// - If it has two, swap the first and last, update prev and next of each to be null or the other item
|
// - If it has two, swap the first and last, update prev and next of each to be null or the other item
|
||||||
// - If it has more than two, add the start to the end then set start to the second element
|
// - If it has more than two, add the start to the end then set start to the second element
|
||||||
|
if (processes->start) {
|
||||||
if (processes->start->next != 0) {
|
if (processes->start->next != 0) {
|
||||||
if (processes->end->prev == processes->start) {
|
if (processes->end->prev == processes->start) {
|
||||||
xnoe::linkedlistelem<Process*>* tmp = processes->start;
|
xnoe::linkedlistelem<Process*>* tmp = processes->start;
|
||||||
@ -89,44 +111,45 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
|
|||||||
processes->end->prev = tmp;
|
processes->end->prev = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get the next process.
|
// Get the next process.
|
||||||
|
if (processes->start)
|
||||||
nextProc = processes->start->elem;
|
nextProc = processes->start->elem;
|
||||||
|
|
||||||
|
if (nextProc == 0) {
|
||||||
|
Global::kernel->terminal->printf("[FATAL] No more processes! Halting!\n");
|
||||||
|
while (1) asm ("hlt");
|
||||||
|
}
|
||||||
|
|
||||||
Global::currentProc = nextProc;
|
Global::currentProc = nextProc;
|
||||||
|
|
||||||
//uint32_t cESP;
|
|
||||||
//asm volatile ("mov %%esp, %0" : "=a" (cESP) :);
|
|
||||||
//currentProc->esp = cESP; // Store the current ESP of the current process process.
|
|
||||||
|
|
||||||
outb(0x20, 0x20);
|
|
||||||
|
|
||||||
// Select the next processes page directory
|
// Select the next processes page directory
|
||||||
asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr));
|
asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr));
|
||||||
// Restore kernelStackPtr of the new process.
|
// Restore kernelStackPtr of the new process.
|
||||||
asm volatile ("mov %0, %%esp" : : "m" (Global::kernel->processes.start->elem->kernelStackPtr));
|
asm volatile ("mov %0, %%esp" : : "m" (Global::kernel->processes.start->elem->kernelStackPtr));
|
||||||
|
|
||||||
// At this point interrupts are disabled till iret so we can safely set
|
// At this point interrupts are disabled till iret so we can safely set
|
||||||
// Global::tss->esp0
|
// Global::tss->esp0 to the new Process's kernelStackPtrDefault
|
||||||
// to the new Process's kernelStackPtrDefault
|
|
||||||
|
|
||||||
Global::tss->esp0 = Global::kernel->processes.start->elem->kernelStackPtrDefault;
|
Global::tss->esp0 = Global::kernel->processes.start->elem->kernelStackPtrDefault;
|
||||||
|
|
||||||
//asm ("popf"); // Pop flags
|
// Set the current proc to valid
|
||||||
asm ("popa"); // Restore registers
|
Global::currentProcValid = true;
|
||||||
asm ("mov -0xc(%ebp), %eax"); // Restore the initial eax
|
|
||||||
// Clear the garbage that was on the stack from previous switch_context call.
|
|
||||||
asm ("mov %ebp, %esp");
|
|
||||||
asm ("pop %ebp"); // Pop EBP
|
|
||||||
|
|
||||||
asm ("iret"); // Manually perform iret.
|
uint32_t* espVal;
|
||||||
|
asm ("mov %%esp, %0":"=a"(espVal):);
|
||||||
|
if (*espVal == 0) {
|
||||||
|
asm("add $4, %esp");
|
||||||
|
asm("ret");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern uint8_t current_scancode;
|
extern uint8_t current_scancode;
|
||||||
extern char decoded;
|
extern char decoded;
|
||||||
|
|
||||||
__attribute__((interrupt)) void syscall(interrupt_frame* frame) {
|
void syscall(frame_struct* frame) {
|
||||||
// Syscall ABI:
|
// Syscall ABI:
|
||||||
// 0: print: Print null terminated string (in esi: char*)
|
// 0: print: Print null terminated string (in esi: char*)
|
||||||
// 1: getch: Get current keyboard character ASCII (out eax: char)
|
// 1: getch: Get current keyboard character ASCII (out eax: char)
|
||||||
@ -138,17 +161,11 @@ __attribute__((interrupt)) void syscall(interrupt_frame* frame) {
|
|||||||
// 7: fork: create process from filename (in esi: char* filename)
|
// 7: fork: create process from filename (in esi: char* filename)
|
||||||
// 8: getPID: returns the current process's PID (out eax: uint32_t)
|
// 8: getPID: returns the current process's PID (out eax: uint32_t)
|
||||||
|
|
||||||
uint32_t* ebp;
|
uint32_t rval = frame->eax;
|
||||||
asm("mov %%ebp, %0" : "=a" (ebp) :);
|
|
||||||
uint32_t eax = *(ebp-4);
|
|
||||||
uint32_t rval = eax;
|
|
||||||
|
|
||||||
uint32_t syscall_number;
|
uint32_t esi = frame->esi;
|
||||||
uint32_t esi;
|
uint32_t edi = frame->edi;
|
||||||
uint32_t edi;
|
switch (frame->eax) {
|
||||||
asm("mov %%esi, %0" : "=a" (esi) :);
|
|
||||||
asm("mov %%edi, %0" : "=a" (edi) :);
|
|
||||||
switch (eax) {
|
|
||||||
case 0:
|
case 0:
|
||||||
Global::kernel->terminal->printf("%s", (char*)esi);
|
Global::kernel->terminal->printf("%s", (char*)esi);
|
||||||
break;
|
break;
|
||||||
@ -181,22 +198,25 @@ __attribute__((interrupt)) void syscall(interrupt_frame* frame) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
asm volatile ("mov %0, %%eax" : : "m" (rval));
|
frame->eax = rval;
|
||||||
asm ("mov %ebp, %esp");
|
|
||||||
asm ("pop %ebp");
|
|
||||||
asm ("iret");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_idt() {
|
void init_idt() {
|
||||||
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
||||||
asm volatile("lidt %0" : : "m" (desc));
|
asm volatile("lidt %0" : : "m" (desc));
|
||||||
for (int i=0; i<256; i++)
|
|
||||||
set_entry(i, 0x08, &ignore_interrupt, 0x8E);
|
|
||||||
|
|
||||||
set_entry(0x20, 0x08, &context_switch, 0xE);
|
for (int i=0; i<256; i++)
|
||||||
set_entry(0xD, 0x08, &gpf, 0xE);
|
set_entry(i, 0x08, isrs[i], 0xE);
|
||||||
set_entry(0xE, 0x08, &page_fault, 0xE);
|
|
||||||
set_entry(0x7f, 0x08, &syscall, 0xE, 3);
|
for (int i=0; i<256; i++)
|
||||||
|
gates[i] = &ignore_interrupt;
|
||||||
|
|
||||||
|
gates[0x20] = &context_switch;
|
||||||
|
gates[0xd] = &gpf;
|
||||||
|
gates[0xe] = &page_fault;
|
||||||
|
gates[0x7f] = &syscall;
|
||||||
|
|
||||||
|
idt[0x7f].privilege = 3;
|
||||||
|
|
||||||
outb(0x20, 0x11);
|
outb(0x20, 0x11);
|
||||||
outb(0xA0, 0x11);
|
outb(0xA0, 0x11);
|
||||||
|
@ -7,14 +7,28 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
|
|
||||||
struct interrupt_frame {
|
struct __attribute__((packed)) frame_struct {
|
||||||
|
uint32_t edi;
|
||||||
|
uint32_t esi;
|
||||||
|
uint32_t ebp;
|
||||||
|
uint32_t oesp;
|
||||||
|
uint32_t ebx;
|
||||||
|
uint32_t edx;
|
||||||
|
uint32_t ecx;
|
||||||
|
uint32_t eax;
|
||||||
uint32_t eip;
|
uint32_t eip;
|
||||||
uint16_t cs;
|
uint16_t cs;
|
||||||
uint16_t _ignored0;
|
uint16_t _ignored0;
|
||||||
uint32_t eflags;
|
uint32_t eflags;
|
||||||
|
uint16_t ss;
|
||||||
|
uint16_t _ignored1;
|
||||||
|
uint32_t esp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern void(*gates[256])(frame_struct*);
|
||||||
|
|
||||||
extern void load_idt();
|
extern void load_idt();
|
||||||
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type, uint8_t privilege = 0);
|
void set_entry(uint8_t interrupt_number, uint16_t code_segment, void(*handler)(), uint8_t type, uint8_t privilege = 0);
|
||||||
void init_idt();
|
void init_idt();
|
||||||
void enable_idt();
|
void enable_idt();
|
||||||
|
|
||||||
@ -27,11 +41,11 @@ struct __attribute__((packed)) GateEntry{
|
|||||||
uint8_t privilege : 2;
|
uint8_t privilege : 2;
|
||||||
uint8_t present : 1;
|
uint8_t present : 1;
|
||||||
uint16_t offset_high;
|
uint16_t offset_high;
|
||||||
} ;
|
};
|
||||||
|
|
||||||
struct __attribute__((packed)) idt_desc {
|
struct __attribute__((packed)) idt_desc {
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
} ;
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,19 +1,21 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
|
||||||
void outb(uint16_t portnumber, uint8_t data) {
|
extern "C" {
|
||||||
|
void outb(uint16_t portnumber, uint8_t data) {
|
||||||
asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber));
|
asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||||
}
|
}
|
||||||
uint8_t inb(uint16_t portnumber) {
|
uint8_t inb(uint16_t portnumber) {
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber));
|
asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void outw(uint16_t portnumber, uint16_t data) {
|
void outw(uint16_t portnumber, uint16_t data) {
|
||||||
asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber));
|
asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||||
}
|
}
|
||||||
uint16_t inw(uint16_t portnumber) {
|
uint16_t inw(uint16_t portnumber) {
|
||||||
uint16_t result;
|
uint16_t result;
|
||||||
asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber));
|
asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void outb(uint16_t portnumber, uint8_t data);
|
extern "C" {
|
||||||
uint8_t inb(uint16_t portnumber);
|
void outb(uint16_t portnumber, uint8_t data);
|
||||||
|
uint8_t inb(uint16_t portnumber);
|
||||||
|
|
||||||
void outw(uint16_t portnumber, uint16_t data);
|
void outw(uint16_t portnumber, uint16_t data);
|
||||||
uint16_t inw(uint16_t portnumber);
|
uint16_t inw(uint16_t portnumber);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
52
src/kernel/isr.S.base
Normal file
52
src/kernel/isr.S.base
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
[BITS 32]
|
||||||
|
|
||||||
|
global isrs
|
||||||
|
|
||||||
|
global catchall_return
|
||||||
|
|
||||||
|
catchall: ; At this point the gate number has been pushed to the stack
|
||||||
|
pushad ; Pushed 32 bytes
|
||||||
|
mov eax, [esp+32]
|
||||||
|
mov ebx, gates
|
||||||
|
mov eax, [ebx+4*eax]
|
||||||
|
push esp
|
||||||
|
call eax
|
||||||
|
|
||||||
|
catchall_return:
|
||||||
|
add esp, 4
|
||||||
|
|
||||||
|
push 0x20
|
||||||
|
push 0x20
|
||||||
|
call outb
|
||||||
|
add esp, 8
|
||||||
|
|
||||||
|
popad
|
||||||
|
mov esp, ebp
|
||||||
|
pop ebp
|
||||||
|
iret
|
||||||
|
|
||||||
|
extern gates ; (void(*)(frame_struct))*
|
||||||
|
extern outb
|
||||||
|
|
||||||
|
; struct frame_struct __attribute__((packed)) {
|
||||||
|
; popad
|
||||||
|
; uint32_t edi;
|
||||||
|
; uint32_t esi;
|
||||||
|
; uint32_t ebp;
|
||||||
|
; uint32_t esp;
|
||||||
|
; uint32_t ebx;
|
||||||
|
; uint32_t edx;
|
||||||
|
; uint32_t ecx;
|
||||||
|
; uint32_t eax;
|
||||||
|
;
|
||||||
|
; interrupt
|
||||||
|
; uint32_t eip;
|
||||||
|
; uint32_t cs;
|
||||||
|
; uint32_t eflags;
|
||||||
|
; uint32_t esp;
|
||||||
|
; uint32_t ss;
|
||||||
|
;
|
||||||
|
; if it's an error
|
||||||
|
; uint32_t err_code;
|
||||||
|
; }
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base)
|
Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base, uint32_t stack)
|
||||||
: Process(0, 0x8a000, page_directory, phys, virt, virt_alloc_base)
|
: Process(0, 0x8a000, page_directory, phys, virt, virt_alloc_base)
|
||||||
{
|
{
|
||||||
this->currentPID = 1;
|
this->currentPID = 1;
|
||||||
@ -9,6 +9,8 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
|
|||||||
|
|
||||||
Global::currentProc = 0;
|
Global::currentProc = 0;
|
||||||
|
|
||||||
|
this->stack = stack;
|
||||||
|
|
||||||
//this->processes.append(this);
|
//this->processes.append(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,5 +32,8 @@ void Kernel::destroyProcess(Process* p) {
|
|||||||
this->processes.remove(p);
|
this->processes.remove(p);
|
||||||
this->pid_map->remove(p->PID, p);
|
this->pid_map->remove(p->PID, p);
|
||||||
delete p;
|
delete p;
|
||||||
while (1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void Kernel::loadPrimaryStack() {
|
||||||
|
// asm volatile("mov %0, %%esp"::"m"(this->stack - 64));
|
||||||
|
//}
|
@ -9,18 +9,20 @@
|
|||||||
class Kernel : public Process {
|
class Kernel : public Process {
|
||||||
public:
|
public:
|
||||||
uint32_t currentPID;
|
uint32_t currentPID;
|
||||||
|
uint32_t stack;
|
||||||
Terminal* terminal;
|
Terminal* terminal;
|
||||||
|
|
||||||
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
||||||
|
|
||||||
xnoe::linkedlist<Process*> processes;
|
xnoe::linkedlist<Process*> processes;
|
||||||
|
|
||||||
Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base, uint32_t stack);
|
||||||
|
|
||||||
void init_kernel();
|
void init_kernel();
|
||||||
|
|
||||||
Process* createProcess(char* filename);
|
Process* createProcess(char* filename);
|
||||||
void destroyProcess(Process* p);
|
void destroyProcess(Process* p);
|
||||||
|
//void loadPrimaryStack();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -36,7 +36,7 @@ char decoded = 0;
|
|||||||
bool caps_on = false;
|
bool caps_on = false;
|
||||||
bool shift_on = false;
|
bool shift_on = false;
|
||||||
|
|
||||||
__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame) {
|
void keyboard_interrupt(frame_struct* frame) {
|
||||||
current_scancode = inb(0x60);
|
current_scancode = inb(0x60);
|
||||||
outb(0x20, 0x21);
|
outb(0x20, 0x21);
|
||||||
if ((current_scancode&0x7f) == 0x2a)
|
if ((current_scancode&0x7f) == 0x2a)
|
||||||
@ -54,7 +54,8 @@ __attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init_keyboard() {
|
void init_keyboard() {
|
||||||
set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E);
|
//set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E);
|
||||||
|
gates[0x21] = &keyboard_interrupt;
|
||||||
|
|
||||||
while (inb(0x64) & 1) {
|
while (inb(0x64) & 1) {
|
||||||
inb(0x60);
|
inb(0x60);
|
||||||
|
@ -27,7 +27,7 @@ int main() {
|
|||||||
PageMap phys_pm(0xc0600000);
|
PageMap phys_pm(0xc0600000);
|
||||||
PageMap virt_pm(0xc0620000);
|
PageMap virt_pm(0xc0620000);
|
||||||
|
|
||||||
Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000);
|
Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000, 0xc1006000);
|
||||||
kernel.init_kernel();
|
kernel.init_kernel();
|
||||||
init_atapio();
|
init_atapio();
|
||||||
|
|
||||||
@ -47,6 +47,7 @@ int main() {
|
|||||||
Global::currentProc = &kernel;
|
Global::currentProc = &kernel;
|
||||||
|
|
||||||
Process* p1 = kernel.createProcess("WORLD BIN");
|
Process* p1 = kernel.createProcess("WORLD BIN");
|
||||||
|
kernel.createProcess("HELLO BIN");
|
||||||
|
|
||||||
init_keyboard();
|
init_keyboard();
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
|
||||||
|
extern void(*catchall_return)();
|
||||||
|
|
||||||
AllocTracker::AllocTracker(void* base, uint32_t size, uint32_t count) : page_base(base), page_size(size), alloc_count(count) {}
|
AllocTracker::AllocTracker(void* base, uint32_t size, uint32_t count) : page_base(base), page_size(size), alloc_count(count) {}
|
||||||
|
|
||||||
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> Process::get_alloc_tracker(uint32_t address) {
|
xnoe::Maybe<xnoe::linkedlistelem<AllocTracker>*> Process::get_alloc_tracker(uint32_t address) {
|
||||||
@ -68,8 +70,6 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha
|
|||||||
|
|
||||||
uint32_t rEBP = stack32;
|
uint32_t rEBP = stack32;
|
||||||
|
|
||||||
stack32 -= 21;
|
|
||||||
|
|
||||||
stack32--;
|
stack32--;
|
||||||
*stack32 = 0; // EAX
|
*stack32 = 0; // EAX
|
||||||
stack32--;
|
stack32--;
|
||||||
@ -87,6 +87,13 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha
|
|||||||
stack32--;
|
stack32--;
|
||||||
*stack32 = 0; // EDI
|
*stack32 = 0; // EDI
|
||||||
|
|
||||||
|
stack32--;
|
||||||
|
|
||||||
|
stack32--;
|
||||||
|
*stack32 = &catchall_return; // cachall_return
|
||||||
|
|
||||||
|
stack32--;
|
||||||
|
|
||||||
this->kernelStackPtr = stack32;
|
this->kernelStackPtr = stack32;
|
||||||
|
|
||||||
load_file(filename, program_data);
|
load_file(filename, program_data);
|
||||||
|
@ -58,6 +58,20 @@ void Terminal::printf(const char* string, ...) {
|
|||||||
this->cur_y++;
|
this->cur_y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current == '\b') {
|
||||||
|
if (this->cur_x > 0) {
|
||||||
|
this->cur_x--;
|
||||||
|
} else {
|
||||||
|
this->cur_y--;
|
||||||
|
this->cur_x = this->width-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mem_pos = this->cur_y * this->width + this->cur_x;
|
||||||
|
|
||||||
|
this->putchar(mem_pos, ' ');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->cur_x == this->width) {
|
if (this->cur_x == this->width) {
|
||||||
this->cur_x = 0;
|
this->cur_x = 0;
|
||||||
this->cur_y++;
|
this->cur_y++;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
char key_to_char[128] = {
|
char key_to_char[128] = {
|
||||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
|
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 0,
|
||||||
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0,
|
||||||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\',
|
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\',
|
||||||
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||||
@ -12,7 +12,7 @@ char key_to_char[128] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
char key_to_char_caps[128] = {
|
char key_to_char_caps[128] = {
|
||||||
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0,
|
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 0,
|
||||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0,
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0,
|
||||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\',
|
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\',
|
||||||
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||||
@ -22,7 +22,7 @@ char key_to_char_caps[128] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
char key_to_char_shift[128] = {
|
char key_to_char_shift[128] = {
|
||||||
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0,
|
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', 0,
|
||||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0,
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0,
|
||||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|',
|
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|',
|
||||||
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0,
|
||||||
@ -54,12 +54,6 @@ void readline(int max, char* buffer) {
|
|||||||
if (scancode == 0x3a)
|
if (scancode == 0x3a)
|
||||||
caps_on ^= 1;
|
caps_on ^= 1;
|
||||||
|
|
||||||
/*if (scancode == 0x0e && index > 0) {
|
|
||||||
set_curpos_raw(get_curpos()-1);
|
|
||||||
non_moving_put(' ');
|
|
||||||
buffer[--index] = 0;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (shift_on)
|
if (shift_on)
|
||||||
decoded = key_to_char_shift[scancode&0x7f];
|
decoded = key_to_char_shift[scancode&0x7f];
|
||||||
else if (caps_on)
|
else if (caps_on)
|
||||||
@ -67,7 +61,12 @@ void readline(int max, char* buffer) {
|
|||||||
else
|
else
|
||||||
decoded = key_to_char[scancode&0x7f];
|
decoded = key_to_char[scancode&0x7f];
|
||||||
|
|
||||||
if (decoded && scancode < 0x80) {
|
if (scancode == 0x0e) {
|
||||||
|
if (index > 0) {
|
||||||
|
buffer[--index] = 0;
|
||||||
|
print("\b");
|
||||||
|
}
|
||||||
|
} else if (decoded && scancode < 0x80) {
|
||||||
buffer[index++] = decoded;
|
buffer[index++] = decoded;
|
||||||
char_print[0] = decoded;
|
char_print[0] = decoded;
|
||||||
print(char_print);
|
print(char_print);
|
@ -1,14 +1,14 @@
|
|||||||
OUTPUT_FORMAT(binary)
|
OUTPUT_FORMAT(binary)
|
||||||
OUTPUT_ARCH(i386:i386)
|
OUTPUT_ARCH(i386:i386)
|
||||||
|
|
||||||
OUTPUT(build/program/world.bin)
|
OUTPUT(build/world/world.bin)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x8020;
|
. = 0x8020;
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
build/program_code_entry.o(.text)
|
build/program_code_entry.o(.text)
|
||||||
build/program/world.o(.text)
|
build/world/world.o(.text)
|
||||||
build/common/common.o(.text)
|
build/common/common.o(.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user