diff --git a/include/c/stdio.h b/include/c/stdio.h index 938e6ce..4c8c1ae 100644 --- a/include/c/stdio.h +++ b/include/c/stdio.h @@ -4,22 +4,115 @@ #include #include #include +#include -// TODO: Make a proper file descriptor table -#define stdin 0 -#define stdout 1 -#define stderr 2 +// Nobody should have to interface with the internals of this structure +typedef struct _iobuf { + char* _ptr; + int _file; + int _oflag; +} FILE; -/* --- Output --- */ +FILE* stdin; +FILE* stdout; +FILE* stderr; + +/* --- Syscall Wrappers --- */ +int write(int fd, const void* ptr, size_t count) { + int result = 0; + __asm__ volatile ("int $0x80" : "=a"(result) : "a"(SYS_WRITE), "b"(fd), "c"(ptr), "d"(count)); + return result; +} + +int read(int fd, void* ptr, size_t count) { + int result = 0; + __asm__ volatile ("int $0x80" : "=a"(result) : "a"(SYS_GETS), "b"(fd), "c"(ptr), "d"(count)); + return result; +} + +int open(const char* path, int oflag) { + int fd = -1; + __asm__ volatile ("int $0x80" : "=a"(fd) : "a"(SYS_OPEN), "b"(path), "c"(oflag)); + return fd; +} + +int close(int fd) { + int result = -1; + __asm__ volatile ("int $0x80" : "=a"(result) : "a"(SYS_CLOSE), "b"(fd)); + return result; +} + +/* --- file I/O --- */ +FILE* fopen(const char* filename, const char* mode) { + FILE* stream = malloc(sizeof(FILE)); + + int oflag = O_RDWR | O_CREAT | O_BIN; // TODO! + + int fd = open(filename, oflag); + + stream->_ptr = NULL; // Idk + stream->_file = fd; + stream->_oflag = oflag; + + return stream; +} + +int fclose(FILE* stream) { + int res = close(stream->_file); + free(stream); + + return res; +} + +size_t fread(void* ptr, size_t size, size_t count, FILE* stream) { + unsigned int offset = 0; + size_t readEl = 0; + int fd = stream->_file; + + while (readEl != count) { + if (read(fd, (void*)(ptr + offset), size) != size) break; + offset += size; + readEl++; + } + + return readEl; +} + +size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { + unsigned int offset = 0; + size_t writtenEl = 0; + int fd = stream->_file; + + while (writtenEl != count) { + if (write(fd, (void*)(ptr + offset), size) != size) break; + offset += size; + writtenEl++; + } + + return writtenEl; + +} + +int fseek(FILE* stream, long int origin, int offset) { + // TODO + return -1; +} + +long int ftell(FILE* stream) { + // TODO + return -1; +} + +/* --- stdout --- */ void putc(char c) { // write(stdout, &c, 1); TODO: This doesn't work and we need to use a static variable static char _c; _c = c; - write(stdout, &_c, 1); + write(1, &_c, 1); } void print(const char* s) { - write(stdout, s, strlen(s)); + write(1, s, strlen(s)); } void clear() { @@ -28,18 +121,18 @@ void clear() { // TODO: Support negative numbers int printf(const char* fmt, ...) { - uint32_t* argPtr = (uint32_t*)&fmt + 1; // First arg after fmt + unsigned int* argPtr = (unsigned int*)&fmt + 1; // First arg after fmt // Printing buffer static char* buffer; - static uint32_t len; - uint32_t max = 256; + static unsigned int len; + int max = 256; buffer = malloc(max); len = 0; - uint8_t state = 0; - for (uint32_t i = 0; fmt[i] != '\0'; i++) { + int state = 0; + for (int i = 0; fmt[i] != '\0'; i++) { if (len > max) { max *= 2; // Reallocate larger buffer TODO: Use realloc(); @@ -57,11 +150,11 @@ int printf(const char* fmt, ...) { } else if (state == '%') { switch (c) { case 'd': // Decimal number - strcat(buffer, itoa(*(uint32_t*)argPtr++, 10)); + strcat(buffer, itoa(*(unsigned int*)argPtr++, 10)); len += strlen(&buffer[len]); // Add the remaining length break; case 'x': // Hex number - strcat(buffer, itoa(*(uint32_t*)argPtr++, 16)); + strcat(buffer, itoa(*(unsigned int*)argPtr++, 16)); len += strlen(&buffer[len]); break; case 's': // String @@ -86,13 +179,13 @@ int printf(const char* fmt, ...) { } buffer[len] = '\0'; - write(stdout, buffer, len); + write(1, buffer, len); free(buffer); return 0; } -/* --- Input --- */ +/* --- stdin --- */ char getc() { char* character = (char*)0x2100; *character = '\0'; @@ -102,9 +195,9 @@ char getc() { // Reads until a newline // TODO: Use Read() Syscall -void read(char* buffer) { +void reads(char* buffer) { char c; - uint8_t len = 0; + int len = 0; while ((c = getc()) != '\n') { if (c == '\b') { diff --git a/include/c/syscall.h b/include/c/syscall.h index 5b0389a..9b533ad 100644 --- a/include/c/syscall.h +++ b/include/c/syscall.h @@ -18,24 +18,13 @@ typedef enum { } SYSCALL_NUMBERS; typedef enum { - O_CREAT = 0x1, // Create if does not exist - O_RDONLY = 0x2, // Read only - O_WRONLY = 0x4, // Write only - O_RDWR = 0x8, // Read and write + O_CREAT = 0x01, // Create if does not exist + O_RDONLY = 0x02, // Read only + O_WRONLY = 0x04, // Write only + O_RDWR = 0x08, // Read and write O_APPEND = 0x10, // Always writes at the end (appends) O_TRUNC = 0x20, // Truncate file size and position to 0 on Open + O_BIN = 0x40, // Read bytes, not text } OFLAGS; -int write(int fd, const void* buf, unsigned int len) { - int result = -1; - __asm__ volatile ("int $0x80" : "=a"(result) : "a"(SYS_WRITE), "b"(fd), "c"(buf), "d"(len)); - return result; -} - -int open(const char* path, int oflag) { - int result = -1; - __asm__ volatile ("int $0x80" : "=a"(result) : "a"(SYS_OPEN), "b"(path), "c"(oflag)); - return result; -} - #endif diff --git a/include/interrupt/pit.h b/include/interrupt/pit.h index 7fa64a3..b660ceb 100644 --- a/include/interrupt/pit.h +++ b/include/interrupt/pit.h @@ -11,8 +11,6 @@ #define COMMAND 0x43 #define INPUT_CLK 1193182 -static uint32_t* sleepTimerTicks = (uint32_t*)SLEEP_TIMER; - __attribute__ ((interrupt)) void timerHandler(intFrame_t* iframe) { static uint32_t cursorTicks = 0; @@ -22,7 +20,7 @@ void timerHandler(intFrame_t* iframe) { if (cursorTicks % 500 == 0) toggleCursor(); } - if (*sleepTimerTicks > 0) { --(*sleepTimerTicks); } + if (*(uint32_t*)SLEEP_TIMER > 0) { --(*(uint32_t*)SLEEP_TIMER); } sendPicEOI(0); } diff --git a/include/interrupt/syscalls.h b/include/interrupt/syscalls.h index 470d6a2..a79ad34 100644 --- a/include/interrupt/syscalls.h +++ b/include/interrupt/syscalls.h @@ -2,7 +2,6 @@ #define SYSCALL_H #include -#include #include #include #include @@ -12,11 +11,13 @@ #include /* - * TODO WARNING - Update MAX_SYSCALLS in the handler TODO + * XXX WARNING - Update MAX_SYSCALLS in the handler XXX */ // Args: ebx - number of miliseconds void sys_sleep() { + uint32_t* sleepTimerTicks = (uint32_t*)SLEEP_TIMER; + __asm__ volatile ("movl %%ebx, %0" : "=r"(*sleepTimerTicks)); while (*sleepTimerTicks > 0) { // Wait... @@ -27,6 +28,7 @@ void sys_sleep() { // Args: ebx - int fd // ecx - void* buf // edx - uint32_t len +// Rets: Number of bytes written void sys_write() { int32_t fd = 0; void* buf = NULL; @@ -48,55 +50,52 @@ void sys_write() { void sys_gets() { char* s; __asm__ volatile ("movl %%ebx, %0" : "=r"(s)); - read(s); + reads(s); } -// Args: ebx - amount of bytes to malloc -// Returns: eax - Pointer to allocated memory +// Args: ebx - size_t count +// Rets: Pointer to malloc-ed memory void sys_malloc() { - uint32_t size = 0; - __asm__ volatile ("movl %%ebx, %0" : "=b"(size)); + uint32_t count = 0; + __asm__ volatile ("movl %%ebx, %0" : "=b"(count)); // First Malloc() if (!mallocListHead) { - mallocInit(size); // Setup malloc linked list + mallocInit(count); // Setup malloc linked list } - void* ptr = mallocNextNode(size); + void* ptr = mallocNextNode(count); mallocMergeFree(); // Return allocated address in eax __asm__ volatile ("movl %0, %%eax" : : "r"(ptr)); } -// Args: ebx - allocated pointer +// Args: ebx - void* ptr void sys_free() { void* ptr = NULL; __asm__ volatile ("movl %%ebx, %0" : "=b"(ptr)); mallocFree(ptr); } -// Args: ebx - path, ecx - oflag +// Args: ebx - path, +// ecx - oflag +// Rets: Opened file descriptor void sys_open() { - int32_t fd = -1; + uint32_t fd = 0; char* path = NULL; uint32_t oflag = 0; - // From kernel.c - //extern openFileTable_t* openFileTable; - //extern inode_t* openINodeTable; - //extern uint32_t maxOpenFiles; - //extern uint32_t openFileCount; - //extern uint32_t maxOpenInodes; - //extern uint32_t openInodeCount; - __asm__ volatile ("nop" : "=b"(path), "=c"(oflag)); __asm__ volatile ("movl %0, %%eax" : : "a"(fd)); } +// Args: ebx - int fd +// Rets: status void sys_close() {} +// TODO void sys_seek() {} // System call table diff --git a/kern.iso b/kern.iso index 67e38ba..420efe4 100644 Binary files a/kern.iso and b/kern.iso differ diff --git a/src/calc.c b/src/calc.c index 0951cf9..dd7e3a3 100644 --- a/src/calc.c +++ b/src/calc.c @@ -15,7 +15,7 @@ int main(int argc, char** argv) { while (1) { printf("> "); - read(input); + reads(input); // Remove whitespace char* old = input; diff --git a/src/kernel.c b/src/kernel.c index 275421f..87f447b 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -75,6 +75,14 @@ void main() { mallocPhysicalAddr = kernelMallocPhysicalAddr; mallocPages = kernelMallocPages; + // Setup stdio FILE* + stdin->_file = 0; + stdin->_oflag = O_RDONLY; + stdout->_file = 1; + stdout->_oflag = O_WRONLY | O_APPEND; + stderr->_file = 2; + stderr->_oflag = O_WRONLY | O_APPEND; + // FS Setup cwd = malloc(1024); strcpy(cwd, "/"); @@ -92,7 +100,7 @@ void main() { char input[256]; char* inputPtr = input; - read(input); + reads(input); if (*input == '\0') continue; diff --git a/src/stage3.c b/src/stage3.c index dcfcbd7..c26beb0 100644 --- a/src/stage3.c +++ b/src/stage3.c @@ -26,7 +26,7 @@ void main() { } } - deinitMemoryRegion(0x1000, 0x11000); // Reserve kernel memory (under 0x12000) + deinitMemoryRegion(0x1000, 0x11fff); // Reserve kernel memory (under 0x12000) deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE); // Load root dir, find kernel INode and parse it