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.

This commit is contained in:
2024-08-14 14:32:44 +02:00
parent 40e84e5b70
commit bab4b308f9
8 changed files with 147 additions and 60 deletions
+111 -18
View File
@@ -4,22 +4,115 @@
#include <syscall.h> #include <syscall.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
// TODO: Make a proper file descriptor table // Nobody should have to interface with the internals of this structure
#define stdin 0 typedef struct _iobuf {
#define stdout 1 char* _ptr;
#define stderr 2 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) { void putc(char c) {
// write(stdout, &c, 1); TODO: This doesn't work and we need to use a static variable // write(stdout, &c, 1); TODO: This doesn't work and we need to use a static variable
static char _c; static char _c;
_c = c; _c = c;
write(stdout, &_c, 1); write(1, &_c, 1);
} }
void print(const char* s) { void print(const char* s) {
write(stdout, s, strlen(s)); write(1, s, strlen(s));
} }
void clear() { void clear() {
@@ -28,18 +121,18 @@ void clear() {
// TODO: Support negative numbers // TODO: Support negative numbers
int printf(const char* fmt, ...) { 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 // Printing buffer
static char* buffer; static char* buffer;
static uint32_t len; static unsigned int len;
uint32_t max = 256; int max = 256;
buffer = malloc(max); buffer = malloc(max);
len = 0; len = 0;
uint8_t state = 0; int state = 0;
for (uint32_t i = 0; fmt[i] != '\0'; i++) { for (int i = 0; fmt[i] != '\0'; i++) {
if (len > max) { if (len > max) {
max *= 2; max *= 2;
// Reallocate larger buffer TODO: Use realloc(); // Reallocate larger buffer TODO: Use realloc();
@@ -57,11 +150,11 @@ int printf(const char* fmt, ...) {
} else if (state == '%') { } else if (state == '%') {
switch (c) { switch (c) {
case 'd': // Decimal number 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 len += strlen(&buffer[len]); // Add the remaining length
break; break;
case 'x': // Hex number case 'x': // Hex number
strcat(buffer, itoa(*(uint32_t*)argPtr++, 16)); strcat(buffer, itoa(*(unsigned int*)argPtr++, 16));
len += strlen(&buffer[len]); len += strlen(&buffer[len]);
break; break;
case 's': // String case 's': // String
@@ -86,13 +179,13 @@ int printf(const char* fmt, ...) {
} }
buffer[len] = '\0'; buffer[len] = '\0';
write(stdout, buffer, len); write(1, buffer, len);
free(buffer); free(buffer);
return 0; return 0;
} }
/* --- Input --- */ /* --- stdin --- */
char getc() { char getc() {
char* character = (char*)0x2100; char* character = (char*)0x2100;
*character = '\0'; *character = '\0';
@@ -102,9 +195,9 @@ char getc() {
// Reads until a newline // Reads until a newline
// TODO: Use Read() Syscall // TODO: Use Read() Syscall
void read(char* buffer) { void reads(char* buffer) {
char c; char c;
uint8_t len = 0; int len = 0;
while ((c = getc()) != '\n') { while ((c = getc()) != '\n') {
if (c == '\b') { if (c == '\b') {
+5 -16
View File
@@ -18,24 +18,13 @@ typedef enum {
} SYSCALL_NUMBERS; } SYSCALL_NUMBERS;
typedef enum { typedef enum {
O_CREAT = 0x1, // Create if does not exist O_CREAT = 0x01, // Create if does not exist
O_RDONLY = 0x2, // Read only O_RDONLY = 0x02, // Read only
O_WRONLY = 0x4, // Write only O_WRONLY = 0x04, // Write only
O_RDWR = 0x8, // Read and write O_RDWR = 0x08, // Read and write
O_APPEND = 0x10, // Always writes at the end (appends) O_APPEND = 0x10, // Always writes at the end (appends)
O_TRUNC = 0x20, // Truncate file size and position to 0 on Open O_TRUNC = 0x20, // Truncate file size and position to 0 on Open
O_BIN = 0x40, // Read bytes, not text
} OFLAGS; } 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 #endif
+1 -3
View File
@@ -11,8 +11,6 @@
#define COMMAND 0x43 #define COMMAND 0x43
#define INPUT_CLK 1193182 #define INPUT_CLK 1193182
static uint32_t* sleepTimerTicks = (uint32_t*)SLEEP_TIMER;
__attribute__ ((interrupt)) __attribute__ ((interrupt))
void timerHandler(intFrame_t* iframe) { void timerHandler(intFrame_t* iframe) {
static uint32_t cursorTicks = 0; static uint32_t cursorTicks = 0;
@@ -22,7 +20,7 @@ void timerHandler(intFrame_t* iframe) {
if (cursorTicks % 500 == 0) toggleCursor(); if (cursorTicks % 500 == 0) toggleCursor();
} }
if (*sleepTimerTicks > 0) { --(*sleepTimerTicks); } if (*(uint32_t*)SLEEP_TIMER > 0) { --(*(uint32_t*)SLEEP_TIMER); }
sendPicEOI(0); sendPicEOI(0);
} }
+19 -20
View File
@@ -2,7 +2,6 @@
#define SYSCALL_H #define SYSCALL_H
#include <interrupt/idt.h> #include <interrupt/idt.h>
#include <interrupt/pit.h>
#include <terminal/terminal.h> #include <terminal/terminal.h>
#include <keyboard/keyboard.h> #include <keyboard/keyboard.h>
#include <memory/malloc.h> #include <memory/malloc.h>
@@ -12,11 +11,13 @@
#include <fs/fs.h> #include <fs/fs.h>
/* /*
* TODO WARNING - Update MAX_SYSCALLS in the handler TODO * XXX WARNING - Update MAX_SYSCALLS in the handler XXX
*/ */
// Args: ebx - number of miliseconds // Args: ebx - number of miliseconds
void sys_sleep() { void sys_sleep() {
uint32_t* sleepTimerTicks = (uint32_t*)SLEEP_TIMER;
__asm__ volatile ("movl %%ebx, %0" : "=r"(*sleepTimerTicks)); __asm__ volatile ("movl %%ebx, %0" : "=r"(*sleepTimerTicks));
while (*sleepTimerTicks > 0) { // Wait... while (*sleepTimerTicks > 0) { // Wait...
@@ -27,6 +28,7 @@ void sys_sleep() {
// Args: ebx - int fd // Args: ebx - int fd
// ecx - void* buf // ecx - void* buf
// edx - uint32_t len // edx - uint32_t len
// Rets: Number of bytes written
void sys_write() { void sys_write() {
int32_t fd = 0; int32_t fd = 0;
void* buf = NULL; void* buf = NULL;
@@ -48,55 +50,52 @@ void sys_write() {
void sys_gets() { void sys_gets() {
char* s; char* s;
__asm__ volatile ("movl %%ebx, %0" : "=r"(s)); __asm__ volatile ("movl %%ebx, %0" : "=r"(s));
read(s); reads(s);
} }
// Args: ebx - amount of bytes to malloc // Args: ebx - size_t count
// Returns: eax - Pointer to allocated memory // Rets: Pointer to malloc-ed memory
void sys_malloc() { void sys_malloc() {
uint32_t size = 0; uint32_t count = 0;
__asm__ volatile ("movl %%ebx, %0" : "=b"(size)); __asm__ volatile ("movl %%ebx, %0" : "=b"(count));
// First Malloc() // First Malloc()
if (!mallocListHead) { if (!mallocListHead) {
mallocInit(size); // Setup malloc linked list mallocInit(count); // Setup malloc linked list
} }
void* ptr = mallocNextNode(size); void* ptr = mallocNextNode(count);
mallocMergeFree(); mallocMergeFree();
// Return allocated address in eax // Return allocated address in eax
__asm__ volatile ("movl %0, %%eax" : : "r"(ptr)); __asm__ volatile ("movl %0, %%eax" : : "r"(ptr));
} }
// Args: ebx - allocated pointer // Args: ebx - void* ptr
void sys_free() { void sys_free() {
void* ptr = NULL; void* ptr = NULL;
__asm__ volatile ("movl %%ebx, %0" : "=b"(ptr)); __asm__ volatile ("movl %%ebx, %0" : "=b"(ptr));
mallocFree(ptr); mallocFree(ptr);
} }
// Args: ebx - path, ecx - oflag // Args: ebx - path,
// ecx - oflag
// Rets: Opened file descriptor
void sys_open() { void sys_open() {
int32_t fd = -1; uint32_t fd = 0;
char* path = NULL; char* path = NULL;
uint32_t oflag = 0; 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 ("nop" : "=b"(path), "=c"(oflag));
__asm__ volatile ("movl %0, %%eax" : : "a"(fd)); __asm__ volatile ("movl %0, %%eax" : : "a"(fd));
} }
// Args: ebx - int fd
// Rets: status
void sys_close() {} void sys_close() {}
// TODO
void sys_seek() {} void sys_seek() {}
// System call table // System call table
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -15,7 +15,7 @@ int main(int argc, char** argv) {
while (1) { while (1) {
printf("> "); printf("> ");
read(input); reads(input);
// Remove whitespace // Remove whitespace
char* old = input; char* old = input;
+9 -1
View File
@@ -75,6 +75,14 @@ void main() {
mallocPhysicalAddr = kernelMallocPhysicalAddr; mallocPhysicalAddr = kernelMallocPhysicalAddr;
mallocPages = kernelMallocPages; 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 // FS Setup
cwd = malloc(1024); cwd = malloc(1024);
strcpy(cwd, "/"); strcpy(cwd, "/");
@@ -92,7 +100,7 @@ void main() {
char input[256]; char input[256];
char* inputPtr = input; char* inputPtr = input;
read(input); reads(input);
if (*input == '\0') continue; if (*input == '\0') continue;
+1 -1
View File
@@ -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); deinitMemoryRegion(MEMMAP_AREA, maxBlocks / BLOCKS_PER_BYTE);
// Load root dir, find kernel INode and parse it // Load root dir, find kernel INode and parse it