Added oneshot timer functionality. Added sleep function. Added proper tracking of physical pages allocated. Made the 0th page invalid. Fixed a 4KiB memory leak when destroying processes. Fixed scrolling colour in terminal.cpp
This commit is contained in:
parent
0fc40ad5e4
commit
dc2fe698a3
@ -46,6 +46,17 @@ void mark_unavailble(uint32_t address, uint32_t size, uint8_t* buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PDE* pde;
|
||||||
|
uint32_t page_directory_phys_addr;
|
||||||
|
uint32_t page_directory_phys_offset;
|
||||||
|
uint32_t page_bitmap_phys;
|
||||||
|
uint32_t page_bitmap_virt;
|
||||||
|
uint32_t stack_ptr;
|
||||||
|
uint32_t vga_addr;
|
||||||
|
uint32_t remainingPages;
|
||||||
|
} KernelInformationStruct;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
init_atapio();
|
init_atapio();
|
||||||
|
|
||||||
@ -55,6 +66,7 @@ void main() {
|
|||||||
// Zero out the bitmap.
|
// Zero out the bitmap.
|
||||||
memset(bitmap, 0x20000, 0);
|
memset(bitmap, 0x20000, 0);
|
||||||
// Ensure the bitmap data is clear
|
// Ensure the bitmap data is clear
|
||||||
|
uint32_t pages;
|
||||||
|
|
||||||
for (int i=0; e820_entries[i].length_low != 0 || e820_entries[i].length_high != 0; i++) {
|
for (int i=0; e820_entries[i].length_low != 0 || e820_entries[i].length_high != 0; i++) {
|
||||||
e820entry entry = e820_entries[i];
|
e820entry entry = e820_entries[i];
|
||||||
@ -74,6 +86,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t page_index = base / 4096;
|
uint32_t page_index = base / 4096;
|
||||||
|
pages += length / 4096;
|
||||||
|
|
||||||
for (int j=0; length > 4096; length -= 4096, j++) {
|
for (int j=0; length > 4096; length -= 4096, j++) {
|
||||||
set_bit(page_index + j, bitmap);
|
set_bit(page_index + j, bitmap);
|
||||||
@ -81,6 +94,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mark_unavailble(bitmap, 0x20000, bitmap);
|
mark_unavailble(bitmap, 0x20000, bitmap);
|
||||||
|
mark_unavailble(0, 0xFFFFF, bitmap);
|
||||||
|
|
||||||
// Page Directory
|
// Page Directory
|
||||||
PDE* kernel_page_directory = bitmap + 0x20000;
|
PDE* kernel_page_directory = bitmap + 0x20000;
|
||||||
@ -168,6 +182,20 @@ void main() {
|
|||||||
"mov %%cr0, %%eax;"
|
"mov %%cr0, %%eax;"
|
||||||
"or $0x80000000, %%eax;"
|
"or $0x80000000, %%eax;"
|
||||||
"mov %%eax, %%cr0" : : "m" (kernel_page_directory));
|
"mov %%eax, %%cr0" : : "m" (kernel_page_directory));
|
||||||
|
|
||||||
|
KernelInformationStruct* kstruct = 0xc1000000 + 16*0x1000 - sizeof(KernelInformationStruct);
|
||||||
|
*kstruct = (KernelInformationStruct){
|
||||||
|
.pde = 0xc0100000,
|
||||||
|
.page_directory_phys_addr = kernel_page_directory,
|
||||||
|
.page_directory_phys_offset = 0xc0100000 - (uint32_t)kernel_page_directory,
|
||||||
|
.page_bitmap_phys = 0xc0600000,
|
||||||
|
.page_bitmap_virt = 0xc0620000,
|
||||||
|
.stack_ptr = 0xc1000000 + 16*0x1000 - sizeof(KernelInformationStruct) - 4,
|
||||||
|
.vga_addr = 0xc07a0000,
|
||||||
|
.remainingPages = pages
|
||||||
|
};
|
||||||
|
|
||||||
((void(*)(void))0xc0000000)();
|
*(uint32_t*)(0xc100a004) = kstruct;
|
||||||
|
|
||||||
|
((void(*)())0xc0000000)();
|
||||||
}
|
}
|
@ -57,4 +57,49 @@ int int_to_hex(unsigned int number, char* string_buffer) {
|
|||||||
acc /= 0x10;
|
acc /= 0x10;
|
||||||
}
|
}
|
||||||
return (index+1);
|
return (index+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printf(const char* string, ...) {
|
||||||
|
va_list ptr;
|
||||||
|
va_start(ptr, string);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
char current;
|
||||||
|
|
||||||
|
while (current=string[index++]) {
|
||||||
|
if (current == '%') {
|
||||||
|
int type = string[index++];
|
||||||
|
int offset;
|
||||||
|
switch (type) {
|
||||||
|
case 'd': {
|
||||||
|
char decimal_buffer[11];
|
||||||
|
offset = int_to_decimal(va_arg(ptr, int), decimal_buffer);
|
||||||
|
printf(decimal_buffer + offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'x': {
|
||||||
|
char hex_buffer[8];
|
||||||
|
offset = int_to_hex(va_arg(ptr, int), hex_buffer);
|
||||||
|
printf(hex_buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 's': {
|
||||||
|
printf(va_arg(ptr, const char*));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'c': {
|
||||||
|
int promoted = va_arg(ptr, int);
|
||||||
|
char charred = promoted;
|
||||||
|
|
||||||
|
write(1, 0, &charred);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(1, 0, ¤t);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ptr);
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
#define COMMON_H
|
#define COMMON_H
|
||||||
|
|
||||||
#include "../kernel/types.h"
|
#include "../kernel/types.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
File,
|
File,
|
||||||
@ -42,5 +43,6 @@ typedef struct {
|
|||||||
void print(char* string);
|
void print(char* string);
|
||||||
int int_to_decimal(unsigned int number, char* string_buffer);
|
int int_to_decimal(unsigned int number, char* string_buffer);
|
||||||
int int_to_hex(unsigned int number, char* string_buffer);
|
int int_to_hex(unsigned int number, char* string_buffer);
|
||||||
|
void printf(const char* string, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -6,14 +6,19 @@ syscall_hdlr_1(bool, exists, "2", char*, path);
|
|||||||
syscall_hdlr_1(FSType, type, "3", char*, path);
|
syscall_hdlr_1(FSType, type, "3", char*, path);
|
||||||
syscall_hdlr_1(void*, malloc, "4", uint32_t, size);
|
syscall_hdlr_1(void*, malloc, "4", uint32_t, size);
|
||||||
syscall_hdlr_1(void, free, "5", void*, ptr);
|
syscall_hdlr_1(void, free, "5", void*, ptr);
|
||||||
|
syscall_hdlr_0(uint32_t, getMillisecondsElapsed, "6");
|
||||||
|
syscall_hdlr_1(uint32_t, exec, "7", uint32_t, filehandler);
|
||||||
syscall_hdlr_0(uint32_t, getPID, "8");
|
syscall_hdlr_0(uint32_t, getPID, "8");
|
||||||
|
syscall_hdlr_0(void, die, "9");
|
||||||
syscall_hdlr_3(int, read, "10", uint32_t, count, uint32_t, filehandler, uint8_t*, buffer);
|
syscall_hdlr_3(int, read, "10", uint32_t, count, uint32_t, filehandler, uint8_t*, buffer);
|
||||||
syscall_hdlr_3(int, write, "11", uint32_t, count, uint32_t, filehandler, const uint8_t*, buffer);
|
syscall_hdlr_3(int, write, "11", uint32_t, count, uint32_t, filehandler, const uint8_t*, buffer);
|
||||||
syscall_hdlr_1(uint32_t, exec, "7", uint32_t, filehandler);
|
syscall_hdlr_0(void, bindToKeyboard, "12");
|
||||||
syscall_hdlr_1(uint32_t, bindStdout, "13", uint32_t, PID);
|
syscall_hdlr_1(uint32_t, bindStdout, "13", uint32_t, PID);
|
||||||
syscall_hdlr_1(uint32_t, bindStdin, "14", uint32_t, PID);
|
syscall_hdlr_1(uint32_t, bindStdin, "14", uint32_t, PID);
|
||||||
syscall_hdlr_1(uint32_t, fopen, "15", char*, filename);
|
syscall_hdlr_1(uint32_t, fopen, "15", char*, filename);
|
||||||
syscall_hdlr_1(void, fclose, "16", uint32_t, filehandler);
|
syscall_hdlr_1(void, fclose, "16", uint32_t, filehandler);
|
||||||
syscall_hdlr_1(void, kill, "17", uint32_t, PID);
|
syscall_hdlr_1(void, kill, "17", uint32_t, PID);
|
||||||
syscall_hdlr_1(void, sleep, "18", uint32_t, time);
|
syscall_hdlr_1(void, sleep, "18", uint32_t, time);
|
||||||
syscall_hdlr_0(void, bindToKeyboard, "12");
|
|
||||||
|
syscall_hdlr_0(uint32_t, getRemainingPages, "19");
|
||||||
|
syscall_hdlr_0(uint32_t, getInitPages, "20");
|
@ -8,12 +8,6 @@ uint32_t kernel_allocate_area = 0xf0000000;
|
|||||||
|
|
||||||
uint32_t last_free_page = 0;
|
uint32_t last_free_page = 0;
|
||||||
|
|
||||||
/*void init_allocator() {
|
|
||||||
for (int i=0; i<1024; i++) {
|
|
||||||
kernel_page_tables[i] = 0xc0101000 + 0x1000*i;
|
|
||||||
}
|
|
||||||
}*/ // Don't do this.
|
|
||||||
|
|
||||||
void set_bit(uint32_t offset, uint8_t* buffer) {
|
void set_bit(uint32_t offset, uint8_t* buffer) {
|
||||||
uint32_t index = offset / 8;
|
uint32_t index = offset / 8;
|
||||||
uint32_t bit = offset % 8;
|
uint32_t bit = offset % 8;
|
||||||
|
@ -7,6 +7,7 @@ namespace Global {
|
|||||||
tss_struct* tss = 0;
|
tss_struct* tss = 0;
|
||||||
bool currentProcValid = false;
|
bool currentProcValid = false;
|
||||||
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
||||||
|
uint32_t milliseconds_elapsed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size) {
|
void* operator new (uint32_t size) {
|
||||||
|
@ -20,6 +20,7 @@ namespace Global {
|
|||||||
extern tss_struct* tss;
|
extern tss_struct* tss;
|
||||||
extern bool currentProcValid;
|
extern bool currentProcValid;
|
||||||
extern xnoe::hashtable<void*, ReadWriter*>* FH;
|
extern xnoe::hashtable<void*, ReadWriter*>* FH;
|
||||||
|
extern uint32_t milliseconds_elapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new (uint32_t size);
|
void* operator new (uint32_t size);
|
||||||
|
@ -26,7 +26,7 @@ void handle_fault(frame_struct* frame) {
|
|||||||
asm ("cli");
|
asm ("cli");
|
||||||
uint32_t problem_address;
|
uint32_t problem_address;
|
||||||
asm ("mov %%cr2, %0" : "=a" (problem_address):);
|
asm ("mov %%cr2, %0" : "=a" (problem_address):);
|
||||||
Global::kernel->terminal->printf("(CS %x EIP %x): ", frame->cs, frame->eip);
|
Global::kernel->terminal->printf("\x1b[44;37;1m(CS %x EIP %x): ", frame->cs, frame->eip);
|
||||||
switch (frame->gate) {
|
switch (frame->gate) {
|
||||||
case 0: // Divide by zero
|
case 0: // Divide by zero
|
||||||
Global::kernel->terminal->printf("Divide by Zero");
|
Global::kernel->terminal->printf("Divide by Zero");
|
||||||
@ -58,10 +58,7 @@ void handle_fault(frame_struct* frame) {
|
|||||||
Global::kernel->destroyProcess(Global::currentProc);
|
Global::kernel->destroyProcess(Global::currentProc);
|
||||||
|
|
||||||
Global::currentProcValid = false;
|
Global::currentProcValid = false;
|
||||||
|
context_switch(frame);
|
||||||
// Go in to an infinite loop
|
|
||||||
asm ("sti");
|
|
||||||
while (1) asm ("hlt");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +118,7 @@ void context_switch(frame_struct* frame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Global::currentProc = processes->start->elem;
|
Global::currentProc = processes->start->elem;
|
||||||
} while (Global::currentProc->state == Suspended);
|
} while (Global::currentProc->state != Running);
|
||||||
|
|
||||||
|
|
||||||
// Select the next processes page directory
|
// Select the next processes page directory
|
||||||
@ -153,11 +150,13 @@ namespace Timer {
|
|||||||
current = current->next;
|
current = current->next;
|
||||||
timed_events.remove(prev);
|
timed_events.remove(prev);
|
||||||
delete prev;
|
delete prev;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current->elem = TimedEvent(count, xnoe::get<1>(t), xnoe::get<2>(t), xnoe::get<3>(t), xnoe::get<4>(t));
|
current->elem = TimedEvent(count, xnoe::get<1>(t), xnoe::get<2>(t), xnoe::get<3>(t), xnoe::get<4>(t));
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
Global::milliseconds_elapsed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary, bool oneshot=false) {
|
void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary, bool oneshot=false) {
|
||||||
@ -177,10 +176,10 @@ void syscall(frame_struct* frame) {
|
|||||||
// 3: type :: char* path -> FSType
|
// 3: type :: char* path -> FSType
|
||||||
// 4: localalloc :: uint32_t size -> void* ptr
|
// 4: localalloc :: uint32_t size -> void* ptr
|
||||||
// 5: localdelete :: void* ptr -> void
|
// 5: localdelete :: void* ptr -> void
|
||||||
// 6: X
|
// 6: getMillisecondsElapsed :: void -> uint32_t
|
||||||
// 7: exec :: void* filehandler -> int PID // Spawns a process and returns its PID.
|
// 7: exec :: void* filehandler -> int PID // Spawns a process and returns its PID.
|
||||||
// 8: getPID: returns the current process's PID (out eax: uint32_t)
|
// 8: getPID: returns the current process's PID (out eax: uint32_t)
|
||||||
// 9: getFileHandler :: char* path -> void* // Returns a file handlers for a specific file
|
// 9: die :: destroys the current process void -> void
|
||||||
// 10: read :: uint32_t count -> void* filehandler -> uint8_t* outputbuffer -> int read // Reads from a file handler in to a buffer, returns successful read
|
// 10: read :: uint32_t count -> void* filehandler -> uint8_t* outputbuffer -> int read // Reads from a file handler in to a buffer, returns successful read
|
||||||
// 11: write :: uint32_t count -> void* filehandler -> uint8_t* inputbuffer -> int written // Reads from a buffer in to a file, returns successful written
|
// 11: write :: uint32_t count -> void* filehandler -> uint8_t* inputbuffer -> int written // Reads from a buffer in to a file, returns successful written
|
||||||
// 12: bindToKeyboard :: void -> void // Binds the current process's stdout to the keyboard.
|
// 12: bindToKeyboard :: void -> void // Binds the current process's stdout to the keyboard.
|
||||||
@ -225,6 +224,7 @@ void syscall(frame_struct* frame) {
|
|||||||
currentProc->deallocate(frame->ebx);
|
currentProc->deallocate(frame->ebx);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
rval = Global::milliseconds_elapsed;
|
||||||
break;
|
break;
|
||||||
case 7: {
|
case 7: {
|
||||||
asm("cli");
|
asm("cli");
|
||||||
@ -238,6 +238,13 @@ void syscall(frame_struct* frame) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
|
Global::kernel->PD->select();
|
||||||
|
|
||||||
|
// We can now safely delete the current process
|
||||||
|
Global::kernel->destroyProcess(Global::currentProc);
|
||||||
|
|
||||||
|
Global::currentProcValid = false;
|
||||||
|
context_switch(frame);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 10: {
|
case 10: {
|
||||||
@ -348,6 +355,13 @@ void syscall(frame_struct* frame) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 19:
|
||||||
|
rval = Global::kernel->phys->remainingPages;
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
rval = Global::kernel->phys->initPages;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -56,4 +56,9 @@ struct __attribute__((packed)) idt_desc {
|
|||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void context_switch(frame_struct* frame);
|
||||||
|
void handle_fault(frame_struct* frame);
|
||||||
|
void syscall(frame_struct* frame);
|
||||||
|
void ignore_interrupt(frame_struct* frame);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -12,8 +12,6 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
|
|||||||
this->stack = stack;
|
this->stack = stack;
|
||||||
|
|
||||||
this->lastFH = 8;
|
this->lastFH = 8;
|
||||||
|
|
||||||
//this->processes.append(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::init_kernel() {
|
void Kernel::init_kernel() {
|
||||||
@ -53,8 +51,4 @@ int Kernel::mapFH(ReadWriter* fh) {
|
|||||||
|
|
||||||
void Kernel::unmapFH(uint32_t fh) {
|
void Kernel::unmapFH(uint32_t fh) {
|
||||||
Global::FH->remove((void*)fh);
|
Global::FH->remove((void*)fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void Kernel::loadPrimaryStack() {
|
|
||||||
// asm volatile("mov %0, %%esp"::"m"(this->stack - 64));
|
|
||||||
//}
|
|
@ -17,21 +17,32 @@
|
|||||||
#include "filesystem/fat16.h"
|
#include "filesystem/fat16.h"
|
||||||
#include "filesystem/devfs.h"
|
#include "filesystem/devfs.h"
|
||||||
|
|
||||||
int main() {
|
struct KernelInformationStruct {
|
||||||
|
PDE* pde;
|
||||||
|
uint32_t page_directory_phys_addr;
|
||||||
|
uint32_t page_directory_phys_offset;
|
||||||
|
uint32_t page_bitmap_phys;
|
||||||
|
uint32_t page_bitmap_virt;
|
||||||
|
uint32_t stack_ptr;
|
||||||
|
uint32_t vga_addr;
|
||||||
|
uint32_t remainingPages;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(KernelInformationStruct* kstruct) {
|
||||||
init_gdt();
|
init_gdt();
|
||||||
|
|
||||||
PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000);
|
PageDirectory kernel_pd = PageDirectory(kstruct->pde, kstruct->page_directory_phys_addr, kstruct->page_directory_phys_offset);
|
||||||
|
|
||||||
kernel_pd.select();
|
kernel_pd.select();
|
||||||
kernel_pd.unmap(0x8000);
|
kernel_pd.unmap(0x8000);
|
||||||
|
|
||||||
PageMap phys_pm(0xc0600000);
|
PageMap phys_pm(kstruct->page_bitmap_phys, kstruct->remainingPages);
|
||||||
PageMap virt_pm(0xc0620000);
|
PageMap virt_pm(kstruct->page_bitmap_virt);
|
||||||
|
|
||||||
Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000, 0xc1006000);
|
Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000, kstruct->stack_ptr);
|
||||||
kernel.init_kernel();
|
kernel.init_kernel();
|
||||||
|
|
||||||
VGAModeTerminal* term = new VGAModeTerminal(0xc07a0000);
|
VGAModeTerminal* term = new VGAModeTerminal(kstruct->vga_addr);
|
||||||
|
|
||||||
kernel.terminal = term;
|
kernel.terminal = term;
|
||||||
|
|
||||||
|
@ -10,8 +10,9 @@ void memcpy(uint8_t* src, uint8_t* dst, uint32_t count) {
|
|||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
PageMap::PageMap(uint32_t map) {
|
PageMap::PageMap(uint32_t map, uint32_t remainingPages) {
|
||||||
this->pagemap = (uint8_t*)map;
|
this->pagemap = (uint8_t*)map;
|
||||||
|
this->initPages = this->remainingPages = remainingPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageMap::PageMap() {
|
PageMap::PageMap() {
|
||||||
@ -38,6 +39,8 @@ void PageMap::unset_bit(uint32_t index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PageMap::bit_set(uint32_t index) {
|
bool PageMap::bit_set(uint32_t index) {
|
||||||
|
if (!index)
|
||||||
|
return false;
|
||||||
uint32_t offset = index % 8;
|
uint32_t offset = index % 8;
|
||||||
uint32_t i = index / 8;
|
uint32_t i = index / 8;
|
||||||
|
|
||||||
@ -46,20 +49,24 @@ bool PageMap::bit_set(uint32_t index) {
|
|||||||
|
|
||||||
void PageMap::mark_unavailable(uint32_t address) {
|
void PageMap::mark_unavailable(uint32_t address) {
|
||||||
unset_bit(address >> 12);
|
unset_bit(address >> 12);
|
||||||
|
this->remainingPages--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageMap::mark_unavailable(uint32_t address, uint32_t count) {
|
void PageMap::mark_unavailable(uint32_t address, uint32_t count) {
|
||||||
for (int i=0; i<count; i++)
|
for (int i=0; i<count; i++)
|
||||||
unset_bit((address >> 12) + i);
|
unset_bit((address >> 12) + i);
|
||||||
|
this->remainingPages -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageMap::mark_available(uint32_t address) {
|
void PageMap::mark_available(uint32_t address) {
|
||||||
set_bit(address >> 12);
|
set_bit(address >> 12);
|
||||||
|
this->remainingPages++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PageMap::mark_available(uint32_t address, uint32_t count) {
|
void PageMap::mark_available(uint32_t address, uint32_t count) {
|
||||||
for (int i=0; i<count; i++)
|
for (int i=0; i<count; i++)
|
||||||
set_bit((address >> 12) + i);
|
set_bit((address >> 12) + i);
|
||||||
|
this->remainingPages += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PageMap::available(uint32_t address) {
|
bool PageMap::available(uint32_t address) {
|
||||||
@ -91,6 +98,7 @@ PageTable::PageTable(uint32_t phys, uint32_t virt) {
|
|||||||
virt_addr = virt;
|
virt_addr = virt;
|
||||||
|
|
||||||
page_table = (PTE*)virt;
|
page_table = (PTE*)virt;
|
||||||
|
valid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageTable::PageTable(){
|
PageTable::PageTable(){
|
||||||
@ -100,6 +108,7 @@ PageTable::PageTable(){
|
|||||||
phys_addr = (Global::allocator->virtual_to_physical(virt_addr)) >> 12;
|
phys_addr = (Global::allocator->virtual_to_physical(virt_addr)) >> 12;
|
||||||
|
|
||||||
page_table = (PTE*)virt_addr;
|
page_table = (PTE*)virt_addr;
|
||||||
|
valid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PageTable::~PageTable() {
|
PageTable::~PageTable() {
|
||||||
@ -149,7 +158,7 @@ PageDirectory::PageDirectory(PDE* page_directory, uint32_t phys_addr, uint32_t o
|
|||||||
|
|
||||||
for (int i=0; i<1024; i++) {
|
for (int i=0; i<1024; i++) {
|
||||||
uint32_t table_phys_addr = page_directory[i].getPhysicalPTAddress();
|
uint32_t table_phys_addr = page_directory[i].getPhysicalPTAddress();
|
||||||
new (page_tables + i) PageTable(table_phys_addr >> 12, table_phys_addr + offset);
|
new (&page_tables[i]) PageTable(table_phys_addr >> 12, table_phys_addr + offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +174,7 @@ PageDirectory::PageDirectory() {
|
|||||||
|
|
||||||
PageDirectory::~PageDirectory() {
|
PageDirectory::~PageDirectory() {
|
||||||
for (int i=0; i<1024; i++)
|
for (int i=0; i<1024; i++)
|
||||||
if (page_tables[i].virt_addr)
|
if (page_tables[i].valid)
|
||||||
page_tables[i].~PageTable();
|
page_tables[i].~PageTable();
|
||||||
delete page_directory;
|
delete page_directory;
|
||||||
}
|
}
|
||||||
@ -173,8 +182,8 @@ PageDirectory::~PageDirectory() {
|
|||||||
void PageDirectory::map(uint32_t phys, uint32_t virt, uint8_t privilege) {
|
void PageDirectory::map(uint32_t phys, uint32_t virt, uint8_t privilege) {
|
||||||
split_addr* split = (split_addr*)&virt;
|
split_addr* split = (split_addr*)&virt;
|
||||||
|
|
||||||
if (!page_tables[split->pd_index].virt_addr)
|
if (!page_tables[split->pd_index].valid)
|
||||||
new (page_tables + split->pd_index) PageTable();
|
new (&page_tables[split->pd_index]) PageTable();
|
||||||
|
|
||||||
page_directory[split->pd_index] = (PDE){
|
page_directory[split->pd_index] = (PDE){
|
||||||
.present = 1,
|
.present = 1,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
void memset(uint8_t* address, uint32_t count, uint8_t value);
|
void memset(uint8_t* address, uint32_t count, uint8_t value);
|
||||||
void memcpy(uint8_t* src, uint8_t* dst, uint32_t count);
|
void memcpy(uint8_t* src, uint8_t* dst, uint32_t count);
|
||||||
|
|
||||||
class __attribute__((packed)) PageMap {
|
class PageMap {
|
||||||
private:
|
private:
|
||||||
uint8_t* pagemap;
|
uint8_t* pagemap;
|
||||||
|
|
||||||
@ -18,7 +18,10 @@ private:
|
|||||||
bool bit_set(uint32_t index);
|
bool bit_set(uint32_t index);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PageMap(uint32_t map);
|
uint32_t remainingPages;
|
||||||
|
uint32_t initPages;
|
||||||
|
|
||||||
|
PageMap(uint32_t map, uint32_t remainingPages=0x100000);
|
||||||
PageMap();
|
PageMap();
|
||||||
|
|
||||||
~PageMap();
|
~PageMap();
|
||||||
@ -40,6 +43,8 @@ struct PageTable {
|
|||||||
|
|
||||||
uint32_t phys_addr;
|
uint32_t phys_addr;
|
||||||
uint32_t virt_addr;
|
uint32_t virt_addr;
|
||||||
|
uint32_t valid = 0;
|
||||||
|
uint32_t reserved;
|
||||||
|
|
||||||
PageTable(uint32_t phys, uint32_t virt);
|
PageTable(uint32_t phys, uint32_t virt);
|
||||||
PageTable();
|
PageTable();
|
||||||
@ -77,12 +82,12 @@ public:
|
|||||||
|
|
||||||
class Allocator {
|
class Allocator {
|
||||||
protected:
|
protected:
|
||||||
static PageMap* phys;
|
|
||||||
PageMap* virt;
|
|
||||||
|
|
||||||
uint32_t virt_alloc_base;
|
uint32_t virt_alloc_base;
|
||||||
uint8_t privilege;
|
uint8_t privilege;
|
||||||
public:
|
public:
|
||||||
|
static PageMap* phys;
|
||||||
|
PageMap* virt;
|
||||||
|
|
||||||
PageDirectory* PD;
|
PageDirectory* PD;
|
||||||
|
|
||||||
Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
Allocator(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base);
|
||||||
@ -93,6 +98,8 @@ public:
|
|||||||
virtual void* allocate(uint32_t size);
|
virtual void* allocate(uint32_t size);
|
||||||
virtual void deallocate(uint32_t virt_addr);
|
virtual void deallocate(uint32_t virt_addr);
|
||||||
|
|
||||||
|
void* getMappingOf(uint32_t phys_addr, uint32_t length_pages);
|
||||||
|
|
||||||
uint32_t virtual_to_physical(uint32_t virt);
|
uint32_t virtual_to_physical(uint32_t virt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, uin
|
|||||||
|
|
||||||
this->kernelStackPtr = stack32;
|
this->kernelStackPtr = stack32;
|
||||||
|
|
||||||
|
filereader->seek(0);
|
||||||
filereader->read(filesize, program_data);
|
filereader->read(filesize, program_data);
|
||||||
|
|
||||||
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||||
@ -101,11 +102,8 @@ Process::~Process() {
|
|||||||
xnoe::linkedlistelem<AllocTracker>* active = next;
|
xnoe::linkedlistelem<AllocTracker>* active = next;
|
||||||
next = next->next;
|
next = next->next;
|
||||||
|
|
||||||
//printf("Deleted %x\n", active->elem.page_base);
|
this->deallocate(active->elem.page_base);
|
||||||
|
|
||||||
this->deallocate(active->elem.page_base+1);
|
|
||||||
}
|
}
|
||||||
this->deallocate(stack);
|
|
||||||
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||||
delete kernelStackPtr;
|
delete kernelStackPtr;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ void Terminal::scroll_up(uint32_t count) {
|
|||||||
// Clear the last line
|
// Clear the last line
|
||||||
uint16_t* last_line = buffer + (height * pages - 1) * width;
|
uint16_t* last_line = buffer + (height * pages - 1) * width;
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
last_line[x] = 0x20 | (edata << 8);
|
last_line[x] = 0x0720; //| (edata << 8);
|
||||||
}
|
}
|
||||||
this->cur_y--;
|
this->cur_y--;
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ void Terminal::scroll_down(uint32_t count) {
|
|||||||
// Clear the last line
|
// Clear the last line
|
||||||
uint16_t* last_line = buffer + (height * (pages - 1)) * width;
|
uint16_t* last_line = buffer + (height * (pages - 1)) * width;
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
last_line[x] = 0x20 | (edata << 8);
|
last_line[x] = 0x0720;// | (edata << 8);
|
||||||
}
|
}
|
||||||
this->cur_y--;
|
this->cur_y--;
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ void Terminal::putchar(uint8_t c) {
|
|||||||
}
|
}
|
||||||
last_page_pointer[this->cur_y*this->width+this->cur_x] = ' ' | (edata<<8);
|
last_page_pointer[this->cur_y*this->width+this->cur_x] = ' ' | (edata<<8);
|
||||||
if (active)
|
if (active)
|
||||||
putchar_internal(this->cur_y*this->width+this->cur_x, ' ');
|
putchar_internal(this->cur_y*this->width+this->cur_x, ' ',this->edata);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (this->cur_x == this->width) {
|
if (this->cur_x == this->width) {
|
||||||
@ -96,7 +96,7 @@ void Terminal::putchar(uint8_t c) {
|
|||||||
last_page_pointer[this->cur_y*this->width+this->cur_x] = c | (edata<<8);
|
last_page_pointer[this->cur_y*this->width+this->cur_x] = c | (edata<<8);
|
||||||
|
|
||||||
if (active)
|
if (active)
|
||||||
putchar_internal(this->cur_y*this->width+this->cur_x, c);
|
putchar_internal(this->cur_y*this->width+this->cur_x, c, this->edata);
|
||||||
this->cur_x++;
|
this->cur_x++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -218,7 +218,7 @@ void Terminal::putchar(uint8_t c) {
|
|||||||
|
|
||||||
void Terminal::update(){}
|
void Terminal::update(){}
|
||||||
void Terminal::update_cur(){}
|
void Terminal::update_cur(){}
|
||||||
void Terminal::putchar_internal(uint32_t ptr, uint8_t c) {}
|
void Terminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {}
|
||||||
|
|
||||||
Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages)
|
Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages)
|
||||||
: ReadWriter(0) {
|
: ReadWriter(0) {
|
||||||
@ -346,7 +346,7 @@ void TextModeTerminal::update_cur() {
|
|||||||
outb(0x3D5, cursor_position_split[1]);
|
outb(0x3D5, cursor_position_split[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextModeTerminal::putchar_internal(uint32_t ptr, uint8_t c) {
|
void TextModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {
|
||||||
text_mode_pointer[ptr] = c | (edata << 8);
|
text_mode_pointer[ptr] = c | (edata << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ TextModeTerminal::TextModeTerminal(uint16_t* text_mode_pointer): Terminal(80, 25
|
|||||||
void VGAModeTerminal::update() {
|
void VGAModeTerminal::update() {
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
putchar_internal(y * width + x, (uint8_t)(current_page_pointer[y * width + x]));
|
putchar_internal(y * width + x, (uint8_t)(current_page_pointer[y * width + x]), (uint8_t)(current_page_pointer[y * width + x]>>8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,7 +366,7 @@ void VGAModeTerminal::update_cur() {
|
|||||||
// Todo: Implement cursor for VGAModeTerminal
|
// Todo: Implement cursor for VGAModeTerminal
|
||||||
}
|
}
|
||||||
|
|
||||||
void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c) {
|
void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {
|
||||||
uint32_t col = ptr % width;
|
uint32_t col = ptr % width;
|
||||||
uint32_t row = ptr / width;
|
uint32_t row = ptr / width;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class Terminal: public ReadWriter {
|
|||||||
private:
|
private:
|
||||||
virtual void update();
|
virtual void update();
|
||||||
virtual void update_cur();
|
virtual void update_cur();
|
||||||
virtual void putchar_internal(uint32_t ptr, uint8_t c);
|
virtual void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata);
|
||||||
|
|
||||||
void scroll_up(uint32_t count=1);
|
void scroll_up(uint32_t count=1);
|
||||||
void scroll_down(uint32_t count=1);
|
void scroll_down(uint32_t count=1);
|
||||||
@ -81,7 +81,7 @@ class TextModeTerminal : public Terminal {
|
|||||||
private:
|
private:
|
||||||
void update() override;
|
void update() override;
|
||||||
void update_cur() override;
|
void update_cur() override;
|
||||||
void putchar_internal(uint32_t ptr, uint8_t c) override;
|
void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) override;
|
||||||
|
|
||||||
uint16_t* text_mode_pointer;
|
uint16_t* text_mode_pointer;
|
||||||
public:
|
public:
|
||||||
@ -93,7 +93,7 @@ class VGAModeTerminal : public Terminal {
|
|||||||
private:
|
private:
|
||||||
void update() override;
|
void update() override;
|
||||||
void update_cur() override;
|
void update_cur() override;
|
||||||
void putchar_internal(uint32_t ptr, uint8_t c) override;
|
void putchar_internal(uint32_t ptr, uint8_t c,uint8_t edata) override;
|
||||||
|
|
||||||
void put_pixel(uint32_t x, uint32_t y, uint8_t color);
|
void put_pixel(uint32_t x, uint32_t y, uint8_t color);
|
||||||
void put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte);
|
void put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte);
|
||||||
|
4
src/programs/crash/crash.c
Normal file
4
src/programs/crash/crash.c
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
int main() {
|
||||||
|
// Cause a Division by zero by trying to divide by zero.
|
||||||
|
int x = 1 / 0;
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
_start:
|
_start:
|
||||||
call main
|
call main
|
||||||
_loop:
|
call die
|
||||||
jmp _loop
|
|
||||||
|
|
||||||
|
extern die
|
||||||
extern main
|
extern main
|
@ -1,8 +1,11 @@
|
|||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
uint32_t crashBin = fopen("/crash.bin");
|
||||||
while (1) {
|
while (1) {
|
||||||
print("Hello, World!\n");
|
printf("Time Elapsed: %dms\n", getMillisecondsElapsed());
|
||||||
sleep(200);
|
printf("Init. Pages: %d\nRemaining Pages: %d\n", getInitPages(), getRemainingPages());
|
||||||
|
exec(crashBin);
|
||||||
|
sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ OUTPUT_FORMAT(binary)
|
|||||||
OUTPUT_ARCH(i386:i386)
|
OUTPUT_ARCH(i386:i386)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x20;
|
. = 0x1020;
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
build/programs/entry.o(.text)
|
build/programs/entry.o(.text)
|
||||||
|
@ -70,6 +70,7 @@ void writeStrToBuf(char* c, procbuffer* b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void displayBuf(procbuffer* b, int dx, int dy) {
|
void displayBuf(procbuffer* b, int dx, int dy) {
|
||||||
|
print("\x1b[42;36;1m");
|
||||||
char pset[9] = "\x1b[00;00H";
|
char pset[9] = "\x1b[00;00H";
|
||||||
for (int i=0; i<dy;i++) {
|
for (int i=0; i<dy;i++) {
|
||||||
pset[3]++;
|
pset[3]++;
|
||||||
@ -182,7 +183,6 @@ int main() {
|
|||||||
write(90, 0, bottom);
|
write(90, 0, bottom);
|
||||||
for (int i=0; i<90;i++)
|
for (int i=0; i<90;i++)
|
||||||
write(1, 0, &plus);
|
write(1, 0, &plus);
|
||||||
print("\x1b[42;36;1m");
|
|
||||||
|
|
||||||
uint32_t program = fopen("/hello.bin");
|
uint32_t program = fopen("/hello.bin");
|
||||||
uint32_t p1 = exec(program);
|
uint32_t p1 = exec(program);
|
||||||
@ -229,6 +229,7 @@ int main() {
|
|||||||
if (read(1, 1, c)) {
|
if (read(1, 1, c)) {
|
||||||
if (c[0] == ':') {
|
if (c[0] == ':') {
|
||||||
char buf[32] = {0};
|
char buf[32] = {0};
|
||||||
|
print("\x1b[45;33;1m");
|
||||||
print("\x1b[59;2H");
|
print("\x1b[59;2H");
|
||||||
print(": ");
|
print(": ");
|
||||||
print("\x1b[59;3H");
|
print("\x1b[59;3H");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user