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
3
.gitignore
vendored
3
.gitignore
vendored
@ -4,4 +4,5 @@
|
||||
*.sector
|
||||
*.o
|
||||
img.d/
|
||||
build/
|
||||
build/
|
||||
isr.S
|
@ -5,6 +5,7 @@ int main() {
|
||||
uint32_t PID = getPID();
|
||||
char intbuffer[32];
|
||||
uint32_t index = int_to_decimal(PID, intbuffer);
|
||||
uint32_t x = *(uint32_t*)0xdeadbeef;
|
||||
while (1) {
|
||||
counter++;
|
||||
if (counter == 312500) {
|
@ -1,14 +1,14 @@
|
||||
OUTPUT_FORMAT(binary)
|
||||
OUTPUT_ARCH(i386:i386)
|
||||
|
||||
OUTPUT(build/program/hello.bin)
|
||||
OUTPUT(build/hello/hello.bin)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x8020;
|
||||
|
||||
.text : {
|
||||
build/program_code_entry.o(.text)
|
||||
build/program/hello.o(.text)
|
||||
build/hello/hello.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;
|
||||
Process* currentProc = 0;
|
||||
tss_struct* tss = 0;
|
||||
bool currentProcValid = true;
|
||||
}
|
||||
|
||||
void* operator new (uint32_t size) {
|
||||
|
@ -13,6 +13,7 @@ namespace Global {
|
||||
extern Kernel* kernel;
|
||||
extern Process* currentProc;
|
||||
extern tss_struct* tss;
|
||||
extern bool currentProcValid;
|
||||
}
|
||||
|
||||
void* operator new (uint32_t size);
|
||||
|
@ -2,7 +2,11 @@
|
||||
|
||||
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;
|
||||
uint16_t* handler_halves = (uint16_t*)&handler_addr;
|
||||
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) {
|
||||
// printf("Interrupt 20 received!!\n");
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
__attribute__((interrupt)) void page_fault(interrupt_frame* frame, uint32_t err_code) {
|
||||
void page_fault(frame_struct* frame, uint32_t err_code) {
|
||||
uint32_t problem_address;
|
||||
asm("mov %%cr2, %0" : "=a" (problem_address) :);
|
||||
printf("(EIP %x): Page Fault at %x\n", frame->eip, problem_address);
|
||||
while (1) asm("hlt");
|
||||
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");
|
||||
} 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) {
|
||||
outb(0x20, 0x20);
|
||||
}
|
||||
void ignore_interrupt(frame_struct* frame) {}
|
||||
|
||||
__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);
|
||||
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
|
||||
// the values of SS0:ESP0 in Global::tss
|
||||
//
|
||||
@ -53,80 +70,86 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) {
|
||||
// to iret
|
||||
|
||||
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;
|
||||
|
||||
// Write current esp to currentProc->kernelStackPtr
|
||||
asm ("mov %%esp, %0" : "=a" (currentProc->kernelStackPtr):);
|
||||
if (Global::currentProcValid) {
|
||||
currentProc = Global::currentProc;
|
||||
// Write current esp to currentProc->kernelStackPtr
|
||||
asm ("mov %%esp, %0" : "=a" (currentProc->kernelStackPtr):);
|
||||
}
|
||||
|
||||
if (currentProc) {
|
||||
if (currentProc || !Global::currentProcValid) {
|
||||
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
|
||||
// - 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 more than two, add the start to the end then set start to the second element
|
||||
if (processes->start->next != 0) {
|
||||
if (processes->end->prev == processes->start) {
|
||||
xnoe::linkedlistelem<Process*>* tmp = processes->start;
|
||||
processes->start = processes->end;
|
||||
processes->end = tmp;
|
||||
if (processes->start) {
|
||||
if (processes->start->next != 0) {
|
||||
if (processes->end->prev == processes->start) {
|
||||
xnoe::linkedlistelem<Process*>* tmp = processes->start;
|
||||
processes->start = processes->end;
|
||||
processes->end = tmp;
|
||||
|
||||
processes->start->prev = 0;
|
||||
processes->end->next = 0;
|
||||
processes->end->prev = processes->start;
|
||||
processes->start->next = processes->end;
|
||||
} else {
|
||||
processes->end->next = processes->start;
|
||||
processes->start = processes->start->next;
|
||||
processes->start->prev = 0;
|
||||
xnoe::linkedlistelem<Process*>* tmp = processes->end;
|
||||
processes->end = processes->end->next;
|
||||
processes->end->next = 0;
|
||||
processes->end->prev = tmp;
|
||||
processes->start->prev = 0;
|
||||
processes->end->next = 0;
|
||||
processes->end->prev = processes->start;
|
||||
processes->start->next = processes->end;
|
||||
} else {
|
||||
processes->end->next = processes->start;
|
||||
processes->start = processes->start->next;
|
||||
processes->start->prev = 0;
|
||||
xnoe::linkedlistelem<Process*>* tmp = processes->end;
|
||||
processes->end = processes->end->next;
|
||||
processes->end->next = 0;
|
||||
processes->end->prev = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next process.
|
||||
nextProc = processes->start->elem;
|
||||
if (processes->start)
|
||||
nextProc = processes->start->elem;
|
||||
|
||||
if (nextProc == 0) {
|
||||
Global::kernel->terminal->printf("[FATAL] No more processes! Halting!\n");
|
||||
while (1) asm ("hlt");
|
||||
}
|
||||
|
||||
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
|
||||
asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr));
|
||||
// Restore kernelStackPtr of the new process.
|
||||
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
|
||||
// Global::tss->esp0
|
||||
// to the new Process's kernelStackPtrDefault
|
||||
// Global::tss->esp0 to the new Process's kernelStackPtrDefault
|
||||
|
||||
Global::tss->esp0 = Global::kernel->processes.start->elem->kernelStackPtrDefault;
|
||||
|
||||
//asm ("popf"); // Pop flags
|
||||
asm ("popa"); // Restore registers
|
||||
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
|
||||
// Set the current proc to valid
|
||||
Global::currentProcValid = true;
|
||||
|
||||
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 char decoded;
|
||||
|
||||
__attribute__((interrupt)) void syscall(interrupt_frame* frame) {
|
||||
void syscall(frame_struct* frame) {
|
||||
// Syscall ABI:
|
||||
// 0: print: Print null terminated string (in esi: 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)
|
||||
// 8: getPID: returns the current process's PID (out eax: uint32_t)
|
||||
|
||||
uint32_t* ebp;
|
||||
asm("mov %%ebp, %0" : "=a" (ebp) :);
|
||||
uint32_t eax = *(ebp-4);
|
||||
uint32_t rval = eax;
|
||||
uint32_t rval = frame->eax;
|
||||
|
||||
uint32_t syscall_number;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
asm("mov %%esi, %0" : "=a" (esi) :);
|
||||
asm("mov %%edi, %0" : "=a" (edi) :);
|
||||
switch (eax) {
|
||||
uint32_t esi = frame->esi;
|
||||
uint32_t edi = frame->edi;
|
||||
switch (frame->eax) {
|
||||
case 0:
|
||||
Global::kernel->terminal->printf("%s", (char*)esi);
|
||||
break;
|
||||
@ -181,22 +198,25 @@ __attribute__((interrupt)) void syscall(interrupt_frame* frame) {
|
||||
break;
|
||||
}
|
||||
|
||||
asm volatile ("mov %0, %%eax" : : "m" (rval));
|
||||
asm ("mov %ebp, %esp");
|
||||
asm ("pop %ebp");
|
||||
asm ("iret");
|
||||
frame->eax = rval;
|
||||
}
|
||||
|
||||
void init_idt() {
|
||||
idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt};
|
||||
asm volatile("lidt %0" : : "m" (desc));
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
set_entry(i, 0x08, &ignore_interrupt, 0x8E);
|
||||
set_entry(i, 0x08, isrs[i], 0xE);
|
||||
|
||||
for (int i=0; i<256; i++)
|
||||
gates[i] = &ignore_interrupt;
|
||||
|
||||
set_entry(0x20, 0x08, &context_switch, 0xE);
|
||||
set_entry(0xD, 0x08, &gpf, 0xE);
|
||||
set_entry(0xE, 0x08, &page_fault, 0xE);
|
||||
set_entry(0x7f, 0x08, &syscall, 0xE, 3);
|
||||
gates[0x20] = &context_switch;
|
||||
gates[0xd] = &gpf;
|
||||
gates[0xe] = &page_fault;
|
||||
gates[0x7f] = &syscall;
|
||||
|
||||
idt[0x7f].privilege = 3;
|
||||
|
||||
outb(0x20, 0x11);
|
||||
outb(0xA0, 0x11);
|
||||
|
@ -7,14 +7,28 @@
|
||||
#include "kernel.h"
|
||||
#include "gdt.h"
|
||||
|
||||
struct interrupt_frame {
|
||||
uint32_t eip;
|
||||
uint16_t cs;
|
||||
uint16_t _ignored0;
|
||||
uint32_t eflags;
|
||||
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;
|
||||
uint16_t cs;
|
||||
uint16_t _ignored0;
|
||||
uint32_t eflags;
|
||||
uint16_t ss;
|
||||
uint16_t _ignored1;
|
||||
uint32_t esp;
|
||||
};
|
||||
|
||||
extern void(*gates[256])(frame_struct*);
|
||||
|
||||
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 enable_idt();
|
||||
|
||||
@ -27,11 +41,11 @@ struct __attribute__((packed)) GateEntry{
|
||||
uint8_t privilege : 2;
|
||||
uint8_t present : 1;
|
||||
uint16_t offset_high;
|
||||
} ;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) idt_desc {
|
||||
uint16_t size;
|
||||
uint32_t offset;
|
||||
} ;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,19 +1,21 @@
|
||||
#include "io.h"
|
||||
|
||||
void outb(uint16_t portnumber, uint8_t data) {
|
||||
asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||
}
|
||||
uint8_t inb(uint16_t portnumber) {
|
||||
uint8_t result;
|
||||
asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||
return result;
|
||||
}
|
||||
extern "C" {
|
||||
void outb(uint16_t portnumber, uint8_t data) {
|
||||
asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||
}
|
||||
uint8_t inb(uint16_t portnumber) {
|
||||
uint8_t result;
|
||||
asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||
return result;
|
||||
}
|
||||
|
||||
void outw(uint16_t portnumber, uint16_t data) {
|
||||
asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||
}
|
||||
uint16_t inw(uint16_t portnumber) {
|
||||
uint16_t result;
|
||||
asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||
return result;
|
||||
void outw(uint16_t portnumber, uint16_t data) {
|
||||
asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber));
|
||||
}
|
||||
uint16_t inw(uint16_t portnumber) {
|
||||
uint16_t result;
|
||||
asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber));
|
||||
return result;
|
||||
}
|
||||
}
|
@ -3,10 +3,12 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void outb(uint16_t portnumber, uint8_t data);
|
||||
uint8_t inb(uint16_t portnumber);
|
||||
extern "C" {
|
||||
void outb(uint16_t portnumber, uint8_t data);
|
||||
uint8_t inb(uint16_t portnumber);
|
||||
|
||||
void outw(uint16_t portnumber, uint16_t data);
|
||||
uint16_t inw(uint16_t portnumber);
|
||||
void outw(uint16_t portnumber, uint16_t data);
|
||||
uint16_t inw(uint16_t portnumber);
|
||||
}
|
||||
|
||||
#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"
|
||||
|
||||
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)
|
||||
{
|
||||
this->currentPID = 1;
|
||||
@ -9,6 +9,8 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
|
||||
|
||||
Global::currentProc = 0;
|
||||
|
||||
this->stack = stack;
|
||||
|
||||
//this->processes.append(this);
|
||||
}
|
||||
|
||||
@ -30,5 +32,8 @@ void Kernel::destroyProcess(Process* p) {
|
||||
this->processes.remove(p);
|
||||
this->pid_map->remove(p->PID, 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 {
|
||||
public:
|
||||
uint32_t currentPID;
|
||||
uint32_t stack;
|
||||
Terminal* terminal;
|
||||
|
||||
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
|
||||
|
||||
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();
|
||||
|
||||
Process* createProcess(char* filename);
|
||||
void destroyProcess(Process* p);
|
||||
//void loadPrimaryStack();
|
||||
};
|
||||
|
||||
#endif
|
@ -36,7 +36,7 @@ char decoded = 0;
|
||||
bool caps_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);
|
||||
outb(0x20, 0x21);
|
||||
if ((current_scancode&0x7f) == 0x2a)
|
||||
@ -54,7 +54,8 @@ __attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame
|
||||
}
|
||||
|
||||
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) {
|
||||
inb(0x60);
|
||||
|
@ -27,7 +27,7 @@ int main() {
|
||||
PageMap phys_pm(0xc0600000);
|
||||
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();
|
||||
init_atapio();
|
||||
|
||||
@ -47,6 +47,7 @@ int main() {
|
||||
Global::currentProc = &kernel;
|
||||
|
||||
Process* p1 = kernel.createProcess("WORLD BIN");
|
||||
kernel.createProcess("HELLO BIN");
|
||||
|
||||
init_keyboard();
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#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) {}
|
||||
|
||||
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;
|
||||
|
||||
stack32 -= 21;
|
||||
|
||||
stack32--;
|
||||
*stack32 = 0; // EAX
|
||||
stack32--;
|
||||
@ -87,6 +87,13 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha
|
||||
stack32--;
|
||||
*stack32 = 0; // EDI
|
||||
|
||||
stack32--;
|
||||
|
||||
stack32--;
|
||||
*stack32 = &catchall_return; // cachall_return
|
||||
|
||||
stack32--;
|
||||
|
||||
this->kernelStackPtr = stack32;
|
||||
|
||||
load_file(filename, program_data);
|
||||
|
@ -58,6 +58,20 @@ void Terminal::printf(const char* string, ...) {
|
||||
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) {
|
||||
this->cur_x = 0;
|
||||
this->cur_y++;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
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,
|
||||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 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] = {
|
||||
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,
|
||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 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] = {
|
||||
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0,
|
||||
0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', 0,
|
||||
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0,
|
||||
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 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)
|
||||
caps_on ^= 1;
|
||||
|
||||
/*if (scancode == 0x0e && index > 0) {
|
||||
set_curpos_raw(get_curpos()-1);
|
||||
non_moving_put(' ');
|
||||
buffer[--index] = 0;
|
||||
}*/
|
||||
|
||||
if (shift_on)
|
||||
decoded = key_to_char_shift[scancode&0x7f];
|
||||
else if (caps_on)
|
||||
@ -67,7 +61,12 @@ void readline(int max, char* buffer) {
|
||||
else
|
||||
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;
|
||||
char_print[0] = decoded;
|
||||
print(char_print);
|
@ -1,14 +1,14 @@
|
||||
OUTPUT_FORMAT(binary)
|
||||
OUTPUT_ARCH(i386:i386)
|
||||
|
||||
OUTPUT(build/program/world.bin)
|
||||
OUTPUT(build/world/world.bin)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x8020;
|
||||
|
||||
.text : {
|
||||
build/program_code_entry.o(.text)
|
||||
build/program/world.o(.text)
|
||||
build/world/world.o(.text)
|
||||
build/common/common.o(.text)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user