diff --git a/src/kernel/arch/i686/fdc.c b/src/kernel/arch/i686/fdc.c new file mode 100644 index 0000000..731ba6c --- /dev/null +++ b/src/kernel/arch/i686/fdc.c @@ -0,0 +1,240 @@ +#include +#include "fdc.h" +#include "isr.h" +#include "io.h" +#include "../../lib/time.h" + +static volatile bool g_fdc_irq = false; +static int g_curr_drive = 0; + +static void i686_fdc_irq(registers *regs){ + g_fdc_irq = true; +} + +static inline void wait_irq(){ + while(!g_fdc_irq); // Wait until g_fdc_irq is true + g_fdc_irq = false; // Then reset it to false +} + +void i686_fdc_initialize_dma(){ + i686_outb(0x0A, 0x06); // Mask DMA channel 2 + i686_outb(0xD8, 0xFF); // Reset master flip-flop + i686_outw(0x04, 0x1000); // Address = 0x1000 + i686_outb(0xD8, 0xFF); // Reset master flip-flop + i686_outb(0x05, 0xFF); // Count to 0x23FF (bytes in 2.5" floppy disk track) + i686_outb(0x05, 0x23); + i686_outb(0x80, 0x00); // External page register = 0 + i686_outb(0x0A, 0x02); // Unmask DMA channel 2 +} + +void i686_fdc_dma_read(){ + i686_outb(0x0A, 0x06); // Mask DMA channel 2 + i686_outb(0x0B, 0x56); // single transfer, address increment, autoinit, read, channel 2 + i686_outb(0x0A, 0x02); // Unmask DMA channel 2 +} + +void i686_fdc_dma_write(){ + i686_outb(0x0A, 0x06); // Mask DMA channel 2 + i686_outb(0x0B, 0x5A); // single transfer, address increment, autoinit, write, channel 2 + i686_outb(0x0A, 0x02); // Unmask DMA channel 2 +} + +uint8_t i686_fdc_msr_read(){ + return i686_inb(i686_FDC_MSR); +} + +void i686_fdc_send_cmd(uint8_t cmd){ + while(!(i686_fdc_msr_read() & i686_FDC_MSR_DATAREG)); + i686_outb(i686_FDC_FIFO, cmd); +} + +uint8_t i686_fdc_read_data(){ + while(!(i686_fdc_msr_read() & i686_FDC_MSR_DATAREG)); + return i686_inb(i686_FDC_FIFO); +} + +void i686_fdc_write_ccr(uint8_t v){ + i686_outb(i686_FDC_CTRL, v); +} + +void i686_fdc_drive_data(uint32_t stepr, uint32_t loadt, uint32_t unloadt, bool dma){ + uint32_t data = 0; + + i686_fdc_send_cmd(i686_FDC_CMD_SPECIFY); + + data = ((stepr & 0xF) << 4) | (unloadt & 0xF); + i686_fdc_send_cmd(data); + + data = loadt << 1 | dma ? 1 : 0; // Ensure dma is a 0/1 bool + i686_fdc_send_cmd(data); +} + +void i686_fdc_check_int(uint32_t *st0, uint32_t *cyl){ + i686_fdc_send_cmd(i686_FDC_CMD_CHECK_INT); + *st0 = i686_fdc_read_data(); + *cyl = i686_fdc_read_data(); +} + +int i686_fdc_motor(bool b){ + if(g_curr_drive > 3) return -2; + + uint32_t motor = 0; + switch(g_curr_drive){ + case 0: motor = i686_FDC_DOR_DRIVE0_MOTOR; break; + case 1: motor = i686_FDC_DOR_DRIVE1_MOTOR; break; + case 2: motor = i686_FDC_DOR_DRIVE2_MOTOR; break; + case 3: motor = i686_FDC_DOR_DRIVE3_MOTOR; break; + } + + if(b) i686_outb(i686_FDC_DOR, g_curr_drive | motor | i686_FDC_DOR_RESET | i686_FDC_DOR_DMA); + else i686_outb(i686_FDC_DOR, i686_FDC_DOR_RESET); + + // Give the motor some time + sleep(20); +} + +void i686_fdc_read_sector_imp(uint8_t head, uint8_t track, uint8_t sector){ + uint32_t st0, cyl; + + // Set DMA for read + i686_fdc_dma_read(); + + // Read a sector + i686_fdc_send_cmd(i686_FDC_CMD_READ_SECT | i686_FDC_CMD_EXT_MULTITRACK | i686_FDC_CMD_EXT_SKIP | i686_FDC_CMD_EXT_DENSITY); + i686_fdc_send_cmd(head << 2 | g_curr_drive); + i686_fdc_send_cmd(track); + i686_fdc_send_cmd(head); + i686_fdc_send_cmd(sector); + i686_fdc_send_cmd(i686_FDC_SECTOR_DTL_512); + i686_fdc_send_cmd((sector + 1) >= i686_FDC_SECTORS_PER_TRACK ? i686_FDC_SECTORS_PER_TRACK : sector + 1); + i686_fdc_send_cmd(i686_FDC_GAP3_3_5); + i686_fdc_send_cmd(0xFF); + + // Wait for IRQ + wait_irq(); + + // Read output + for(int i = 0; i < 7; i++) i686_fdc_read_data(); + + // Tell the FDC we are done + i686_fdc_check_int(&st0, &cyl); +} + +static void lba_to_chs(int lba, int *head, int *track, int *sector){ + *head = (lba % (i686_FDC_SECTORS_PER_TRACK * 2)) / i686_FDC_SECTORS_PER_TRACK; + *track = lba / (i686_FDC_SECTORS_PER_TRACK * 2); + *sector = lba % i686_FDC_SECTORS_PER_TRACK + 1; +} + +uint8_t *i686_fdc_read_sector(int lba){ + if(g_curr_drive > 3) return 0; + + // Convert LBA to CHS + int head = 0, track = 0, sector = 1; + lba_to_chs(lba, &head, &track, §or); + + // Turn on motor and seek + i686_fdc_motor(true); + if(i686_fdc_seek(track, head) != 0) return 0; + + // Read and turn off motor + i686_fdc_read_sector_imp(head, track, sector); + i686_fdc_motor(false); + + return (uint8_t *)0x1000; +} + +int i686_fdc_calibrate(uint32_t drive){ + uint32_t st0, cyl; + + if(drive > 3) return -2; + + i686_fdc_motor(true); + + for(int i = 0; i < 10; i++){ + // Send command + i686_fdc_send_cmd(i686_FDC_CMD_CALIBRATE); + i686_fdc_send_cmd(drive); + wait_irq(); + i686_fdc_check_int(&st0, &cyl); + + if(!cyl){ + i686_fdc_motor(false); + return 0; + } + } + + + i686_fdc_motor(false); + return -1; +} + +int i686_fdc_seek(uint32_t cyl, uint32_t head){ + uint32_t st0, cyl0; + + if(g_curr_drive > 3) return -2; + + for(int i = 0; i < 10; i++){ + // Send the command + i686_fdc_send_cmd(i686_FDC_CMD_SEEK); + i686_fdc_send_cmd(head << 2 | g_curr_drive); + i686_fdc_send_cmd(cyl); + + // Wait for the results + wait_irq(); + i686_fdc_check_int(&st0, &cyl0); + + // Found? + if(cyl0 == cyl) return 0; + } + + return -1; +} + +void i686_fdc_disable(){ + i686_outb(i686_FDC_DOR, 0); +} + +void i686_fdc_enable(){ + i686_outb(i686_FDC_DOR, i686_FDC_DOR_RESET | i686_FDC_DOR_DMA); +} + +void i686_fdc_reset(){ + uint32_t st0, cyl; + + // Reset the controller + i686_fdc_disable(); + i686_fdc_enable(); + wait_irq(); + + // CHECK_INT to all drives + for(int i = 0; i < 4; i++) i686_fdc_check_int(&st0, &cyl); + + // 500kb/s + i686_fdc_write_ccr(0); + + // steprate = 3ms, unload time = 240ms, load time = 16ms, dma = true + i686_fdc_drive_data(3, 16, 240, true); + + // Calibrate the disk + i686_fdc_calibrate(g_curr_drive); +} + +void i686_fdc_set_working_drive(int drive){ + if(drive < 4) g_curr_drive = drive; +} + +void i686_fdc_initialize(){ + debug_printf("[FDC] Initializing\n"); + // Setup IRQ + i686_isr_register_handler(IRQ(6), i686_fdc_irq); + + // Initialize DMA + i686_fdc_initialize_dma(); + + // Reset FDC + i686_fdc_reset(); + + // Set drive info + i686_fdc_drive_data(13, 1, 0x0F, true); +} diff --git a/src/kernel/arch/i686/fdc.h b/src/kernel/arch/i686/fdc.h new file mode 100644 index 0000000..5d391fa --- /dev/null +++ b/src/kernel/arch/i686/fdc.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include + +#define i686_FDC_DOR 0x3F2 +#define i686_FDC_MSR 0x3F4 +#define i686_FDC_FIFO 0x3F5 +#define i686_FDC_CTRL 0x3F7 +#define i686_FDC_DOR_DRIVE0 0x00 +#define i686_FDC_DOR_DRIVE1 0x01 +#define i686_FDC_DOR_DRIVE2 0x02 +#define i686_FDC_DOR_DRIVE3 0x03 +#define i686_FDC_DOR_RESET 0x04 +#define i686_FDC_DOR_DMA 0x08 +#define i686_FDC_DOR_DRIVE0_MOTOR 0x10 +#define i686_FDC_DOR_DRIVE1_MOTOR 0x20 +#define i686_FDC_DOR_DRIVE2_MOTOR 0x40 +#define i686_FDC_DOR_DRIVE3_MOTOR 0x80 +#define i686_FDC_MSR_DRIVE0_POS_MODE 0x01 +#define i686_FDC_MSR_DRIVE1_POS_MODE 0x02 +#define i686_FDC_MSR_DRIVE2_POS_MODE 0x04 +#define i686_FDC_MSR_DRIVE3_POS_MODE 0x08 +#define i686_FDC_MSR_BUSY 0x10 +#define i686_FDC_MSR_DMA 0x20 +#define i686_FDC_MSR_DATAIO 0x40 +#define i686_FDC_MSR_DATAREG 0x80 +#define i686_FDC_CMD_READ_TRACK 0x02 +#define i686_FDC_CMD_SPECIFY 0x03 +#define i686_FDC_CMD_CHECK_STAT 0x04 +#define i686_FDC_CMD_WRITE_SECT 0x05 +#define i686_FDC_CMD_READ_SECT 0x06 +#define i686_FDC_CMD_CALIBRATE 0x07 +#define i686_FDC_CMD_CHECK_INT 0x08 +#define i686_FDC_CMD_WRITE_DEL_S 0x09 +#define i686_FDC_CMD_READ_ID_S 0x0A +#define i686_FDC_CMD_READ_DEL_S 0x0C +#define i686_FDC_CMD_FORMAT_TRACK 0x0D +#define i686_FDC_CMD_SEEK 0x0F +#define i686_FDC_CMD_EXT_SKIP 0x20 +#define i686_FDC_CMD_EXT_DENSITY 0x40 +#define i686_FDC_CMD_EXT_MULTITRACK 0x80 +#define i686_FDC_GAP3_STD 42 +#define i686_FDC_GAP3_5_14 32 +#define i686_FDC_GAP3_3_5 27 +#define i686_FDC_SECTOR_DTL_128 0 +#define i686_FDC_SECTOR_DTL_256 1 +#define i686_FDC_SECTOR_DTL_512 2 +#define i686_FDC_SECTOR_DTL_1024 4 +#define i686_FDC_SECTORS_PER_TRACK 18 + +void i686_fdc_initialize_dma(); +void i686_fdc_dma_read(); +void i686_fdc_dma_write(); +uint8_t i686_fdc_msr_read(); +void i686_fdc_send_cmd(uint8_t cmd); +uint8_t i686_fdc_read_data(); +void i686_fdc_write_ccr(uint8_t v); +void i686_fdc_drive_data(uint32_t stepr, uint32_t loadt, uint32_t unloadt, bool dma); +void i686_fdc_check_int(uint32_t *st0, uint32_t *cyl); +int i686_fdc_motor(bool b); +void i686_fdc_read_sector_imp(uint8_t head, uint8_t track, uint8_t sector); +uint8_t *i686_fdc_read_sector(int lba); +int i686_fdc_calibrate(uint32_t drive); +int i686_fdc_seek(uint32_t cyl, uint32_t head); +void i686_fdc_disable(); +void i686_fdc_enable(); +void i686_fdc_reset(); +void i686_fdc_set_working_drive(int drive); +void i686_fdc_initialize(); diff --git a/src/kernel/arch/i686/pit.c b/src/kernel/arch/i686/pit.c new file mode 100644 index 0000000..de631de --- /dev/null +++ b/src/kernel/arch/i686/pit.c @@ -0,0 +1,19 @@ +#include "pit.h" +#include "isr.h" +#include "../../lib/stdio.h" +#include "../../lib/debug.h" + +static volatile uint32_t g_tick_count = 0; + +static void i686_pit_handler(registers *regs){ + g_tick_count++; +} + +void i686_pit_initialize(){ + debug_printf("[PIT] Initializing\n"); + i686_isr_register_handler(IRQ(0), i686_pit_handler); +} + +uint32_t i686_pit_get_tick_count(){ + return g_tick_count; +} diff --git a/src/kernel/arch/i686/pit.h b/src/kernel/arch/i686/pit.h new file mode 100644 index 0000000..87afd64 --- /dev/null +++ b/src/kernel/arch/i686/pit.h @@ -0,0 +1,6 @@ +#pragma once + +#include + +void i686_pit_initialize(); +uint32_t i686_pit_get_tick_count(); diff --git a/src/kernel/drivers/keyboard.c b/src/kernel/drivers/keyboard.c index be99c41..6fee995 100644 --- a/src/kernel/drivers/keyboard.c +++ b/src/kernel/drivers/keyboard.c @@ -11,54 +11,66 @@ static bool g_caps_lock = false; static bool g_shift = false; -static char g_key_buffer[256]; +static struct { + char buffer[KEY_BUFFER_LENGTH]; + int base; + int top; +} g_key_buffer; + +void keyboard_buffer_add(char c){ + g_key_buffer.buffer[g_key_buffer.top] = c; + g_key_buffer.top++; + g_key_buffer.top %= KEY_BUFFER_LENGTH; +} + +char keyboard_buffer_get(){ + char c = g_key_buffer.buffer[g_key_buffer.base]; + g_key_buffer.base++; + g_key_buffer.base %= KEY_BUFFER_LENGTH; + return c; +} + +int keyboard_buffer_length(){ + int base = g_key_buffer.base; + int top = g_key_buffer.top; + if(top < base) top += KEY_BUFFER_LENGTH; + return top - base; +} static const char g_sc_ascii[128] = { '?', '?', '1', '2', '3', '4', '5', '6', - '7', '8', '9', '0', '-', '=', '?', '?', + '7', '8', '9', '0', '-', '=', '\b', '?', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', '?', '?', 'a', 's', + 'o', 'p', '[', ']', '\n', '?', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', '?', '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '?', '?', '?', ' ' }; -static void user_input(char *str){ - shell_run(str); -} - static void keyboard_callback(){ uint8_t scancode = i686_inb(0x60); if(scancode == 0x2A) g_shift = true; // Shift pressed else if(scancode == 0x2A + 128) g_shift = false; // Shift released else if(scancode == 0x3A) g_caps_lock = !g_caps_lock; // Caps lock pressed else if(scancode < 128){ // If it's a "pressed" event, not "released" - if(scancode == 0x0E){ // Backspace - putc('\b'); - g_key_buffer[strlen(g_key_buffer)-1] = '\0'; - } - else if(scancode == 0x1C){ // Enter - putc('\n'); - user_input(g_key_buffer); - g_key_buffer[0] = '\0'; - } - else{ - char c = g_sc_ascii[scancode]; - if(c >= 'a' && c <= 'z' && g_shift != g_caps_lock) c += 'A' - 'a'; - putc(c); + char c = g_sc_ascii[scancode]; + if(c >= 'a' && c <= 'z' && g_shift != g_caps_lock) c += 'A' - 'a'; - // strlen() works here because char[] is the same as - // char*, and both are null-terminated, so they are - // exactly the same - int len = strlen(g_key_buffer); - g_key_buffer[len] = c; - g_key_buffer[len+1] = '\0'; - } + // strlen() works here because char[] is the same as + // char*, and both are null-terminated, so they are + // exactly the same + keyboard_buffer_add(c); } } void keyboard_initialize(){ - debug_printf("[KEYBOARD] Initializing keyboard\n"); + debug_printf("[KEYBOARD] Initializing\n"); + + // Setup IRQ i686_isr_register_handler(IRQ(1), keyboard_callback); + + // Initialize key buffer + g_key_buffer.base = 0; + g_key_buffer.top = 0; } diff --git a/src/kernel/drivers/keyboard.h b/src/kernel/drivers/keyboard.h index 194ced5..565a0ce 100644 --- a/src/kernel/drivers/keyboard.h +++ b/src/kernel/drivers/keyboard.h @@ -1,3 +1,7 @@ #pragma once +#define KEY_BUFFER_LENGTH 16 + +char keyboard_buffer_get(); +int keyboard_buffer_length(); void keyboard_initialize(); diff --git a/src/kernel/drivers/timer.c b/src/kernel/drivers/timer.c deleted file mode 100644 index 57f8866..0000000 --- a/src/kernel/drivers/timer.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "timer.h" -#include "../arch/i686/isr.h" -#include "../lib/stdio.h" -#include "../lib/debug.h" - -static void timer_handler(registers *regs){ - //printf("TICK\n"); -} - -void timer_initialize(){ - debug_printf("[TIMER] Initializing PIT\n"); - i686_isr_register_handler(IRQ(0), timer_handler); -} diff --git a/src/kernel/drivers/timer.h b/src/kernel/drivers/timer.h deleted file mode 100644 index 4f33b4d..0000000 --- a/src/kernel/drivers/timer.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void timer_initialize(); diff --git a/src/kernel/hal/hal.c b/src/kernel/hal/hal.c index 57345cd..d96d558 100644 --- a/src/kernel/hal/hal.c +++ b/src/kernel/hal/hal.c @@ -2,9 +2,15 @@ #include "../arch/i686/gdt.h" #include "../arch/i686/idt.h" #include "../arch/i686/isr.h" +#include "../arch/i686/pit.h" void hal_initialize(){ i686_gdt_initialize(); i686_idt_initialize(); i686_isr_initialize(); + i686_pit_initialize(); +} + +uint32_t hal_get_tick_count(){ + return i686_pit_get_tick_count(); } diff --git a/src/kernel/hal/hal.h b/src/kernel/hal/hal.h index 4fa1812..af08711 100644 --- a/src/kernel/hal/hal.h +++ b/src/kernel/hal/hal.h @@ -1,3 +1,6 @@ #pragma once +#include + void hal_initialize(); +uint32_t hal_get_tick_count(); diff --git a/src/kernel/lib/stdio.c b/src/kernel/lib/stdio.c index 247fdb9..b9bfaed 100644 --- a/src/kernel/lib/stdio.c +++ b/src/kernel/lib/stdio.c @@ -3,6 +3,7 @@ #include "stdio.h" #include "../drivers/vga.h" #include "../drivers/uart.h" +#include "../drivers/keyboard.h" typedef void (*print_callable_fn_t)(char); @@ -128,6 +129,34 @@ void serial_printf(char *fmt, ...){ _vprintf(serial_putc, fmt, args); } +void gets(char *str, int max){ + int count = 0; + str[0] = '\0'; + + for(;;){ + if(keyboard_buffer_length()){ + char c = keyboard_buffer_get(); + if(c == '\n'){ + putc(c); + return; + } + else if(c == '\b'){ + if(count){ + putc(c); + str[count--] = '\0'; + } + } + else{ + if(count < max){ + putc(c); + str[count] = c; + str[++count] = '\0'; + } + } + } + } +} + void clear_screen(){ vga_fill_screen(' ', VGA_COLOR_BG_BLACK | VGA_COLOR_FG_WHITE); vga_set_cursor(0); diff --git a/src/kernel/lib/stdio.h b/src/kernel/lib/stdio.h index 6176760..8596e70 100644 --- a/src/kernel/lib/stdio.h +++ b/src/kernel/lib/stdio.h @@ -9,4 +9,5 @@ void vprintf(char *fmt, va_list args); void printf(char *fmt, ...); void serial_vprintf(char *fmt, va_list args); void serial_printf(char *fmt, ...); +void gets(char *str, int max); void clear_screen(); diff --git a/src/kernel/lib/string.c b/src/kernel/lib/string.c index f7003bc..45dac6a 100644 --- a/src/kernel/lib/string.c +++ b/src/kernel/lib/string.c @@ -17,3 +17,14 @@ void strcpy(char *dest, char *src){ } *dest = '\0'; } + +int atoi(char *str){ + int res = 0; + + for(int i = 0; i < strlen(str); i++){ + res *= 10; + res += str[i] - '0'; + } + + return res; +} diff --git a/src/kernel/lib/string.h b/src/kernel/lib/string.h index 6338e57..20b1e18 100644 --- a/src/kernel/lib/string.h +++ b/src/kernel/lib/string.h @@ -3,3 +3,4 @@ int strlen(char *s); int strcmp(char *s1, char *s2); void strcpy(char *dest, char *src); +int atoi(char *str); diff --git a/src/kernel/lib/time.c b/src/kernel/lib/time.c new file mode 100644 index 0000000..cb61a1a --- /dev/null +++ b/src/kernel/lib/time.c @@ -0,0 +1,8 @@ +#include +#include "time.h" +#include "../hal/hal.h" + +void sleep(int ms){ + uint32_t ticks = ms + hal_get_tick_count(); + while(ticks > hal_get_tick_count()); +} diff --git a/src/kernel/lib/time.h b/src/kernel/lib/time.h new file mode 100644 index 0000000..6d8acec --- /dev/null +++ b/src/kernel/lib/time.h @@ -0,0 +1,3 @@ +#pragma once + +void sleep(int ms); diff --git a/src/kernel/main.c b/src/kernel/main.c index 9ed149d..5367c0b 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,7 +1,6 @@ #include #include "lib/stdio.h" #include "hal/hal.h" -#include "drivers/timer.h" #include "drivers/keyboard.h" #include "drivers/uart.h" #include "fs/vfs.h" @@ -9,6 +8,7 @@ #include "arch/i686/mm/vmm.h" #include "multiboot.h" #include "lib/debug.h" +#include "arch/i686/fdc.h" extern uint8_t end; // Kernel end @@ -23,7 +23,6 @@ void __attribute__((cdecl)) kmain(multiboot_info_t *multiboot_info){ uart_initialize(COM1, 2); // Initialize drivers - timer_initialize(); keyboard_initialize(); // Initialize physical memory manager @@ -31,6 +30,8 @@ void __attribute__((cdecl)) kmain(multiboot_info_t *multiboot_info){ i686_pmm_initialize(mem_size, (int)(&end)); + // Memory map + debug_printf("= Memory map =\n"); for(int i = 0; i < multiboot_info->mmap_length; i += sizeof(multiboot_memory_map_t)){ multiboot_memory_map_t *memory_map = (multiboot_memory_map_t *)(multiboot_info->mmap_addr + i); debug_printf("Start Addr: 0x%x%x | Length: 0x%x%x | Size: 0x%x | Type: %i\n", memory_map->addr_h, memory_map->addr_l, memory_map->len_h, memory_map->len_l, memory_map->size, memory_map->type); @@ -45,8 +46,17 @@ void __attribute__((cdecl)) kmain(multiboot_info_t *multiboot_info){ // Initialize virtual memory i686_vmm_initialize(); + // Floppy disk controller + i686_fdc_set_working_drive(0); + i686_fdc_initialize(); + // Initialize FS vfs_initialize(); + // Run shell + shell(); + + // Halt at end + debug_printf("Kernel execution ended\n"); for(;;); } diff --git a/src/kernel/shell.c b/src/kernel/shell.c index a974b99..73a28e3 100644 --- a/src/kernel/shell.c +++ b/src/kernel/shell.c @@ -1,7 +1,10 @@ +#include #include "shell.h" #include "lib/stdio.h" #include "lib/string.h" #include "lib/memory.h" +#include "lib/time.h" +#include "arch/i686/fdc.h" int shell_run(char *cmd){ int ret = 0; @@ -19,6 +22,35 @@ int shell_run(char *cmd){ else if(!strcmp(cmd, "serial")){ serial_printf("Hello world!\n"); } + else if(!strcmp(cmd, "sleep")){ + printf("Sleeping...\n"); + sleep(25); + printf("Done!\n"); + } + else if(!strcmp(cmd, "readsect")){ + puts("Sector number: "); + char secn_str[4]; + gets(secn_str, 3); + int secn = atoi(secn_str); + + uint8_t *sector = i686_fdc_read_sector(secn); + + if(sector){ + int i = 0; + for(int c = 0; c < 4; c++){ + for(int j = 0; j < 128; j++){ + printf("0x%x ", sector[i+j]); + } + i += 128; + printf("\nPress enter to continue\n"); + gets(NULL, NULL); + } + } + else{ + printf("ERROR reading sector %i from disk", secn); + } + printf("Done!\n"); + } else{ printf("SHELL: Unknown command \"%s\"\n", cmd); ret = 127; @@ -27,3 +59,14 @@ int shell_run(char *cmd){ return ret; } + +void shell(){ + puts("\x1b[33mWelcome to quark!\x1b[0m\n\n"); + + for(;;){ + static char cmd_buffer[256]; + puts("$>"); + gets(cmd_buffer, 255); + shell_run(cmd_buffer); + } +} diff --git a/src/kernel/shell.h b/src/kernel/shell.h index 0cff83b..e21cbf2 100644 --- a/src/kernel/shell.h +++ b/src/kernel/shell.h @@ -1,3 +1,3 @@ #pragma once -int shell_run(); +void shell();