mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
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 <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
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+1
-1
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user