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 <string.h>
#include <stdlib.h>
#include <stdint.h>
// 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') {
+5 -16
View File
@@ -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
+1 -3
View File
@@ -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);
}
+19 -20
View File
@@ -2,7 +2,6 @@
#define SYSCALL_H
#include <interrupt/idt.h>
#include <interrupt/pit.h>
#include <terminal/terminal.h>
#include <keyboard/keyboard.h>
#include <memory/malloc.h>
@@ -12,11 +11,13 @@
#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
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
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -15,7 +15,7 @@ int main(int argc, char** argv) {
while (1) {
printf("> ");
read(input);
reads(input);
// Remove whitespace
char* old = input;
+9 -1
View File
@@ -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;
+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);
// Load root dir, find kernel INode and parse it