CeDOS - Commit e253ef8a

Merge branch 'feature-filesystem' into develop Added syscalls to enable applications to access files and unified FAT files and console in one interface (which is very hacky at this point)
Celina Kalus
Thu, 06 Apr 2023 19:32:03 +0200
15 files changed, 166 insertions(+), 53 deletions(-)
M include/cedos/file.hinclude/cedos/file.h

@@ -5,6 +5,8 @@ #include <stdint.h>

#include "cedos/mm/paging.h" +int file_open(const char *pathname, int flags); +int file_openat(int fd, const char *fname, int flags); int file_read(int fd, char *buffer, uint32_t size); int file_write(int fd, char *buffer, uint32_t size);
M run.shrun.sh

@@ -1,1 +1,1 @@

-qemu-system-i386 -drive index=0,if=floppy,format=raw,file=./build/release/cedos.img -m 64 -monitor stdio -no-reboot -d int,cpu_reset,exec,in_asm 2> log/run_err.log+qemu-system-i386 -drive index=0,if=floppy,format=raw,file=./build/release/cedos.img -m 64 -monitor stdio -no-reboot -d int,cpu_reset,exec,in_asm -vnc :0 2> log/run_err.log
A src/apps/cat.c

@@ -0,0 +1,25 @@

+#include "common/cedos.h" +#include "common/stdio.h" + +#include <stdint.h> + +void main(char *args) { + int fd = sc_file_open(args, 0); + + if (fd < 0) { + printf("Could not find file: %s\n", args); + return; + } + + char *buffer = (void*)(0x2000000); + + int size = sc_file_read(fd, buffer, -1); + + while (size > 0) { + int chunk = 256; + if (size < chunk) { chunk = size; } + sc_file_write(0, buffer, chunk); + size -= chunk; + buffer += chunk; + } +}
M src/apps/common/cedos.csrc/apps/common/cedos.c

@@ -20,6 +20,12 @@ interrupt(0x30, res, 3, 0, 0, 0);

return res; } +int file_openat(int fd, const char *fname, int flags) { + volatile uint32_t res = 0; + interrupt(0x30, res, 6, fd, fname, flags); + return res; +} + int sc_file_read(int fd, char *buffer, uint32_t size) { volatile uint32_t res = 0; interrupt(0x30, res, 0, fd, buffer, size);

@@ -41,4 +47,10 @@

void process_wait(int pid) { volatile uint32_t res = 0; interrupt(0x30, res, 5, pid, 0, 0); +} + +int sc_file_open(char *pathname, int flags) { + volatile uint32_t res = 0; + interrupt(0x30, res, 6, pathname, flags, 0); + return res; }
M src/apps/common/cedos.hsrc/apps/common/cedos.h

@@ -13,5 +13,7 @@ void process_wait(int pid);

int sc_file_read(int fd, char *buffer, uint32_t size); int sc_file_write(int fd, char *buffer, uint32_t size); +int sc_file_openat(int fd, char *buffer, uint32_t size); + #endif
M src/apps/common/stdio.csrc/apps/common/stdio.c

@@ -97,6 +97,12 @@ while (str[length]) { length++; }

print(str, length); } +int print_hex_char(uint8_t c) { + char buffer[2]; + int size = sprint_hex_char(c, buffer); + print(buffer, size); +} + void print_char(char c) { print(&c, 1); }

@@ -117,6 +123,8 @@ if (*fmt == 'X') {

print_uint32(va_arg(args, uint32_t)); } else if (*fmt == 'i') { print_int(va_arg(args, int)); + } else if (*fmt == 'x') { + print_int(va_arg(args, char)); } else if (*fmt == 'u') { print_uint(va_arg(args, unsigned int)); } else if (*fmt == 'p') {
M src/apps/echo.csrc/apps/echo.c

@@ -4,5 +4,5 @@

#include <stdint.h> void main(char *args) { - printf(args); + printf("%s\n", args); }
A src/apps/hexdump.c

@@ -0,0 +1,42 @@

+#include "common/cedos.h" +#include "common/stdio.h" + +#include <stdint.h> + +int hexdump(char *address, int length) { + unsigned char *first_line = (char *)((long)address & (long)0xFFFFFFF0); + unsigned char *last_line = (char *)((long)(address + length) & (long)0xFFFFFFF0); + + while (1) { + if (first_line >= last_line) { break; } + printf("%p ", first_line); + for (int i = 0; i < 16; i++) { + printf("%X ", (unsigned int)(first_line[i])); + } + printf(" |"); + for (int i = 0; i < 16; i++) { + uint8_t c = *(uint8_t*)(&first_line[i]); + if (c < 0x20 || c > 0x7F) { c = '.'; } + printf("%c", c); + } + printf("\n"); + + + first_line += 0x10; + } +} + +void main(char *args) { + int fd = sc_file_open(args, 0); + + if (fd < 0) { + printf("Could not find file: %s\n", args); + return; + } + + char *buffer = (void*)(0x2000000); + + int size = sc_file_read(fd, buffer, -1); + + hexdump(buffer, size); +}
M src/apps/shell.csrc/apps/shell.c

@@ -3,7 +3,7 @@ #include "common/stdio.h"

#include <stdint.h> -void read_line(char *buffer) { +int read_line(char *buffer) { int i = 0; char c; buffer[0] = 0;

@@ -25,6 +25,8 @@ }

