From bab4b308f92122841723043b118904172bcb5793 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Wed, 14 Aug 2024 14:32:44 +0200 Subject: [PATCH] Began working on file I/O through stdio.h. Wrote most of the code needed in stdio.h. Next up is writing the syscall handlers. --- include/c/stdio.h | 129 ++++++++++++++++++++++++++++++----- include/c/syscall.h | 21 ++---- include/interrupt/pit.h | 4 +- include/interrupt/syscalls.h | 39 ++++++----- kern.iso | Bin 1470464 -> 1470464 bytes src/calc.c | 2 +- src/kernel.c | 10 ++- src/stage3.c | 2 +- 8 files changed, 147 insertions(+), 60 deletions(-) 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 67e38bac384bcf6babb6528c0a973f10ad56968f..420efe498b8e7a52fdffff05670e583877d56ffc 100644 GIT binary patch delta 5667 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 ex`HgAFiVL delta 4853 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 M-IpUDo{yvRKZ=Y6)&Kwi 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