CeDOS - Commit 750de1e6

Added very basic file interface for keyboard input and tty output
Celina Kalus
Tue, 14 Mar 2023 16:52:40 +0100
12 files changed, 197 insertions(+), 30 deletions(-)
M include/cedos/drivers/keyboard.hinclude/cedos/drivers/keyboard.h

@@ -25,7 +25,7 @@ /*!

* Reads a single character from the keyboard * \return A single char corresponding to a key press. */ - uint32_t (*read)(void); + uint8_t (*read)(void); } KB_DRIVER; //! PS/2 keyboard driver (default driver)
A include/cedos/file.h

@@ -0,0 +1,11 @@

+#ifndef FILE_H +#define FILE_H + +#include <stdint.h> + +#include "cedos/mm/paging.h" + +int file_read(int fd, char *buffer, uint32_t size); +int file_write(int fd, char *buffer, uint32_t size); + +#endif
M src/apps/cedos.csrc/apps/cedos.c

@@ -1,11 +1,12 @@

#include "cedos.h" #include "assembly.h" +#include <stdint.h> -int sysprint(const char *fmt, int arg1, int arg2) { +/*int sysprint(const char *fmt, int arg1, int arg2) { int res = 0; interrupt(0x30, res, 4, fmt, arg1, arg2); return res; -} +}*/ int yield() { int res = 0;

@@ -17,4 +18,17 @@ int get_pid() {

int res = 0; interrupt(0x30, res, 3, 0, 0, 0); return res; -}+} + +int sc_file_read(int fd, char *buffer, uint32_t size) { + int res = 0; + interrupt(0x30, res, 0, fd, buffer, size); + return res; +} + +int sc_file_write(int fd, char *buffer, uint32_t size) { + int res = 0; + interrupt(0x30, res, 1, fd, buffer, size); + return res; +} +
M src/apps/cedos.hsrc/apps/cedos.h

@@ -3,8 +3,13 @@ #define CEDOS_H

#include "assembly.h" +#include <stdint.h> + int sysprint(const char *fmt, int arg1, int arg2); int yield(); int get_pid(); + +int sc_file_read(int fd, char *buffer, uint32_t size); +int sc_file_write(int fd, char *buffer, uint32_t size); #endif
M src/apps/fibonacci.csrc/apps/fibonacci.c