buffer[i] = 0; sc_file_write(0, &c, 1); + + return i; } void main(char *args) {

@@ -36,11 +38,27 @@ while (1) {

printf("/> "); char buffer[256]; - read_line(buffer); + int length = read_line(buffer); + + if (length == 0) { continue; } + + char *file = buffer; + char *args = (char *)(0); + + int i = 0; + while (1) { + if (buffer[i] == ' ') { + buffer[i] = 0; + args = &(buffer[i+1]); + break; + } + + i++; + } //printf("Executing %s...\n", buffer); - int pid = process_spawn(buffer, "Hello, world!\n"); + int pid = process_spawn(file, args); //printf("Child process %i spawned, waiting for termination...\n", pid);
M src/kernel/elf.csrc/kernel/elf.c

@@ -2,7 +2,7 @@ #include <stdint.h>

#include "cedos/elf.h" #include "cedos/core.h" -#include "cedos/fat.h" +#include "cedos/file.h" #include "cedos/sched/process.h" #include "assert.h"

@@ -128,9 +128,9 @@ PROCESS_ID elf_exec(const char *fname, char *args) {

PRINT_DBG("Loading ELF executable \"%s\".\n", fname); VIRT_ADDR elf_addr = (VIRT_ADDR*)(0xA0000000); // TODO: needs to change when we have other file systems - int fd = FAT_openat(0, fname, 0); + int fd = file_open(fname, 0); assert(fd != -1); - int size = FAT_read(fd, elf_addr, 0); + int size = file_read(fd, elf_addr, 0); assert(size != 0); ELF_HEADER *header = (ELF_HEADER*)(elf_addr);
M src/kernel/fat.csrc/kernel/fat.c

@@ -188,6 +188,11 @@ int FAT_openat(int fd, const char *fname, int flags) {

int i = 0; // TODO: take fd into consideration (open file in that subdirectory) + + + if (!(fd & 0x1000)) { return -1; } + + fd &= 0x0FFF; uint16_t first_cluster; while (1) {

@@ -199,13 +204,15 @@ if (i <= 0) { return -1; }

if (strcmp(buffer, fname) == 0) { // file found - return first_cluster; + return first_cluster | 0x1000; } } } uint32_t FAT_read(int fd, void *buffer, int count) { - uint16_t cluster = fd; + if (!(fd & 0x1000)) { return -1; } + + uint16_t cluster = fd & 0xFFF; uint32_t size = 0; while (1) {
M src/kernel/file.csrc/kernel/file.c

@@ -3,18 +3,40 @@

#include "cedos/drivers/console.h" #include "cedos/drivers/keyboard.h" +const int root_fd = 0x1000; + +int file_open(const char *pathname, int flags) { + while (*pathname == '/') { + pathname++; + } + + return file_openat(0x1000, pathname, flags); +} + +int file_openat(int fd, const char *fname, int flags) { + if (fd & 0x1000) { + return FAT_openat(fd, fname, flags); + } else { + // open other files + } +} + int file_read(int fd, char *buffer, uint32_t size) { - int i = 0; - while (i < size) { - char table[] = { - '^', 0x1B, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\\', '´', 0x08, - '\t', 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', '+', '\n', - 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', '#', - 0, '<', 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-'}; - uint32_t scancode = std_kb->read(); - char c = scancode >= 0 && scancode <= 60 ? table[scancode] : 0; - if (c == 0) { continue; } - buffer[i++] = c; + if (fd & 0x1000) { + return FAT_read(fd, buffer, size); + } else { + int i = 0; + while (i < size) { + char table[] = { + '^', 0x1B, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\\', '´', 0x08, + '\t', 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', '+', '\n', + 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', '#', + 0, '<', 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, 0, 0, ' ' }; + uint32_t scancode = std_kb->read(); + char c = scancode >= 0 && scancode <= 60 ? table[scancode] : 0; + if (c == 0) { continue; } + buffer[i++] = c; + } } }
M src/kernel/main.csrc/kernel/main.c

@@ -62,6 +62,10 @@ printk("Initializing keyboard...");

ps2_kb.init(); printk("done.\n"); + printk("Initializing root file system..."); + FAT_init(); + printk("done."); + printk("Initialization finished.\n--------------\n");

@@ -142,36 +146,6 @@ }

int os_main(void) { infodump(); - - FAT_init(); - - int i = 0; - - while (1) { - char buffer[832]; - uint16_t first_cluster; - uint32_t file_size; - - i = FAT_root_dir_next(i, buffer, &first_cluster, &file_size); - if (i <= 0) { break; } - - PRINT_DBG("%s (start: %i, size: %i)\n", buffer, first_cluster, file_size); - - uint16_t cluster = first_cluster; - - if (cluster == 0xFFF || cluster == 0x000) { continue; } - - PRINT_DBG(" clusters: \n"); - while (1) { - PRINT_DBG(" %x\n", cluster); - - //char *sect = FAT_read_cluster(cluster); - //hexdump(sect, 512 * 8); - - cluster = FAT_next_cluster(cluster); - if (cluster == 0xFFF || cluster == 0x000) { break; } - } - } // create test tasks printk("Creating tasks.\n");
M src/kernel/sched/sched.csrc/kernel/sched/sched.c

@@ -55,7 +55,7 @@ PROCESS_ID sched_spawn(const char *name, char *args) {

crit_enter(); if (name != NULL) { - int fd = FAT_openat(0, name, 0); + int fd = file_open(name, 0); if (fd == -1) { return -1; } }
M src/kernel/syscall.csrc/kernel/syscall.c

@@ -17,7 +17,8 @@ file_write,

sched_yield, get_current_process, sched_spawn, - sched_wait + sched_wait, + file_open }; extern void syscall_interrupt(void);