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() {
|
||||
init_atapio();
|
||||
|
||||
@ -55,6 +66,7 @@ void main() {
|
||||
// Zero out the bitmap.
|
||||
memset(bitmap, 0x20000, 0);
|
||||
// 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++) {
|
||||
e820entry entry = e820_entries[i];
|
||||
@ -74,6 +86,7 @@ void main() {
|
||||
}
|
||||
}
|
||||
uint32_t page_index = base / 4096;
|
||||
pages += length / 4096;
|
||||
|
||||
for (int j=0; length > 4096; length -= 4096, j++) {
|
||||
set_bit(page_index + j, bitmap);
|
||||
@ -81,6 +94,7 @@ void main() {
|
||||
}
|
||||
|
||||
mark_unavailble(bitmap, 0x20000, bitmap);
|
||||
mark_unavailble(0, 0xFFFFF, bitmap);
|
||||
|
||||
// Page Directory
|
||||
PDE* kernel_page_directory = bitmap + 0x20000;
|
||||
@ -169,5 +183,19 @@ void main() {
|
||||
"or $0x80000000, %%eax;"
|
||||
"mov %%eax, %%cr0" : : "m" (kernel_page_directory));
|
||||
|
||||
((void(*)(void))0xc0000000)();
|
||||
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
|
||||
};
|
||||
|
||||
*(uint32_t*)(0xc100a004) = kstruct;
|
||||
|
||||
((void(*)())0xc0000000)();
|
||||
}
|
@ -58,3 +58,48 @@ int int_to_hex(unsigned int number, char* string_buffer) {
|
||||
}
|
||||
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
|
||||
|
||||
#include "../kernel/types.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef enum {
|
||||
File,
|
||||
@ -42,5 +43,6 @@ typedef struct {
|
||||
void print(char* string);
|
||||
int int_to_decimal(unsigned int number, char* string_buffer);
|
||||
int int_to_hex(unsigned int number, char* string_buffer);
|
||||
void printf(const char* string, ...);
|
||||
|
||||
#endif
|
@ -6,14 +6,19 @@ syscall_hdlr_1(bool, exists, "2", char*, path);
|
||||
syscall_hdlr_1(FSType, type, "3", char*, path);
|
||||
syscall_hdlr_1(void*, malloc, "4", uint32_t, size);
|
||||
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(void, die, "9");
|
||||
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_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, bindStdin, "14", uint32_t, PID);
|
||||
syscall_hdlr_1(uint32_t, fopen, "15", char*, filename);
|
||||
syscall_hdlr_1(void, fclose, "16", uint32_t, filehandler);
|
||||
syscall_hdlr_1(void, kill, "17", uint32_t, PID);
|
||||
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;
|
||||
|
||||
/*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) {
|
||||
uint32_t index = offset / 8;
|
||||
uint32_t bit = offset % 8;
|
||||
|
@ -7,6 +7,7 @@ namespace Global {
|
||||
tss_struct* tss = 0;
|
||||
bool currentProcValid = false;
|
||||
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
|
||||
uint32_t milliseconds_elapsed = 0;
|
||||
}
|
||||
|
||||
void* operator new (uint32_t size) {
|
||||
|
@ -20,6 +20,7 @@ namespace Global {
|
||||
extern tss_struct* tss;
|
||||
extern bool currentProcValid;
|
||||
extern xnoe::hashtable<void*, ReadWriter*>* FH;
|
||||
extern uint32_t milliseconds_elapsed;
|
||||
}
|
||||
|
||||
void* operator new (uint32_t size);
|
||||
|
@ -26,7 +26,7 @@ void handle_fault(frame_struct* frame) {
|
||||
asm ("cli");
|
||||
uint32_t 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) {
|
||||
case 0: // 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::currentProcValid = false;
|
||||
|
||||
// Go in to an infinite loop
|
||||
asm ("sti");
|
||||
while (1) asm ("hlt");
|
||||
context_switch(frame);
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,7 +118,7 @@ void context_switch(frame_struct* frame) {
|
||||
}
|
||||
}
|
||||
Global::currentProc = processes->start->elem;
|
||||
} while (Global::currentProc->state == Suspended);
|
||||
} while (Global::currentProc->state != Running);
|
||||
|
||||
|
||||
// Select the next processes page directory
|
||||
@ -153,11 +150,13 @@ namespace Timer {
|
||||
current = current->next;
|
||||
timed_events.remove(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 = current->next;
|
||||
}
|
||||
Global::milliseconds_elapsed++;
|
||||
}
|
||||
|
||||
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
|
||||
// 4: localalloc :: uint32_t size -> void* ptr
|
||||
// 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.
|
||||
// 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
|
||||
// 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.
|
||||
@ -225,6 +224,7 @@ void syscall(frame_struct* frame) {
|
||||
currentProc->deallocate(frame->ebx);
|
||||
break;
|
||||
case 6:
|
||||
rval = Global::milliseconds_elapsed;
|
||||
break;
|
||||
case 7: {
|
||||
asm("cli");
|
||||
@ -238,6 +238,13 @@ void syscall(frame_struct* frame) {
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case 10: {
|
||||
@ -348,6 +355,13 @@ void syscall(frame_struct* frame) {
|
||||
break;
|
||||
}
|
||||
|
||||
case 19:
|
||||
rval = Global::kernel->phys->remainingPages;
|
||||
break;
|
||||
case 20:
|
||||
rval = Global::kernel->phys->initPages;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -56,4 +56,9 @@ struct __attribute__((packed)) idt_desc {
|
||||
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
|
@ -12,8 +12,6 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint
|
||||
this->stack = stack;
|
||||
|
||||
this->lastFH = 8;
|
||||
|
||||
//this->processes.append(this);
|
||||
}
|
||||
|
||||
void Kernel::init_kernel() {
|
||||
@ -54,7 +52,3 @@ int Kernel::mapFH(ReadWriter* fh) {
|
||||
void Kernel::unmapFH(uint32_t 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/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();
|
||||
|
||||
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.unmap(0x8000);
|
||||
|
||||
PageMap phys_pm(0xc0600000);
|
||||
PageMap virt_pm(0xc0620000);
|
||||
PageMap phys_pm(kstruct->page_bitmap_phys, kstruct->remainingPages);
|
||||
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();
|
||||
|
||||
VGAModeTerminal* term = new VGAModeTerminal(0xc07a0000);
|
||||
VGAModeTerminal* term = new VGAModeTerminal(kstruct->vga_addr);
|
||||
|
||||
kernel.terminal = term;
|
||||
|
||||
|
@ -10,8 +10,9 @@ void memcpy(uint8_t* src, uint8_t* dst, uint32_t count) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
||||
PageMap::PageMap(uint32_t map) {
|
||||
PageMap::PageMap(uint32_t map, uint32_t remainingPages) {
|
||||
this->pagemap = (uint8_t*)map;
|
||||
this->initPages = this->remainingPages = remainingPages;
|
||||
}
|
||||
|
||||
PageMap::PageMap() {
|
||||
@ -38,6 +39,8 @@ void PageMap::unset_bit(uint32_t index) {
|
||||
}
|
||||
|
||||
bool PageMap::bit_set(uint32_t index) {
|
||||
if (!index)
|
||||
return false;
|
||||
uint32_t offset = 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) {
|
||||
unset_bit(address >> 12);
|
||||
this->remainingPages--;
|
||||
}
|
||||
|
||||
void PageMap::mark_unavailable(uint32_t address, uint32_t count) {
|
||||
for (int i=0; i<count; i++)
|
||||
unset_bit((address >> 12) + i);
|
||||
this->remainingPages -= count;
|
||||
}
|
||||
|
||||
void PageMap::mark_available(uint32_t address) {
|
||||
set_bit(address >> 12);
|
||||
this->remainingPages++;
|
||||
}
|
||||
|
||||
void PageMap::mark_available(uint32_t address, uint32_t count) {
|
||||
for (int i=0; i<count; i++)
|
||||
set_bit((address >> 12) + i);
|
||||
this->remainingPages += count;
|
||||
}
|
||||
|
||||
bool PageMap::available(uint32_t address) {
|
||||
@ -91,6 +98,7 @@ PageTable::PageTable(uint32_t phys, uint32_t virt) {
|
||||
virt_addr = virt;
|
||||
|
||||
page_table = (PTE*)virt;
|
||||
valid = 1;
|
||||
}
|
||||
|
||||
PageTable::PageTable(){
|
||||
@ -100,6 +108,7 @@ PageTable::PageTable(){
|
||||
phys_addr = (Global::allocator->virtual_to_physical(virt_addr)) >> 12;
|
||||
|
||||
page_table = (PTE*)virt_addr;
|
||||
valid = 1;
|
||||
}
|
||||
|
||||
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++) {
|
||||
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() {
|
||||
for (int i=0; i<1024; i++)
|
||||
if (page_tables[i].virt_addr)
|
||||
if (page_tables[i].valid)
|
||||
page_tables[i].~PageTable();
|
||||
delete page_directory;
|
||||
}
|
||||
@ -173,8 +182,8 @@ PageDirectory::~PageDirectory() {
|
||||
void PageDirectory::map(uint32_t phys, uint32_t virt, uint8_t privilege) {
|
||||
split_addr* split = (split_addr*)&virt;
|
||||
|
||||
if (!page_tables[split->pd_index].virt_addr)
|
||||
new (page_tables + split->pd_index) PageTable();
|
||||
if (!page_tables[split->pd_index].valid)
|
||||
new (&page_tables[split->pd_index]) PageTable();
|
||||
|
||||
page_directory[split->pd_index] = (PDE){
|
||||
.present = 1,
|
||||
|
@ -8,7 +8,7 @@
|
||||
void memset(uint8_t* address, uint32_t count, uint8_t value);
|
||||
void memcpy(uint8_t* src, uint8_t* dst, uint32_t count);
|
||||
|
||||
class __attribute__((packed)) PageMap {
|
||||
class PageMap {
|
||||
private:
|
||||
uint8_t* pagemap;
|
||||
|
||||
@ -18,7 +18,10 @@ private:
|
||||
bool bit_set(uint32_t index);
|
||||
|
||||
public:
|
||||
PageMap(uint32_t map);
|
||||
uint32_t remainingPages;
|
||||
uint32_t initPages;
|
||||
|
||||
PageMap(uint32_t map, uint32_t remainingPages=0x100000);
|
||||
PageMap();
|
||||
|
||||
~PageMap();
|
||||
@ -40,6 +43,8 @@ struct PageTable {
|
||||
|
||||
uint32_t phys_addr;
|
||||
uint32_t virt_addr;
|
||||
uint32_t valid = 0;
|
||||
uint32_t reserved;
|
||||
|
||||
PageTable(uint32_t phys, uint32_t virt);
|
||||
PageTable();
|
||||
@ -77,12 +82,12 @@ public:
|
||||
|
||||
class Allocator {
|
||||
protected:
|
||||
static PageMap* phys;
|
||||
PageMap* virt;
|
||||
|
||||
uint32_t virt_alloc_base;
|
||||
uint8_t privilege;
|
||||
public:
|
||||
static PageMap* phys;
|
||||
PageMap* virt;
|
||||
|
||||
PageDirectory* PD;
|
||||
|
||||
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 deallocate(uint32_t virt_addr);
|
||||
|
||||
void* getMappingOf(uint32_t phys_addr, uint32_t length_pages);
|
||||
|
||||
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;
|
||||
|
||||
filereader->seek(0);
|
||||
filereader->read(filesize, program_data);
|
||||
|
||||
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||
@ -101,11 +102,8 @@ Process::~Process() {
|
||||
xnoe::linkedlistelem<AllocTracker>* active = next;
|
||||
next = next->next;
|
||||
|
||||
//printf("Deleted %x\n", active->elem.page_base);
|
||||
|
||||
this->deallocate(active->elem.page_base+1);
|
||||
this->deallocate(active->elem.page_base);
|
||||
}
|
||||
this->deallocate(stack);
|
||||
asm ("mov %0, %%cr3" : : "r" (pCR3));
|
||||
delete kernelStackPtr;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ void Terminal::scroll_up(uint32_t count) {
|
||||
// Clear the last line
|
||||
uint16_t* last_line = buffer + (height * pages - 1) * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
last_line[x] = 0x20 | (edata << 8);
|
||||
last_line[x] = 0x0720; //| (edata << 8);
|
||||
}
|
||||
this->cur_y--;
|
||||
}
|
||||
@ -54,7 +54,7 @@ void Terminal::scroll_down(uint32_t count) {
|
||||
// Clear the last line
|
||||
uint16_t* last_line = buffer + (height * (pages - 1)) * width;
|
||||
for (int x = 0; x < width; x++) {
|
||||
last_line[x] = 0x20 | (edata << 8);
|
||||
last_line[x] = 0x0720;// | (edata << 8);
|
||||
}
|
||||
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);
|
||||
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;
|
||||
default:
|
||||
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);
|
||||
|
||||
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++;
|
||||
break;
|
||||
}
|
||||
@ -218,7 +218,7 @@ void Terminal::putchar(uint8_t c) {
|
||||
|
||||
void Terminal::update(){}
|
||||
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)
|
||||
: ReadWriter(0) {
|
||||
@ -346,7 +346,7 @@ void TextModeTerminal::update_cur() {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@ TextModeTerminal::TextModeTerminal(uint16_t* text_mode_pointer): Terminal(80, 25
|
||||
void VGAModeTerminal::update() {
|
||||
for (int y = 0; y < height; y++) {
|
||||
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
|
||||
}
|
||||
|
||||
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 row = ptr / width;
|
||||
|
||||
|
@ -31,7 +31,7 @@ class Terminal: public ReadWriter {
|
||||
private:
|
||||
virtual void update();
|
||||
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_down(uint32_t count=1);
|
||||
@ -81,7 +81,7 @@ class TextModeTerminal : public Terminal {
|
||||
private:
|
||||
void update() 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;
|
||||
public:
|
||||
@ -93,7 +93,7 @@ class VGAModeTerminal : public Terminal {
|
||||
private:
|
||||
void update() 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_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:
|
||||
call main
|
||||
_loop:
|
||||
jmp _loop
|
||||
call die
|
||||
|
||||
extern die
|
||||
extern main
|
@ -1,8 +1,11 @@
|
||||
#include "common/common.h"
|
||||
|
||||
int main() {
|
||||
uint32_t crashBin = fopen("/crash.bin");
|
||||
while (1) {
|
||||
print("Hello, World!\n");
|
||||
sleep(200);
|
||||
printf("Time Elapsed: %dms\n", getMillisecondsElapsed());
|
||||
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)
|
||||
|
||||
SECTIONS {
|
||||
. = 0x20;
|
||||
. = 0x1020;
|
||||
|
||||
.text : {
|
||||
build/programs/entry.o(.text)
|
||||
|
@ -70,6 +70,7 @@ void writeStrToBuf(char* c, procbuffer* b) {
|
||||
}
|
||||
|
||||
void displayBuf(procbuffer* b, int dx, int dy) {
|
||||
print("\x1b[42;36;1m");
|
||||
char pset[9] = "\x1b[00;00H";
|
||||
for (int i=0; i<dy;i++) {
|
||||
pset[3]++;
|
||||
@ -182,7 +183,6 @@ int main() {
|
||||
write(90, 0, bottom);
|
||||
for (int i=0; i<90;i++)
|
||||
write(1, 0, &plus);
|
||||
print("\x1b[42;36;1m");
|
||||
|
||||
uint32_t program = fopen("/hello.bin");
|
||||
uint32_t p1 = exec(program);
|
||||
@ -229,6 +229,7 @@ int main() {
|
||||
if (read(1, 1, c)) {
|
||||
if (c[0] == ':') {
|
||||
char buf[32] = {0};
|
||||
print("\x1b[45;33;1m");
|
||||
print("\x1b[59;2H");
|
||||
print(": ");
|
||||
print("\x1b[59;3H");
|
||||
|
Loading…
x
Reference in New Issue
Block a user