diff --git a/src/bootstage2/main.c b/src/bootstage2/main.c index d2d4231..8cb2792 100644 --- a/src/bootstage2/main.c +++ b/src/bootstage2/main.c @@ -1,5 +1,4 @@ #include "atapio.h" -#include "screenstuff.h" #include "paging.h" typedef struct { @@ -47,23 +46,7 @@ void mark_unavailble(uint32_t address, uint32_t size, uint8_t* buffer) { } } -char* stringify_type(uint32_t type) { - switch (type) { - case 1: - return "Usable"; - case 3: - return "ACPI Reclaimable"; - case 4: - return "ACPI NVS"; - case 5: - return "Bad memory"; - default: - return "Reserved"; - } -} - void main() { - init_term(); init_atapio(); // e820 memory map exists at 0x20000 @@ -73,13 +56,8 @@ void main() { memset(bitmap, 0x20000, 0); // Ensure the bitmap data is clear - for (int i=0; i<0x20000; i++) - if (bitmap[i]) - printf("Found data in bitmap at %x!\n", (bitmap+i)); - for (int i=0; e820_entries[i].length_low != 0 || e820_entries[i].length_high != 0; i++) { e820entry entry = e820_entries[i]; - printf("BIOS-e820: Starting %x%x, length %x%x is %s\n", entry.base_high, entry.base_low, entry.length_high, entry.length_low, stringify_type(entry.type)); if (entry.type != 1) continue; @@ -97,8 +75,6 @@ void main() { } uint32_t page_index = base / 4096; - printf("Page Index: %d\nLength (Pages): %d\n", page_index, length / 4096); - for (int j=0; length > 4096; length -= 4096, j++) { set_bit(page_index + j, bitmap); } @@ -185,8 +161,6 @@ void main() { load_file("KERNEL BIN", kernel_location); - printf("Stage2 success!\n"); - //while (1); asm volatile("mov %0, %%eax;" diff --git a/src/bootstage2/screenstuff.c b/src/bootstage2/screenstuff.c deleted file mode 100644 index 1b898e1..0000000 --- a/src/bootstage2/screenstuff.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "screenstuff.h" - -uint16_t* VMEM_ADDR = (uint16_t*)0xb8000; -const int TERM_WIDTH = 80; -const int TERM_HEIGHT = 25; - -int cursor_x = 0; -int cursor_y = 0; - -uint16_t get_curpos() { - uint16_t cursor_position = 0; - uint8_t* cursor_position_split = (uint8_t*)&cursor_position; - outb(0x3D4, 0x0F); - cursor_position_split[0] = inb(0x3D5); - outb(0x3D4, 0x0E); - cursor_position_split[1] = inb(0x3D5); - return cursor_position; -} - -void init_term() { - uint16_t cursor_position = get_curpos(); - - cursor_y = cursor_position / TERM_WIDTH; - cursor_x = cursor_position % TERM_WIDTH; -} - -void clear_screen() { - for (int i=0; i -#include "types.h" -#include "io.h" - -uint16_t get_curpos(); -void init_term(); -void clear_screen(); -void clear_line(int line); -void set_curpos_raw(int curpos); -void set_curpos(int x, int y); -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, ...); -void non_moving_put(char chr); - -#endif \ No newline at end of file diff --git a/src/bootstage2/strings.c b/src/bootstage2/strings.c index cc48b9f..8e04442 100644 --- a/src/bootstage2/strings.c +++ b/src/bootstage2/strings.c @@ -8,62 +8,4 @@ bool strcmp(char* a, char* b, int max) { index++; } return true; -} - -char* split_on_first(char delimeter, char* string) { - int index = 0; - char current; - - while (current = string[index++]) { - if (current == delimeter) { - string[index-1] = 0; - return string+index; - } - } - - return 0; -} - -int string_split(char delimeter, char* string, char** pointer_array) { - int index = 0; - int last_split_index = 0; - int split_count = 0; - - char current; - - while (current = string[index]) { - if (current == delimeter) { - string[index] = 0; - pointer_array[split_count++] = (string+last_split_index); - last_split_index = (index+1); - } - index++; - } - - // Add remaining part of the string to the pointer_array - pointer_array[split_count] = (string+last_split_index); - - return split_count; -} - -void decode_filename(char* nice_name, char* filenamebuffer) { - // Clear filenamebuffer - for (int i=0; i<11; i++) - filenamebuffer[i] = ' '; - filenamebuffer[11] = 0; - - int fbIndex = 0; - for (int i=0; i<12; i++) { - if (nice_name[i] == 0) - return; - if (nice_name[i] == '.') { - fbIndex = 8; - continue; - } - - if (nice_name[i] >= 0x61 && nice_name[i] <= 0x7f) - filenamebuffer[fbIndex++] = nice_name[i] - 32; - else - filenamebuffer[fbIndex++] = nice_name[i]; - } } \ No newline at end of file diff --git a/src/bootstage2/strings.h b/src/bootstage2/strings.h index baf7c5c..7ea7d6a 100644 --- a/src/bootstage2/strings.h +++ b/src/bootstage2/strings.h @@ -4,8 +4,5 @@ #include bool strcmp(char* a, char* b, int max); -char* split_on_first(char delimeter, char* string); -int string_split(char delimeter, char* string, char** pointer_array); -void decode_filename(char* nice_name, char* filenamebuffer); #endif \ No newline at end of file diff --git a/src/common/common.h b/src/common/common.h index af3e523..4726e13 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -3,6 +3,31 @@ #include "../kernel/types.h" +typedef enum { + File, + Directory, + CharacterDev, + BlockDev, + NoExist +} FSType; + +typedef struct { + uint16_t length; + uint8_t* path; +} PathEntry; + +typedef struct { + PathEntry path; + FSType type; + uint32_t sizeBytes; +} FSDirectoryEntry; + +typedef struct { + uint32_t count; + uint32_t stringsLength; + FSDirectoryEntry entries[]; +} FSDirectoryListing; + #define syscall_hdlr_0(a, b, c) \ a b(); #define syscall_hdlr_1(a, b, c, d, e) \ diff --git a/src/common/syscalls.h b/src/common/syscalls.h index f4bc08e..07e0103 100644 --- a/src/common/syscalls.h +++ b/src/common/syscalls.h @@ -1,9 +1,15 @@ -syscall_hdlr_1(void*, localalloc, "4", uint32_t, size); -syscall_hdlr_1(void, localdelete, "5", void*, ptr); +#include + +syscall_hdlr_1(uint32_t, getDentsSize, "0", char*, path); +syscall_hdlr_2(void, getDents, "1", char*, path, uint8_t*, buffer); +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, getPID, "8"); -syscall_hdlr_3(int, read, "10", uint32_t, count, void*, filehandler, uint8_t*, buffer); -syscall_hdlr_3(int, write, "11", uint32_t, count, void*, filehandler, uint8_t*, buffer); -syscall_hdlr_1(uint32_t, fork, "7", uint32_t, filehandler); +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_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); diff --git a/src/kernel/allocate.h b/src/kernel/allocate.h index 3e7d36e..822ae82 100644 --- a/src/kernel/allocate.h +++ b/src/kernel/allocate.h @@ -3,7 +3,6 @@ #include "paging.h" #include "datatypes/tuple.h" -//void init_allocator(); extern uint8_t* bitmap; extern PDE* kernel_page_directory; diff --git a/src/kernel/ata.h b/src/kernel/ata.h index 65d710e..b7c3350 100644 --- a/src/kernel/ata.h +++ b/src/kernel/ata.h @@ -1,14 +1,10 @@ #ifndef ATA_PIO #define ATA_PIO -#include - #include "io.h" #include "types.h" #include "strings.h" -#include "allocate.h" #include "global.h" -#include "ioport.h" #include "stdio/readwriter.h" diff --git a/src/kernel/datatypes/hashtable.h b/src/kernel/datatypes/hashtable.h index 12add28..c546866 100644 --- a/src/kernel/datatypes/hashtable.h +++ b/src/kernel/datatypes/hashtable.h @@ -5,7 +5,6 @@ #include "linkedlist.h" #include "../memory.h" #include "maybe.h" -#include "../screenstuff.h" namespace xnoe { template diff --git a/src/kernel/datatypes/linkedlist.h b/src/kernel/datatypes/linkedlist.h index 45dcb44..9b3fbeb 100644 --- a/src/kernel/datatypes/linkedlist.h +++ b/src/kernel/datatypes/linkedlist.h @@ -1,6 +1,7 @@ #ifndef LINKEDLIST_H #define LINKEDLIST_H +#include "../types.h" #include "../memory.h" namespace xnoe { diff --git a/src/kernel/filesystem/fat16.cpp b/src/kernel/filesystem/fat16.cpp index 8cdf839..00759dd 100644 --- a/src/kernel/filesystem/fat16.cpp +++ b/src/kernel/filesystem/fat16.cpp @@ -3,9 +3,9 @@ uint32_t FAT16FileReadWriter::offsetBytesToCluster(uint32_t offset) { uint32_t cluster = this->firstCluster; uint32_t remaining = offset; - while (remaining > 512) { + while (remaining > this->clusterSize) { cluster = this->backingFS->FAT1[this->firstCluster]; - remaining -= 512; + remaining -= this->clusterSize; } return cluster; @@ -17,28 +17,29 @@ FAT16FileReadWriter::FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster, this->sizeBytes = sizeBytes; this->currentPosition = 0; this->backingFS = backingFS; + this->clusterSize = 512 * (uint32_t)(*this->backingFS->sectorsPerCluster); } uint32_t FAT16FileReadWriter::read(uint32_t count, uint8_t* buffer) { - uint8_t* clusterBuffer = new uint8_t[512]; + uint8_t* clusterBuffer = new uint8_t[this->clusterSize]; uint32_t clusterToRead = offsetBytesToCluster(this->currentPosition); uint32_t sectorToRead = this->backingFS->clusterToSector(clusterToRead); - this->backingFS->backingDevice->seek(sectorToRead * 512); - this->backingFS->backingDevice->read(512, clusterBuffer); + this->backingFS->backingDevice->seek(sectorToRead * this->clusterSize); + this->backingFS->backingDevice->read(this->clusterSize, clusterBuffer); - uint32_t currentClusterIndex = this->currentPosition % 512; + uint32_t currentClusterIndex = this->currentPosition % this->clusterSize; uint32_t remaining = count; uint32_t index = 0; while (remaining) { - if (currentClusterIndex == 512) { + if (currentClusterIndex == this->clusterSize) { clusterToRead = this->backingFS->FAT1[clusterToRead]; if (clusterToRead == 0xffff) break; sectorToRead = this->backingFS->clusterToSector(clusterToRead); - this->backingFS->backingDevice->seek(sectorToRead * 512); - this->backingFS->backingDevice->read(512, clusterBuffer); + this->backingFS->backingDevice->seek(sectorToRead * this->clusterSize); + this->backingFS->backingDevice->read(this->clusterSize, clusterBuffer); currentClusterIndex = 0; } @@ -91,7 +92,7 @@ bool FAT16FS::pathEntryTo83(PathEntry pe, char* buffer) { } uint32_t FAT16FS::clusterToSector(uint32_t cluster) { - return cluster + (*sectorsPerFAT * *countFATs) + (*countRDEs / 16) + (*countReserved - 1) - 1; + return (cluster * (uint32_t)(*this->sectorsPerCluster)) + (*sectorsPerFAT * *countFATs) + (*countRDEs / 16) + (*countReserved - 1) - 1; } void FAT16FS::load_file(uint32_t location, uint8_t* destination) { @@ -100,9 +101,9 @@ void FAT16FS::load_file(uint32_t location, uint8_t* destination) { bool loaded = false; while (!loaded) { uint16_t fromSector = clusterToSector(location); - this->backingDevice->seek(fromSector * 512); - this->backingDevice->read(512, destination+offset); - offset += 512; + this->backingDevice->seek(fromSector * 512 * *this->sectorsPerCluster); + this->backingDevice->read(512 * *this->sectorsPerCluster, destination+offset); + offset += 512 * *this->sectorsPerCluster; location = FAT1[location++]; if (location == 0xffff) @@ -116,7 +117,7 @@ uint32_t FAT16FS::calc_size(uint32_t location) { bool loaded = false; while (!loaded) { uint16_t fromSector = clusterToSector(location); - offset += 512; + offset += 512 * *this->sectorsPerCluster; location = FAT1[location++]; if (location == 0xffff) @@ -349,7 +350,7 @@ uint32_t FAT16FS::getDentsSize(Path p) { uint32_t found = 0; uint32_t count = xnoe::get<1>(directory); - found += 4; + found += sizeof(FSDirectoryListing); for (int i=0; icount = getRealCount(directoryEntries, count); + buffer->stringsLength = 0; char* nameBuffer = ((char*)buffer); - nameBuffer += sizeof(FSDirectoryEntry)*buffer->count + 4; + nameBuffer += sizeof(FSDirectoryEntry)*buffer->count + sizeof(FSDirectoryListing); for (int i=0; istringsLength += 13; } } diff --git a/src/kernel/filesystem/fat16.h b/src/kernel/filesystem/fat16.h index 957202d..0c26787 100644 --- a/src/kernel/filesystem/fat16.h +++ b/src/kernel/filesystem/fat16.h @@ -2,7 +2,6 @@ #define FAT16_H #include "fstree.h" -#include "strings.h" #include "../memory.h" #include "../stdio/readwriter.h" #include "../datatypes/tuple.h" @@ -10,7 +9,6 @@ struct __attribute__((packed)) DirectoryEntry { char name[11]; - uint8_t readonly : 1; uint8_t hidden : 1; uint8_t system : 1; @@ -72,6 +70,8 @@ private: uint32_t offsetBytesToCluster(uint32_t offset); + uint32_t clusterSize; + FAT16FS* backingFS; public: FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster, uint32_t sizeBytes, FAT16FS* backingFS); @@ -88,6 +88,7 @@ public: uint16_t* FAT1; uint8_t sectorOne[512]; + uint8_t* sectorsPerCluster = ((uint8_t*)(sectorOne + 0x0d)); uint16_t* countReserved = ((uint16_t*)(sectorOne + 0x0e)); uint8_t* countFATs = ((uint8_t*)(sectorOne + 0x10)); uint16_t* countRDEs = ((uint16_t*)(sectorOne + 0x11)); diff --git a/src/kernel/filesystem/fstree.cpp b/src/kernel/filesystem/fstree.cpp index 7473b0c..654a96d 100644 --- a/src/kernel/filesystem/fstree.cpp +++ b/src/kernel/filesystem/fstree.cpp @@ -4,11 +4,17 @@ bool operator==(const PathEntry& lhs, const PathEntry& rhs) { if (lhs.length == rhs.length) if (lhs.length == 0) return true; + else if (lhs.length < rhs.length) + return strcmp(lhs.path, rhs.path, lhs.length); else return strcmp(lhs.path, rhs.path, lhs.length); return false; } +bool operator!=(const PathEntry& lhs, const PathEntry& rhs) { + return !(lhs == rhs); +} + // FS Tree Skeleton bool FSTree::exists(Path p){} FSType FSTree::type(Path p){} @@ -116,6 +122,21 @@ Path* RootFSTree::getRemainingPath(Path p) { return 0; } +FSTreeNode* RootFSTree::getExhaustive(Path p) { + PathElement* currentPath = p.start; + FSTreeNode* currentNode = this->node; + if (currentPath->elem != currentNode->self) + return 0; + while (currentPath && currentNode) { + currentNode = getNodeFromPathEntry(currentPath->elem, currentNode); + currentPath = currentPath->next; + } + if (currentPath) + return 0; + else + return currentNode; +} + template T RootFSTree::attempt(T(FSTree::*fn)(Path), Path p, T fallback) { FSTree* mp = getLongestMatchingUnder(p); @@ -156,10 +177,53 @@ ReadWriter* RootFSTree::open(Path p){ return attempt(&FSTree::open, p, 0); } uint32_t RootFSTree::getDentsSize(Path p){ - return attempt(&FSTree::getDentsSize, p, 0); + uint32_t size = attempt(&FSTree::getDentsSize, p, 0); + FSTreeNode* n = getExhaustive(p); + if (n) { + xnoe::linkedlistelem* current = n->children.start; + while (current) { + size += sizeof(FSDirectoryEntry); + size += current->elem->self.length; + current = current->next; + } + } + return size; } void RootFSTree::getDents(Path p, FSDirectoryListing* buffer){ attempt(&FSTree::getDents, p, buffer); + uint32_t oldCount = buffer->count; + uint32_t stringsOffset = buffer->count * sizeof(FSDirectoryEntry) + sizeof(FSDirectoryListing); + uint32_t addCount = 0; + char* strings = ((uint32_t)buffer) + stringsOffset; + FSTreeNode* n = getExhaustive(p); + if (n) { + xnoe::linkedlistelem* current = n->children.start; + while (current) { + addCount++; + current = current->next; + } + if (addCount) { + current = n->children.start; + for (int i=buffer->stringsLength; i>=0; i--) + strings[i+addCount*sizeof(FSDirectoryEntry)] = strings[i]; + for (int i=0; i < buffer->count; i++) + buffer->entries[i].path.path += addCount*sizeof(FSDirectoryEntry); + while (current) { + strings += addCount*sizeof(FSDirectoryEntry) + buffer->stringsLength; + memcpy(current->elem->self.path, strings, current->elem->self.length); + buffer->entries[buffer->count++] = FSDirectoryEntry { + PathEntry{ + current->elem->self.length, + strings + }, + Directory, + 0 + }; + strings += current->elem->self.length; + current = current->next; + } + } + } } bool RootFSTree::isMountpoint(Path p) { diff --git a/src/kernel/filesystem/fstree.h b/src/kernel/filesystem/fstree.h index ed5b614..e22f08e 100644 --- a/src/kernel/filesystem/fstree.h +++ b/src/kernel/filesystem/fstree.h @@ -2,8 +2,8 @@ #define FSTREE_H #include "../datatypes/linkedlist.h" -#include "strings.h" #include "../stdio/readwriter.h" +#include "../strings.h" struct PathEntry { uint16_t length; @@ -31,6 +31,7 @@ struct FSDirectoryEntry { struct FSDirectoryListing { uint32_t count; + uint32_t stringsLength; FSDirectoryEntry entries[]; }; @@ -56,6 +57,7 @@ class RootFSTree: public FSTree { private: FSTree* getLongestMatchingUnder(Path p); Path* getRemainingPath(Path p); + FSTreeNode* getExhaustive(Path p); FSTreeNode* makeNodeIfNotExist(Path p); diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 4f0cc94..0bd7a1e 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -171,29 +171,29 @@ void awaken(frame_struct* frame, Process* p) { void syscall(frame_struct* frame) { // Syscall ABI: - // 0: X - // 1: X - // 2: X - // 3: X - // 4: localalloc: LocalAlloc: Allocate under current process (in esi: size; out eax void* ptr) - // 5: localdelete: LocalDelete: Deallocate under current process (in esi: pointer) + // 0: getDentsSize :: char* path -> uint32_t size + // 1: getDents :: char* path -> uint8_t* buffer -> void + // 2: exists :: char* path -> bool + // 3: type :: char* path -> FSType + // 4: localalloc :: uint32_t size -> void* ptr + // 5: localdelete :: void* ptr -> void // 6: X - // 7: fork :: void* filehandler esi -> 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) - // 9: getFileHandler :: char* path esi -> void* eax // Returns a file handlers for a specific file - // 10: read :: uint32_t count ebx -> void* filehandler esi -> uint8_t* outputbuffer edi -> int read // Reads from a file handler in to a buffer, returns successful read - // 11: write :: uint32_t count ebx -> void* filehandler esi -> uint8_t* inputbuffer edi -> int written // Reads from a buffer in to a file, returns successful written + // 9: getFileHandler :: char* path -> void* // Returns a file handlers for a specific file + // 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. - // 13: bindStdout :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdout of another process. - // 14: bindStdin :: int PID esi -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdin of another process. + // 13: bindStdout :: int PID -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdout of another process. + // 14: bindStdin :: int PID -> int filehandler // Returns a filehandler for a CircularRWBuffer binding stdin of another process. - // 15: fopen :: char* path esi -> int filehandler // Returns a filehandler to the file. - // 16: fclose :: int filehandler esi -> void // Closes a file handler. + // 15: fopen :: char* path -> int filehandler // Returns a filehandler to the file. + // 16: fclose :: int filehandler -> void // Closes a file handler. - // 17: kill :: int PID esi -> void // Destroys a process. + // 17: kill :: int PID -> void // Destroys a process. - // 18: sleep :: int time ms esi -> void // Sleeps the current process for esi milliseconds. + // 18: sleep :: int time ms -> void // Sleeps the current process for time milliseconds. // File handlers: // 0: Stdout @@ -207,12 +207,16 @@ void syscall(frame_struct* frame) { switch (frame->eax) { case 0: + rval = Global::kernel->rootfs->getDentsSize(createPathFromString(frame->ebx)); break; case 1: + Global::kernel->rootfs->getDents(createPathFromString(frame->ebx), frame->ecx); break; case 2: + rval = Global::kernel->rootfs->exists(createPathFromString(frame->ebx)); break; case 3: + rval = Global::kernel->rootfs->type(createPathFromString(frame->ebx)); break; case 4: rval = currentProc->allocate(frame->ebx); diff --git a/src/kernel/idt.h b/src/kernel/idt.h index 2f7a852..ccb0918 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -2,7 +2,6 @@ #define IDT_H #include "types.h" -#include "screenstuff.h" #include "global.h" #include "kernel.h" #include "gdt.h" diff --git a/src/kernel/io.cpp b/src/kernel/io.cpp index 6d600ea..e85f11c 100644 --- a/src/kernel/io.cpp +++ b/src/kernel/io.cpp @@ -18,4 +18,22 @@ extern "C" { asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber)); return result; } +} + +Port::Port(uint16_t a) { + this->addr = a; +} + +uint8_t Port::readb() { + return inb(this->addr); +} +uint16_t Port::readw() { + return inw(this->addr); +} + +void Port::writeb(uint8_t d) { + outb(this->addr, d); +} +void Port::writew(uint16_t d) { + outw(this->addr, d); } \ No newline at end of file diff --git a/src/kernel/io.h b/src/kernel/io.h index a6a2919..4649d2c 100644 --- a/src/kernel/io.h +++ b/src/kernel/io.h @@ -11,4 +11,17 @@ extern "C" { uint16_t inw(uint16_t portnumber); } +class Port { +private: + uint16_t addr; +public: + Port(uint16_t a); + + uint8_t readb(); + uint16_t readw(); + + void writeb(uint8_t d); + void writew(uint16_t d); +}; + #endif \ No newline at end of file diff --git a/src/kernel/ioport.cpp b/src/kernel/ioport.cpp deleted file mode 100644 index 20553c1..0000000 --- a/src/kernel/ioport.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "ioport.h" - -Port::Port(uint16_t a) { - this->addr = a; -} - -uint8_t Port::readb() { - return inb(this->addr); -} -uint16_t Port::readw() { - return inw(this->addr); -} - -void Port::writeb(uint8_t d) { - outb(this->addr, d); -} -void Port::writew(uint16_t d) { - outw(this->addr, d); -} \ No newline at end of file diff --git a/src/kernel/ioport.h b/src/kernel/ioport.h deleted file mode 100644 index fcee08d..0000000 --- a/src/kernel/ioport.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef IOPORT_H -#define IOPORT_H - -#include "io.h" - -class Port { -private: - uint16_t addr; -public: - Port(uint16_t a); - - uint8_t readb(); - uint16_t readw(); - - void writeb(uint8_t d); - void writew(uint16_t d); -}; - -#endif \ No newline at end of file diff --git a/src/kernel/keyboard.h b/src/kernel/keyboard.h index 4318016..a6ce60d 100644 --- a/src/kernel/keyboard.h +++ b/src/kernel/keyboard.h @@ -3,7 +3,6 @@ #include #include "io.h" -#include "screenstuff.h" #include "idt.h" void init_keyboard(); diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 78544ba..798bdea 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -1,5 +1,4 @@ #include "types.h" -#include "screenstuff.h" #include "io.h" #include "idt.h" #include "keyboard.h" @@ -20,7 +19,6 @@ int main() { init_gdt(); - init_term(); PageDirectory kernel_pd = PageDirectory(0xc0100000, 0x120000, 0xbffe0000); diff --git a/src/kernel/memory.h b/src/kernel/memory.h index c008c4a..2947d20 100644 --- a/src/kernel/memory.h +++ b/src/kernel/memory.h @@ -3,7 +3,6 @@ #include "paging.h" #include "allocate.h" -#include "screenstuff.h" #include "global.h" void memset(uint8_t* address, uint32_t count, uint8_t value); diff --git a/src/kernel/paging.h b/src/kernel/paging.h index b3bed31..1890a01 100644 --- a/src/kernel/paging.h +++ b/src/kernel/paging.h @@ -1,7 +1,6 @@ #ifndef PAGING_H #define PAGING_H -#include #include "types.h" struct __attribute__((packed)) split_addr { diff --git a/src/kernel/process.h b/src/kernel/process.h index f780c19..118f153 100644 --- a/src/kernel/process.h +++ b/src/kernel/process.h @@ -6,7 +6,6 @@ #include "datatypes/linkedlist.h" #include "datatypes/hashtable.h" #include "datatypes/maybe.h" -#include "screenstuff.h" #include "global.h" #include "ata.h" diff --git a/src/kernel/screenstuff.cpp b/src/kernel/screenstuff.cpp deleted file mode 100644 index 0a75ed6..0000000 --- a/src/kernel/screenstuff.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "screenstuff.h" - -uint16_t* VMEM_ADDR = (uint16_t*)0xc0501000; -const int TERM_WIDTH = 80; -const int TERM_HEIGHT = 25; - -int cursor_x = 0; -int cursor_y = 0; - -uint16_t get_curpos() { - uint16_t cursor_position = 0; - uint8_t* cursor_position_split = (uint8_t*)&cursor_position; - outb(0x3D4, 0x0F); - cursor_position_split[0] = inb(0x3D5); - outb(0x3D4, 0x0E); - cursor_position_split[1] = inb(0x3D5); - return cursor_position; -} - -void init_term() { - uint16_t cursor_position = get_curpos(); - - cursor_y = cursor_position / TERM_WIDTH; - cursor_x = cursor_position % TERM_WIDTH; -} - -void clear_screen() { - for (int i=0; i -#include "types.h" -#include "io.h" -#include "strings.h" - -uint16_t get_curpos(); -void init_term(); -void clear_screen(); -void clear_line(int line); -void set_curpos_raw(int curpos); -void set_curpos(int x, int y); -void printf(const char* string, ...); -void non_moving_put(char chr); - -#endif \ No newline at end of file diff --git a/src/kernel/strings.h b/src/kernel/strings.h index 8b9b051..300138c 100644 --- a/src/kernel/strings.h +++ b/src/kernel/strings.h @@ -1,8 +1,6 @@ #ifndef STRINGS_H #define STRINGS_H -#include - bool strcmp(char* a, char* b, int max); char* split_on_first(char delimeter, char* string); int string_split(char delimeter, char* string, char** pointer_array); diff --git a/src/kernel/terminal.cpp b/src/kernel/terminal.cpp index a76ce47..f010760 100644 --- a/src/kernel/terminal.cpp +++ b/src/kernel/terminal.cpp @@ -1,35 +1,224 @@ #include "terminal.h" -void Terminal::scroll_up() { - // Scroll the entire buffer up. - for (int y = 0; y < (height * pages); y++) { - uint16_t* cline = buffer + y * width; - uint16_t* nline = buffer + (y+1) * width; - for (int x = 0; x < width; x++) { - cline[x] = nline[x]; +int strToInt(char* str, uint32_t max) { + int r=0; + int i=0; + while (*str >= 0x30 && *str <= 0x39 && i < max) { + r *= 10; + r += *(str++) - 0x30; + i++; + } + return r; +} + +int clamp(int a, int b, int c) { + if (a < b) + return b; + if (a > c) + return c; + return a; +} + +void Terminal::scroll_up(uint32_t count) { + for (int i=0; icur_y--; } - // Clear the last line - uint16_t* last_line = buffer + (height * pages - 1) * width; - for (int x = 0; x < width; x++) { - last_line[x] = 0x0720; - } - this->cur_y--; this->update(); } -void Terminal::putchar(uint32_t ptr, uint8_t c, uint8_t edata) { - // All modifications to the screen are done to the last page. - last_page_pointer[ptr] = c | (edata<<8); - if (active) - putchar_internal(ptr, c, edata); +void Terminal::scroll_down(uint32_t count) { + for (int i=0; i= 0; y--) { + uint16_t* nline = buffer + y * width; + uint16_t* cline = buffer + (y+1) * width; + for (int x = 0; x < width; x++) { + cline[x] = nline[x]; + } + } + // 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); + } + this->cur_y--; + } + + this->update(); +} + +void Terminal::putchar(uint8_t c) { + again: + switch (this->state) { + case None: + switch (c) { + case 0x1b: + this->state = EscapeCode; + break; + case '\n': + this->cur_x = 0; + this->cur_y++; + break; + case '\b': + if (this->cur_x == 0) { + if (this->cur_y > 0) { + this->cur_x = this->width-1; + this->cur_y--; + } + } else { + this->cur_x--; + } + 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, ' '); + break; + default: + if (this->cur_x == this->width) { + this->cur_x = 0; + this->cur_y++; + } + // All modifications to the screen are done to the last page. + 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); + this->cur_x++; + break; + } + break; + case EscapeCode: + switch (c) { + case '[': + this->state = CSI; + break; + default: + break; + } + break; + case CSI: + this->state = ParameterBytes; + this->parameterIndex = 0; + this->intermediaryIndex = 0; + goto again; + break; + case ParameterBytes: + if (parameterIndex < 128 && c >= 0x30 && c <= 0x3F) { + parameterBytes[parameterIndex++] = c; + } else { + parameterIndex; + this->state = IntermediaryBytes; + goto again; + } + break; + case IntermediaryBytes: + if (intermediaryIndex < 128 && c >= 0x20 && c <= 0x2F) { + intermediaryBytes[intermediaryIndex++] = c; + } else { + intermediaryIndex; + this->state = FinalByte; + goto again; + } + break; + case FinalByte: + switch (c) { + case 'A': + this->cur_y -= clamp(strToInt(parameterBytes, parameterIndex), 0, this->cur_y); + break; + case 'B': + this->cur_y += clamp(strToInt(parameterBytes, parameterIndex), 0, this->height - this->cur_y); + break; + case 'C': + this->cur_x += clamp(strToInt(parameterBytes, parameterIndex), 0, this->width - this->cur_x); + break; + case 'D': + this->cur_x -= clamp(strToInt(parameterBytes, parameterIndex), 0, this->cur_x); + break; + case 'E': + this->cur_y += clamp(strToInt(parameterBytes, parameterIndex), 0, this->height - this->cur_y); + this->cur_x = 0; + break; + case 'F': + this->cur_y -= clamp(strToInt(parameterBytes, parameterIndex), 0, this->cur_y); + this->cur_x = 0; + break; + case 'G': + this->cur_x = clamp(strToInt(parameterBytes, parameterIndex), 0, this->width); + break; + case 'f': + case 'H': { + uint32_t semicolonIndex = 0; + while (parameterBytes[semicolonIndex++] != ';' && semicolonIndex <= parameterIndex); + this->cur_y = clamp(strToInt(parameterBytes, parameterIndex) - 1, 0, this->height) ; + this->cur_x = clamp(strToInt(parameterBytes+semicolonIndex, parameterIndex-semicolonIndex) - 1, 0, this->width); + break; + } + case 'm': + this->state = SGR; + goto again; + break; + default: + break; + } + this->state = None; + break; + case SGR: { + uint32_t index = 0; + while (index <= parameterIndex) { + uint32_t n = strToInt(parameterBytes+index, parameterIndex-index); + switch (n) { + case 0: + this->edata = 0xf; + break; + case 1: + if ((this->edata&0xf) <= 0x7) + this->edata += 8; + break; + case 2: + if ((this->edata&0xf) >= 0x7) + this->edata -= 8; + break; + case 30 ... 37: + this->edata &= 0xf0; + this->edata |= n-30; + break; + case 40 ... 47: + this->edata &= 0x0f; + this->edata |= (n-40)<<4; + break; + default: + break; + } + while (parameterBytes[index++] != ';' && index <= parameterIndex); + } + this->state = None; + } + default: + break; + } + if (this->cur_y == this->height) { + this->cur_y--; + scroll_up(); + } } void Terminal::update(){} void Terminal::update_cur(){} -void Terminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {} +void Terminal::putchar_internal(uint32_t ptr, uint8_t c) {} Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages) : ReadWriter(0) { @@ -46,23 +235,6 @@ Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages) this->active = false; } -int strToInt(char* str) { - int r=0; - while (*str >= 0x30 && *str <= 0x39) { - r *= 10; - r += *(str++) - 0x30; - } - return r; -} - -int clamp(int a, int b, int c) { - if (a < b) - return b; - if (a > c) - return c; - return a; -} - void Terminal::printf(const char* string, ...) { va_list ptr; va_start(ptr, string); @@ -71,73 +243,6 @@ void Terminal::printf(const char* string, ...) { char current; while (current=string[index++]) { - if (current == '\n') { - this->cur_x = 0; - this->cur_y++; - } - - if (current == 0x1b && string[index] == '[') { - index++; - char* parameterStart = (string+index); - while (string[index] >= 0x30 && string[index] <= 0x3F) - index++; - char* parameterEnd = (string+index); - - char* intermediateStart = (string+index); - while (string[index] >= 0x20 && string[index] <= 0x2F) - index++; - - char final = *(string+(index++)); - - switch (final) { - case 'A': - this->cur_y -= clamp(strToInt(parameterStart), 0, this->cur_y); - break; - case 'B': - this->cur_y += clamp(strToInt(parameterStart), 0, this->height - this->cur_y); - break; - case 'C': - this->cur_x += clamp(strToInt(parameterStart), 0, this->width - this->cur_x); - break; - case 'D': - this->cur_x -= clamp(strToInt(parameterStart), 0, this->cur_x); - break; - case 'H': { - char* s=parameterStart; - while (*s != ';' && s < parameterEnd) - s++; - s++; - this->cur_y = clamp(strToInt(parameterStart), 1, this->height) - 1; - this->cur_x = clamp(strToInt(s), 1, this->width) - 1; - break; - } - } - - continue; - } - - if (current == '\b') { - if (this->cur_x > 0) { - this->cur_x--; - } else if (this->cur_y > 0) { - 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++; - } - - if (this->cur_y == this->height) - this->scroll_up(); - if (current == '%') { int type = string[index++]; int offset; @@ -159,22 +264,17 @@ void Terminal::printf(const char* string, ...) { break; } case 'c': { - int mem_pos = this->cur_y * this->width + this->cur_x++; int promoted = va_arg(ptr, int); char charred = promoted; - this->putchar(mem_pos, charred); + this->putchar(charred); break; } } continue; } - - if (current != '\n') { - int mem_pos = this->cur_y * this->width + this->cur_x++; - this->putchar(mem_pos, current); - } + this->putchar(current); } this->set_curpos(this->cur_x, this->cur_y); @@ -183,84 +283,8 @@ void Terminal::printf(const char* string, ...) { } uint32_t Terminal::write(uint32_t count, uint8_t* string) { - int index = 0; - char current; - - while (index < count) { - current=string[index++]; - if (current == '\n') { - this->cur_x = 0; - this->cur_y++; - } - - if (current == 0x1b && string[index] == '[') { - index++; - char* parameterStart = (string+index); - while (string[index] >= 0x30 && string[index] <= 0x3F) - index++; - char* parameterEnd = (string+index); - - char* intermediateStart = (string+index); - while (string[index] >= 0x20 && string[index] <= 0x2F) - index++; - - char final = *(string+(index++)); - - switch (final) { - case 'A': - this->cur_y -= clamp(strToInt(parameterStart), 0, this->cur_y); - break; - case 'B': - this->cur_y += clamp(strToInt(parameterStart), 0, this->height - this->cur_y); - break; - case 'C': - this->cur_x += clamp(strToInt(parameterStart), 0, this->width - this->cur_x); - break; - case 'D': - this->cur_x -= clamp(strToInt(parameterStart), 0, this->cur_x); - break; - case 'H': { - char* s=parameterStart; - while (*s != ';' && s < parameterEnd) - s++; - s++; - this->cur_y = clamp(strToInt(parameterStart), 1, this->height) - 1; - this->cur_x = clamp(strToInt(s), 1, this->width) - 1; - break; - } - } - - continue; - } - - if (current == '\b') { - if (this->cur_x > 0) { - this->cur_x--; - } else if (this->cur_y > 0) { - 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++; - } - - if (this->cur_y == this->height) - this->scroll_up(); - - if (current != '\n') { - int mem_pos = this->cur_y * this->width + this->cur_x++; - - this->putchar(mem_pos, current); - } - } + for (int index=0; index < count; index++) + this->putchar(string[index]); this->set_curpos(this->cur_x, this->cur_y); } @@ -322,7 +346,7 @@ void TextModeTerminal::update_cur() { outb(0x3D5, cursor_position_split[1]); } -void TextModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) { +void TextModeTerminal::putchar_internal(uint32_t ptr, uint8_t c) { text_mode_pointer[ptr] = c | (edata << 8); } @@ -333,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]), 0); + putchar_internal(y * width + x, (uint8_t)(current_page_pointer[y * width + x])); } } } @@ -342,7 +366,7 @@ void VGAModeTerminal::update_cur() { // Todo: Implement cursor for VGAModeTerminal } -void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) { +void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c) { uint32_t col = ptr % width; uint32_t row = ptr / width; @@ -353,11 +377,8 @@ void VGAModeTerminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) { return; uint8_t* char_data = font[c]; - for (int y=0; y<8; y++) { - //for (int x=0; x<8; x++) { - put_pixels_byte(sx, sy+y, 15, char_data[y]); - //} - } + for (int y=0; y<8; y++) + put_pixels_byte(sx, sy+y, edata, char_data[y]); } void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uint8_t pixel_byte) { @@ -371,10 +392,11 @@ void VGAModeTerminal::put_pixels_byte(uint32_t x, uint32_t y, uint8_t color, uin } for (int i=0; i<4; i++) { + this->planes[i][pixelindex] = 0; if (color & (1<planes[i][pixelindex] = trbyte; - else - this->planes[i][pixelindex] = 0; + this->planes[i][pixelindex] |= trbyte; + if ((color>>4) & (1<planes[i][pixelindex] |= ~trbyte; } } diff --git a/src/kernel/terminal.h b/src/kernel/terminal.h index b90f699..2a17fdd 100644 --- a/src/kernel/terminal.h +++ b/src/kernel/terminal.h @@ -17,15 +17,32 @@ namespace Timer { void register_event(uint32_t milliseconds, void(*function)(frame_struct*, void*), void* auxiliary, bool oneshot=false); } +enum TerminalState { + None, + EscapeCode, + CSI, + ParameterBytes, + IntermediaryBytes, + FinalByte, + SGR +}; + class Terminal: public ReadWriter { private: virtual void update(); virtual void update_cur(); - virtual void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07); + virtual void putchar_internal(uint32_t ptr, uint8_t c); - void scroll_up(); + void scroll_up(uint32_t count=1); + void scroll_down(uint32_t count=1); - void putchar(uint32_t ptr, uint8_t c, uint8_t edata=0x07); + void putchar(uint8_t c); + + TerminalState state = None; + uint8_t parameterBytes[128]; + uint8_t intermediaryBytes[128]; + uint32_t parameterIndex = 0; + uint32_t intermediaryIndex = 0; protected: uint16_t* buffer; @@ -40,6 +57,8 @@ protected: uint16_t* last_page_pointer; bool active; + + uint8_t edata=0x07; public: Terminal(uint32_t width, uint32_t height, uint32_t pages); @@ -62,7 +81,7 @@ class TextModeTerminal : public Terminal { private: void update() override; void update_cur() override; - void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07) override; + void putchar_internal(uint32_t ptr, uint8_t c) override; uint16_t* text_mode_pointer; public: @@ -74,7 +93,7 @@ class VGAModeTerminal : public Terminal { private: void update() override; void update_cur() override; - void putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata=0x07) override; + void putchar_internal(uint32_t ptr, uint8_t c) 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); diff --git a/src/programs/world/world.c b/src/programs/world/world.c index e5a92ed..914ce74 100644 --- a/src/programs/world/world.c +++ b/src/programs/world/world.c @@ -169,6 +169,7 @@ int main() { for (int i=0; i < 1000; i++) write(1, 0, &space); print("\x1b[1;1H"); + print("\x1b[45;33;1m"); char* mid = "+ ++ +"; char* bottom = "+ +"; @@ -181,20 +182,21 @@ 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 = fork(program); + uint32_t p1 = exec(program); uint32_t p1out = bindStdout(p1); uint32_t p1in = bindStdin(p1); fclose(program); program = fopen("/timer.bin"); - uint32_t p2 = fork(program); + uint32_t p2 = exec(program); uint32_t p2out = bindStdout(p2); uint32_t p2in = bindStdin(p2); fclose(program); procbuffer b1 = { - .buffer = localalloc(56 * 43), + .buffer = malloc(56 * 43), .x = 0, .y = 0, .process = p1, @@ -203,7 +205,7 @@ int main() { }; procbuffer b2 = { - .buffer = localalloc(56 * 43), + .buffer = malloc(56 * 43), .x = 0, .y = 0, .process = p2, @@ -247,6 +249,11 @@ int main() { writeStrToBuf(" Kills the current process\n", selectedBuf); writeStrToBuf(":load \n", selectedBuf); writeStrToBuf(" Loads and executes the program \n", selectedBuf); + writeStrToBuf(":ls \n", selectedBuf); + writeStrToBuf(" Lists the files in directory \n", selectedBuf); + writeStrToBuf(":clear\n", selectedBuf); + writeStrToBuf(" Clears the buffer\n", selectedBuf); + writeStrToBuf("--------\n", selectedBuf); } else if (strcmpcnt(4, buf, "kill")) { if (selectedBuf->process) { @@ -255,21 +262,28 @@ int main() { selectedBuf->process = 0; selectedBuf->stdin = 0; selectedBuf->stdout = 0; - if (selectedBuf == &b1) { - selectedBuf = &b2; - } else { - selectedBuf = &b1; - } } } else if (strcmpcnt(4, buf, "load")) { if (!selectedBuf->process) { char* potFn = buf+5; uint32_t fh = fopen(potFn); - selectedBuf->process = fork(fh); + selectedBuf->process = exec(fh); selectedBuf->stdout = bindStdout(selectedBuf->process); selectedBuf->stdin = bindStdin(selectedBuf->process); fclose(fh); } + } else if (strcmpcnt(2, buf, "ls")) { + uint32_t size = getDentsSize((char*)(buf+3)); + FSDirectoryListing* listing = (FSDirectoryListing*)malloc(size); + getDents((char*)(buf+3), listing); + writeStrToBuf("\n", selectedBuf); + for (int i=0; icount; i++) { + writeCountToBuf(listing->entries[i].path.length, listing->entries[i].path.path, selectedBuf); + writeStrToBuf("\n", selectedBuf); + } + free(listing); + } else if (strcmpcnt(5, buf, "clear")) { + clearBuf(selectedBuf); } } else { if (selectedBuf->process)