@@ -8,8 +8,10 @@ while (1) {

uint32_t tmp = a + b; a = b; b = tmp; - sysprint("fib (%i) = %i\n", i, a); + printf("fib (%i) = %i\n", i, a); i++; - hlt();//yield(); + char c = 0; + sc_file_read(0, &c, 1); + printf("[%c]\n", (int)(uint32_t)c);//yield(); } }
A src/apps/stdio.c

@@ -0,0 +1,102 @@

+#include "cedos.h" +#include "stdio.h" + +#include <stdarg.h> + +char user_numeric[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; +char user_hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + +int print_char(char c) { + sc_file_write(0, &c, 1); +} + +char read_char() { + char c; + sc_file_read(1, &c, 1); + return c; +} + +void print_hex_char(uint8_t c) { + print_char(user_hex[c >> 4]); + print_char(user_hex[c & 0x0F]); +} + +void print_uint32(uint32_t value) { + uint8_t* mem = (uint8_t*)(&value); + for (int i = 0; i < 4; i++) { + print_hex_char(mem[3-i]); + } +} + +void rek_print_uint(unsigned int value) { + if (value > 0) { + rek_print_uint(value / 10); + print_char(user_numeric[value % 10]); + } +} + +void print_uint(unsigned int value) { + if (value == 0) { + print_char('0'); + return; + } + + rek_print_uint(value); +} + +void print_int(int value) { + if (value < 0) { + print_char('-'); + print_int(-value); + return; + } else if (value == 0) { + print_char('0'); + return; + } + + rek_print_uint((unsigned int)value); +} + +int printf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + uint32_t index = 0; + + enum { + STATE_DEFAULT, + STATE_ARGUMENT, + } state = STATE_DEFAULT; + + while (*fmt) { + if (state == STATE_ARGUMENT && *fmt == 'X') { + print_uint32(va_arg(args, uint32_t)); + state = STATE_DEFAULT; + } else if (state == STATE_ARGUMENT && *fmt == 'i') { + print_int(va_arg(args, int)); + state = STATE_DEFAULT; + } else if (state == STATE_ARGUMENT && *fmt == 'u') { + print_uint(va_arg(args, unsigned int)); + state = STATE_DEFAULT; + } else if (state == STATE_ARGUMENT && *fmt == 'p') { + print_uint32(va_arg(args, uint32_t)); + state = STATE_DEFAULT; + } else if (state == STATE_ARGUMENT && *fmt == 's') { + const char* string = va_arg(args, const char*); + while (*string) { print_char(*string++); } + state = STATE_DEFAULT; + } else if (state == STATE_ARGUMENT && *fmt == 'c') { + print_char(va_arg(args, int)); + state = STATE_DEFAULT; + } else if (state == STATE_ARGUMENT && *fmt == '%') { + print_char('%'); + state = STATE_DEFAULT; + } else if (*fmt == '%') { + state = STATE_ARGUMENT; + } else { + print_char(*fmt); + } + + fmt++; + } +}
A src/apps/stdio.h

@@ -0,0 +1,6 @@

+#ifndef STDIO_H +#define STDIO_H + +int printf(const char *fmt, ...); + +#endif
M src/kernel/core.csrc/kernel/core.c

@@ -7,45 +7,45 @@

char numeric[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; -void print_hex_char(uint8_t c) { +void printk_hex_char(uint8_t c) { core_con->write_c(hex[c >> 4]); core_con->write_c(hex[c & 0x0F]); } -void print_uint32(uint32_t value) { +void printk_uint32(uint32_t value) { uint8_t* mem = (uint8_t*)(&value); for (int i = 0; i < 4; i++) { - print_hex_char(mem[3-i]); + printk_hex_char(mem[3-i]); } } -void rek_print_uint(unsigned int value) { +void rek_printk_uint(unsigned int value) { if (value > 0) { - rek_print_uint(value / 10); + rek_printk_uint(value / 10); core_con->write_c(numeric[value % 10]); } } -void print_uint(unsigned int value) { +void printk_uint(unsigned int value) { if (value == 0) { core_con->write_c('0'); return; } - rek_print_uint(value); + rek_printk_uint(value); } -void print_int(int value) { +void printk_int(int value) { if (value < 0) { core_con->write_c('-'); - print_int(-value); + printk_int(-value); return; } else if (value == 0) { core_con->write_c('0'); return; } - rek_print_uint((unsigned int)value); + rek_printk_uint((unsigned int)value); } void memdump(void* start, uint32_t size) {

@@ -58,14 +58,14 @@ uint32_t last_line = (uint32_t)(_end);

for (uint32_t i = first_line; i < last_line; i += 0x10) { core_con->write_c(' '); - print_uint32(i); + printk_uint32(i); core_con->write_c(' '); for (int j = 0; j < 0x10; j++) { uint8_t* p = (uint8_t*)(i | j); if (p >= start && p < (start + size)) { - print_hex_char(*p); + printk_hex_char(*p); core_con->write_c(' '); } else { core_con->write_c(' ');

@@ -123,16 +123,16 @@ } state = STATE_DEFAULT;

while (*fmt) { if (state == STATE_ARGUMENT && *fmt == 'X') { - print_uint32(va_arg(args, uint32_t)); + printk_uint32(va_arg(args, uint32_t)); state = STATE_DEFAULT; } else if (state == STATE_ARGUMENT && *fmt == 'i') { - print_int(va_arg(args, int)); + printk_int(va_arg(args, int)); state = STATE_DEFAULT; } else if (state == STATE_ARGUMENT && *fmt == 'u') { - print_uint(va_arg(args, unsigned int)); + printk_uint(va_arg(args, unsigned int)); state = STATE_DEFAULT; } else if (state == STATE_ARGUMENT && *fmt == 'p') { - print_uint32(va_arg(args, uint32_t)); + printk_uint32(va_arg(args, uint32_t)); state = STATE_DEFAULT; } else if (state == STATE_ARGUMENT && *fmt == 's') { const char* string = va_arg(args, const char*);
M src/kernel/drivers/ps2_keyboard.csrc/kernel/drivers/ps2_keyboard.c

@@ -32,7 +32,7 @@ /*!

* Reads a single character from the PS/2 keyboard * \return A single char corresponding to a key press. */ -uint32_t ps2_kb_read(void); +uint8_t ps2_kb_read(void); //! PS/2 keyboard driver (default driver) KB_DRIVER ps2_kb = {

@@ -96,7 +96,7 @@

return 1; } -uint32_t ps2_kb_read(void) { +uint8_t ps2_kb_read(void) { while (buffer_empty()) { sched_yield(); }
A src/kernel/file.c

@@ -0,0 +1,23 @@

+#include "cedos/file.h" + +#include "cedos/drivers/console.h" +#include "cedos/drivers/keyboard.h" + +int file_read(int fd, char *buffer, uint32_t size) { + for (int i = 0; i < size; i++) { + char table[] = { + 0, 0, '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; + buffer[i] = c; + } +} + +int file_write(int fd, char *buffer, uint32_t size) { + for (int i = 0; i < size; i++) { + std_con->write_c(buffer[i]); + } +}
M src/kernel/sched/sched.csrc/kernel/sched/sched.c

@@ -170,7 +170,9 @@ pic1_eoi();

} void entry_idle(void) { - while (1) { printk("idle.\n"); hlt(); } + while (1) { + //printk("idle.\n"); + } } extern void* sched_interrupt;

@@ -190,9 +192,11 @@ }

void sched_yield(void) { crit_enter(); + //printk("yield.\n"); PROCESS *current = get_process(current_pid); if (current != NULL && current->state != PSTATE_TERMINATED) { - current->state = PSTATE_BLOCKED; + current->state = PSTATE_READY; + //current->state = PSTATE_RUNNING; } uint32_t csc = crit_stash();
M src/kernel/syscall.csrc/kernel/syscall.c

@@ -1,6 +1,7 @@

#include "cedos/interrupts.h" #include "cedos/core.h" #include "cedos/sched/sched.h" +#include "cedos/file.h" void test(uint32_t ebx, uint32_t ecx, uint32_t edx) { printk("SYSCALL 0x01: EBX=%i ECX=%X EDX=%X\n", ebx, ecx, edx);

@@ -11,11 +12,10 @@ printk(fmt, arg1, arg2);

} void* SYSCALL_TABLE[] = { - test, - hard_reset, + file_read, + file_write, sched_yield, - get_current_process, - __sysprint + get_current_process }; extern void syscall_interrupt(void);