From 781029e00ad1efb141eb77e3f72f03f33bc03ce6 Mon Sep 17 00:00:00 2001 From: Alexander Myltsev Date: Tue, 13 Dec 2022 01:18:30 +0300 Subject: [PATCH] Support the "halt" command. --- drivers/keyboard.c | 19 ++++++++++++++----- drivers/keyboard.h | 3 +++ fs/fs.c | 8 ++++++-- kernel.c | 16 +++++++++++++--- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/drivers/keyboard.c b/drivers/keyboard.c index 8de3bec..f64a084 100644 --- a/drivers/keyboard.c +++ b/drivers/keyboard.c @@ -5,20 +5,29 @@ static const char sc_ascii[] = { '?', '?', '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', '?', '?', 'Q', 'W', 'E', 'R', 'T', 'Y', - 'U', 'I', 'O', 'P', '[', ']', '?', '?', 'A', 'S', 'D', 'F', 'G', - 'H', 'J', 'K', 'L', ';', '\'', '`', '?', '\\', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', ',', '.', '/', '?', '?', '?', ' ', + '7', '8', '9', '0', '-', '=', '?', '?', 'q', 'w', 'e', 'r', 't', 'y', + 'u', 'i', 'o', 'p', '[', ']', '\n', '?', 'a', 's', 'd', 'f', 'g', + 'h', 'j', 'k', 'l', ';', '\'', '`', '?', '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', '?', '?', '?', ' ', }; static void interrupt_handler(registers_t *r) { uint8_t scancode = port_byte_in(0x60); if (scancode < sizeof(sc_ascii)) { - char string[] = {sc_ascii[scancode], '\0'}; + char c = sc_ascii[scancode]; + if (kbd_buf_size < 1024) { + kbd_buf[kbd_buf_size++] = c; + } + char string[] = {c, '\0'}; printk(string); } } +char* kbd_buf; +unsigned kbd_buf_size; + void init_keyboard() { + kbd_buf = (char*)(1 << 20); + register_interrupt_handler(IRQ1, interrupt_handler); } diff --git a/drivers/keyboard.h b/drivers/keyboard.h index 33601ea..c13d4bb 100644 --- a/drivers/keyboard.h +++ b/drivers/keyboard.h @@ -1,3 +1,6 @@ #pragma once void init_keyboard(); + +extern unsigned kbd_buf_size; +extern char *kbd_buf; diff --git a/fs/fs.c b/fs/fs.c index 6a5c74a..abd1fef 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -29,11 +29,15 @@ int read_file(const char* name, void* buf, uint32_t bufsize) { return -1; } uint32_t sector = fs_start + statbuf.reserved[0]; - while (bufsize >= sector_size) { + uint32_t bytes_read = 0; + uint32_t file_sectors = (statbuf.size + sector_size - 1) / sector_size; + while (bufsize >= sector_size && file_sectors > 0) { read_sectors_ATA_PIO(buf, sector, 1); sector++; + file_sectors--; bufsize -= sector_size; buf += sector_size; + bytes_read += sector_size; } - return 0; + return bytes_read < statbuf.size ? bytes_read : statbuf.size; } diff --git a/kernel.c b/kernel.c index a7b3ec2..436dce6 100644 --- a/kernel.c +++ b/kernel.c @@ -9,6 +9,7 @@ asm(".asciz \"kernel start\""); #include "drivers/misc.h" #include "drivers/uart.h" #include "fs/fs.h" +#include "string.h" void _start() { load_gdt(); @@ -16,19 +17,28 @@ void _start() { uartinit(); load_idt(); sti(); - char buf[4096 + 512]; + + char *buf = (char*)(16 << 20); vga_clear_screen(); printk("YABLOKO\n"); - if (read_file("kernel.bin", buf, sizeof(buf)) == 0) { + if (read_file("kernel.bin", buf, 4096 + sector_size) > 0) { printk(buf + 4096); } else { printk("failed to read file\n"); } + printk("\n> "); while (1) { + if (kbd_buf_size > 0 && kbd_buf[kbd_buf_size-1] == '\n') { + if (!strncmp("halt\n", kbd_buf, kbd_buf_size)) { + qemu_shutdown(); + } else { + printk("unknown command, try: halt\n> "); + } + kbd_buf_size = 0; + } asm("hlt"); } - qemu_shutdown(); }