forked from PoliEcho-holding-org/kern
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:
+111
-18
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
while (1) {
|
||||
printf("> ");
|
||||
read(input);
|
||||
reads(input);
|
||||
|
||||
// Remove whitespace
|
||||
char* old = input;
|
||||
|
||||
+9
-1
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user