From f6e2d0c19bfb2d82734a82c16ee6c908bdd4ae7e Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Sun, 25 Jan 2015 17:46:12 -0800 Subject: [PATCH] C kernel runs now after fixing bootloader and build, beginnings of a REPL --- Makefile | 15 +-- asm/bootloader.S | 14 ++- asm/kernel_syms.S | 26 ++++- src/kernel.c | 242 ++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 267 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index a875315..cfbcb00 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,15 @@ all: boot.img kernel.bin src/%.o: src/%.c - bcc -ansi -3 -c -o $@ $< + bcc -ansi -0 -c -o $@ $< kernel.bin: src/kernel.o - ld86 -T0x1000 -M -o $@ $^ + ld86 -d -M -o $@ $^ | tee ld86.out asm/kernel_syms.S: kernel.bin - objdump86 kernel.bin | \ - grep -E "^[0-9]+ T _.*" | \ - python -c "import sys; print '\n'.join([\"_extern_c%s:\n jmp 0x1000:0x%04x\" % (x.split(' ')[2].strip('\n'), int(x.split(' ')[0].lstrip('0'), 16)-0x1000) for x in sys.stdin.readlines()])" > asm/kernel_syms.S + cat ld86.out | \ + grep -E "^\s+kernel\s+[a-zA-Z0-9_]+ 0 [0-9]+" | \ + python -c "import sys; print '\n'.join([\"_extern_c%s:\n jmp 0x1000:0x%04x\" % (x.lstrip(' ').replace('kernel', '').lstrip(' ').split(' ')[0], int(x.lstrip(' ').replace('kernel', '').lstrip(' ').split(' ')[4], 16)) for x in sys.stdin.readlines()])" > asm/kernel_syms.S boot.bin: asm/kernel_syms.S asm/bootloader.S asm/bootloader.S cd asm && nasm bootloader.S -f bin -o ../$@ @@ -18,7 +18,10 @@ asm/%.o: asm/%.S nasm $< -f as86 -o $@ boot.img: boot.bin kernel.bin - cat $^ > $@ + dd if=/dev/zero of=boot.img ibs=1k count=1440 + cat $^ > boot.tmp + dd if=boot.tmp of=boot.img conv=notrunc + rm -f boot.tmp test: boot.img bochs -f bochsrc -q diff --git a/asm/bootloader.S b/asm/bootloader.S index 667d150..2967814 100644 --- a/asm/bootloader.S +++ b/asm/bootloader.S @@ -2,6 +2,10 @@ [org 0x7C00] ; Origin at 0x7C00 (upper end of memory) start: + ;; FIXME - we need to relocate ourselves to the + ;; upper end of memory somewhere so we can overwrite + ;; ourselves with the kernel at 0x0000 + call blankScreen mov dx, 0x0 @@ -13,10 +17,10 @@ start: mov dl, 0x0 call setCursorPosition - mov al, 0x1 ; read the remaining 16 tracks + mov al, 0x10 ; read the remaining 16 tracks mov ch, 0x0 ; .... on track 0 .... mov cl, 0x2 ; .... starting at sector 2 - mov bx, 0x1000 ; 0x1000 is a standard kernel start location + mov bx, 0x1000 ; Load the kernel into the bottom of memory mov es, bx mov bx, 0x0 ; bx = 0, es:bx = 0x1000:0 call loadFloppyDiskSectors @@ -58,6 +62,11 @@ _end_floppy_read: call setCursorPosition mov si, _str_floppydone call printString + mov ax, 0x1000 + mov ds, ax + mov ax, 0x1000 + mov ss, ax + mov sp, 0xFFFF jmp _extern_c_main %include "libinterrupt.S" @@ -69,4 +78,3 @@ _end_floppy_read: times 510 - ($ - $$) db 0 ; fill up to 510 bytes with 0 dw 0xAA55 ; magic bootloader signature - diff --git a/asm/kernel_syms.S b/asm/kernel_syms.S index 01ae27d..e727dac 100644 --- a/asm/kernel_syms.S +++ b/asm/kernel_syms.S @@ -1,4 +1,26 @@ +_extern_c_backupCursor: + jmp 0x1000:0x001e +_extern_c_blankScreen: + jmp 0x1000:0x03b6 +_extern_c_strlen: + jmp 0x1000:0x00ba _extern_c_main: - jmp 0x1000:0x0049 -_extern_c_printCh: + jmp 0x1000:0x0412 +_extern_c_getkey: + jmp 0x1000:0x0155 +_extern_c_repl: + jmp 0x1000:0x02ea +_extern_c_strcmp: + jmp 0x1000:0x0265 +_extern_c_advanceCursor: + jmp 0x1000:0x0067 +_extern_c_setCursorPosition: jmp 0x1000:0x0000 +_extern_c_memset: + jmp 0x1000:0x0227 +_extern_c_putc: + jmp 0x1000:0x00a0 +_extern_c_puts: + jmp 0x1000:0x00f4 +_extern_c_gets: + jmp 0x1000:0x017b diff --git a/src/kernel.c b/src/kernel.c index 415d7d5..d3b2628 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,34 +1,238 @@ -void printChar(char c) +char _cursor_x = 0; +char _cursor_y = 0; + +#define NULL 0x0 +typedef int size_t; + +void setCursorPosition(char x, char y) { #asm -#if !__FIRST_ARG_IN_AX__ - mov bx, sp -#endif -#if __FIRST_ARG_IN_AX__ - mov si, ax -#else - mov si, [bx+2] -#endif - mov ah, 0x0e - mov bh, 0x00 - mov bl, 0x07 - int 0x10 + push bx; + mov bx, sp; + mov dl, [bx+4]; + mov dh, [bx+6]; + pop bx; + push ax; + push bx; + mov ah, #0x02; + mov bx, #0x0; + int 0x10; + pop bx; + pop ax; +#endasm + return; +} + +void backupCursor() +{ + + if ( _cursor_x == 0 && _cursor_y > 0 ) { + _cursor_x = 80; + _cursor_y -= 1; + } else if ( _cursor_x > 0 ) { + _cursor_x -= 1; + } + setCursorPosition(_cursor_x, _cursor_y); +} + +void advanceCursor() +{ + _cursor_x += 1; + if ( _cursor_x > 79 ) { + _cursor_x = 0; + _cursor_y += 1; + } + setCursorPosition(_cursor_x, _cursor_y); +} + +void putc(char c) +{ +#asm + push bx; + push ax; + mov bx, sp; + mov al, [bx+6]; + mov ah, #0x0e; + mov bh, #0x00; + mov bl, #0x07; + int 0x10; + pop ax; + pop bx; #endasm return; } -void printString(char *ptr) +int strlen(char *ptr) { - while ((char)*ptr != '\0') { - printChar((char)*ptr); - ptr++; + char *ptr2 = ptr; + if ( ptr == NULL ) { + return 0; } + while (*ptr2 != 0x0 ) { + ptr2 += 1; + } + + return ptr2 - ptr; +} + +void puts(char *ptr, char x, char y) +{ + if ( ptr == NULL ) { + return; + } + while ((char)*ptr != 0x0) { + putc((char)*ptr); + if (*ptr == '\n') { + _cursor_y += 1; + _cursor_x = 0; + setCursorPosition(_cursor_x, _cursor_y); + } else { + advanceCursor(); + } + ptr += 1; + } return; } +char getkey(char *dest) +{ + char echo; + char scancode; +#asm + push ax; + mov ah, 0x10; + int 0x16; + mov [bp-6], ah; + mov [bp-5], al; + pop ax; +#endasm + *dest = echo; + return scancode; +} + +char *gets(char *d) +{ + char *orig = d; + char scancode; + char printable; + + if ( d == NULL ) { + return NULL; + } + + scancode = getkey(&printable); + + while ( scancode != NULL ) { + if ( scancode == 0x0e ) { + if ( d > orig ) { + backupCursor(); + setCursorPosition(_cursor_x, _cursor_y); + d -= 1; + putc(0x0); + } + } else if ( scancode == 0x1c ) { + break; + } else { + *(d++) = printable; + putc(printable); + advanceCursor(); + } + scancode = getkey(&printable); + } + + _gets_finish_loop: + *d = NULL; + return orig; +} + +void memset(void *s, int c, size_t n) +{ + int *d = (int *)s; + if ( s == NULL ) { + return; + } + while ( ((int)d - (int)s) <= n ) { + *d = c; + d += sizeof(int); + } +} + +signed int strcmp(char *s1, char *s2) +{ + int d = 0; + int s1len = 0; + + if ( s1 == NULL || s2 == NULL ) { + return 1; + } + + s1len = strlen(s1); + if ( s1len != strlen(s2) ) { + return 1; + } + + while ( *s1 != '\0' ) { + if ( *s1 != *s2 ) { + return 1; + } + s1 += sizeof(char); + s2 += sizeof(char); + } + + return 0; +} + +void repl(void) +{ + char keybuff[512]; + + while ( 1 ) { + puts("> "); + memset((void *)&keybuff, 0x00, 512); + if ( gets((char *)&keybuff) != NULL ) { + puts("\n"); + if ( strcmp(&keybuff, "quit") == 0 ) { + puts("You asked for it\n"); + #asm + hlt; + #endasm + + } else if ( strcmp(&keybuff, "reset") == 0 ) { + puts("Resetting PC ... "); + #asm + jmp 0xf000:0xfff0; + #endasm + + } else if ( strcmp(&keybuff, "help") == 0 ) { + puts("help : Show this help message\n"); + puts("quit : Halt the computer\n"); + puts("reset : Reset the PC\n"); + puts("\n"); + } else { + puts("Wat?\n"); + } + } + } +} + +void blankScreen(void) +{ + char i = 0; + char j = 0; + for ( i = 0 ; i < 26 ; i++ ) { + for ( j = 0; j < 81 ; j++ ) { + setCursorPosition(j, i); + putc(' '); + } + } +} + void main(void) { - //printString("Piquant Kernel v0.1\n"); - while(1); + blankScreen(); + setCursorPosition(0, 0); + puts("Piquant Kernel v0.1\n"); + puts("\n"); + repl(); }