C kernel runs now after fixing bootloader and build, beginnings of a REPL

This commit is contained in:
2015-01-25 17:46:12 -08:00
parent 5e4513dd22
commit f6e2d0c19b
4 changed files with 267 additions and 30 deletions

View File

@@ -1,15 +1,15 @@
all: boot.img kernel.bin all: boot.img kernel.bin
src/%.o: src/%.c src/%.o: src/%.c
bcc -ansi -3 -c -o $@ $< bcc -ansi -0 -c -o $@ $<
kernel.bin: src/kernel.o kernel.bin: src/kernel.o
ld86 -T0x1000 -M -o $@ $^ ld86 -d -M -o $@ $^ | tee ld86.out
asm/kernel_syms.S: kernel.bin asm/kernel_syms.S: kernel.bin
objdump86 kernel.bin | \ cat ld86.out | \
grep -E "^[0-9]+ T _.*" | \ 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.split(' ')[2].strip('\n'), int(x.split(' ')[0].lstrip('0'), 16)-0x1000) for x in sys.stdin.readlines()])" > asm/kernel_syms.S 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 boot.bin: asm/kernel_syms.S asm/bootloader.S asm/bootloader.S
cd asm && nasm bootloader.S -f bin -o ../$@ cd asm && nasm bootloader.S -f bin -o ../$@
@@ -18,7 +18,10 @@ asm/%.o: asm/%.S
nasm $< -f as86 -o $@ nasm $< -f as86 -o $@
boot.img: boot.bin kernel.bin 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 test: boot.img
bochs -f bochsrc -q bochs -f bochsrc -q

View File

@@ -2,6 +2,10 @@
[org 0x7C00] ; Origin at 0x7C00 (upper end of memory) [org 0x7C00] ; Origin at 0x7C00 (upper end of memory)
start: 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 call blankScreen
mov dx, 0x0 mov dx, 0x0
@@ -13,10 +17,10 @@ start:
mov dl, 0x0 mov dl, 0x0
call setCursorPosition 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 ch, 0x0 ; .... on track 0 ....
mov cl, 0x2 ; .... starting at sector 2 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 es, bx
mov bx, 0x0 ; bx = 0, es:bx = 0x1000:0 mov bx, 0x0 ; bx = 0, es:bx = 0x1000:0
call loadFloppyDiskSectors call loadFloppyDiskSectors
@@ -58,6 +62,11 @@ _end_floppy_read:
call setCursorPosition call setCursorPosition
mov si, _str_floppydone mov si, _str_floppydone
call printString call printString
mov ax, 0x1000
mov ds, ax
mov ax, 0x1000
mov ss, ax
mov sp, 0xFFFF
jmp _extern_c_main jmp _extern_c_main
%include "libinterrupt.S" %include "libinterrupt.S"
@@ -69,4 +78,3 @@ _end_floppy_read:
times 510 - ($ - $$) db 0 ; fill up to 510 bytes with 0 times 510 - ($ - $$) db 0 ; fill up to 510 bytes with 0
dw 0xAA55 ; magic bootloader signature dw 0xAA55 ; magic bootloader signature

View File

@@ -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: _extern_c_main:
jmp 0x1000:0x0049 jmp 0x1000:0x0412
_extern_c_printCh: _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 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

View File

@@ -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 #asm
#if !__FIRST_ARG_IN_AX__ push bx;
mov bx, sp mov bx, sp;
#endif mov dl, [bx+4];
#if __FIRST_ARG_IN_AX__ mov dh, [bx+6];
mov si, ax pop bx;
#else push ax;
mov si, [bx+2] push bx;
#endif mov ah, #0x02;
mov ah, 0x0e mov bx, #0x0;
mov bh, 0x00 int 0x10;
mov bl, 0x07 pop bx;
int 0x10 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 #endasm
return; return;
} }
void printString(char *ptr) int strlen(char *ptr)
{ {
while ((char)*ptr != '\0') { char *ptr2 = ptr;
printChar((char)*ptr); if ( ptr == NULL ) {
ptr++; 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; 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) void main(void)
{ {
//printString("Piquant Kernel v0.1\n"); blankScreen();
while(1); setCursorPosition(0, 0);
puts("Piquant Kernel v0.1\n");
puts("\n");
repl();
} }