From 07f029b4b7d3d6d8e5fb4dfc1198b6ae6880fb56 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Wed, 17 May 2017 17:58:46 +0200 Subject: better magic signature detection (using a compile stamp with date and time) using local labels where possible, some renames in assembly code added a console_put_hex and serial_put_hex better call to qemu printing the status of the host when crashing the emulator --- doc/LINKS.TODO | 7 ++++++- src/Makefile | 6 +++--- src/boot.asm | 8 ++++---- src/console.c | 11 +++++++++++ src/console.h | 1 + src/kernel.c | 11 ++++++++--- src/magic.asm | 9 +++++++-- src/serial.c | 10 ++++++++++ src/serial.h | 1 + src/stage1_functions.asm | 18 +++++++++--------- src/stage2_functions.asm | 31 ++++++++++++++++--------------- src/vga.c | 2 +- 12 files changed, 77 insertions(+), 38 deletions(-) diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO index a65d4ea..b565fed 100644 --- a/doc/LINKS.TODO +++ b/doc/LINKS.TODO @@ -4,7 +4,6 @@ http://wiki.osdev.org/Linker_Scripts http://wiki.osdev.org/Printing_To_Screen http://wiki.osdev.org/Exceptions#General_Protection_Fault https://en.wikipedia.org/wiki/X86_calling_conventions -https://github.com/FlingOS/FlingOS http://repo.or.cz/w/lightOS.git https://littleosbook.github.io/ http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html @@ -12,3 +11,9 @@ http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html http://x86.renejeschke.de/html/file_module_x86_id_139.html http://retired.beyondlogic.org/serial/serial1.htm https://pdos.csail.mit.edu/6.828/2014/reference.html + +In C#: +https://github.com/FlingOS/FlingOS + +In Rust: +http://os.phil-opp.com/ diff --git a/src/Makefile b/src/Makefile index c2b91fa..7f5f162 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,7 +12,7 @@ image.bin: boot.bin kernel.bin magic.bin # + 1 * 512 = 512 for magic.bin # (M + N + 1 is the number of sectors to be read in stage 2, as stage 1 # loads only the first sector, so adapt NOF_LOAD_SECTORS to 12) - truncate -s 6656 image.tmp + truncate -s 7168 image.tmp cat image.tmp magic.bin > image.bin boot.bin: boot.asm gdt.asm stage1_functions.asm stage2_functions.asm switch_mode.asm @@ -51,10 +51,10 @@ stdlib.o: stdlib.c stdlib.h $(CC) $(CFLAGS) -c -o stdlib.o stdlib.c clean: - -rm -f boot.bin kernel.bin image.bin magic.bin *.o kernel.map image.tmp + -rm -f boot.bin kernel.bin image.bin magic.bin *.o boot.map image.tmp run-qemu: image.bin - qemu-system-i386 -m 32 -drive "file=image.bin,if=ide,format=raw" \ + qemu-system-i386 -d guest_errors -m 32 -drive "file=image.bin,if=ide,format=raw" \ -serial file:serial.log run-bochs: diff --git a/src/boot.asm b/src/boot.asm index 3257a56..8fb5d8a 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -6,8 +6,8 @@ ; 16-bit real-mode [bits 16] -; export a map of kernel symbols for debugging - [map symbols kernel.map] +; export a map of boot loader symbols for debugging + [map symbols boot.map] ; initialize segment registers mov ax, 0 @@ -131,9 +131,9 @@ HALT_OS: ; make sure we loop endlessly here but without burning too ; much CPU cli -_halt_loop: +.loop: hlt - jmp _halt_loop + jmp .loop MESSAGE_PROTECTED_MODE: db "Switched to 32-bit Protected Mode", 0 diff --git a/src/console.c b/src/console.c index ef4c36f..ea57d07 100644 --- a/src/console.c +++ b/src/console.c @@ -43,6 +43,17 @@ void console_put_string( console_t *console, const char *s ) } } +void console_put_hex( console_t *console, const uint32_t v ) +{ + if( console->vga != NULL ) { + vga_put_hex( console->vga, v ); + } + + if( console->serial != NULL ) { + serial_put_hex( console->serial, v ); + } +} + void console_put_newline( console_t *console ) { if( console->vga != NULL ) { diff --git a/src/console.h b/src/console.h index a792e0d..e922b98 100644 --- a/src/console.h +++ b/src/console.h @@ -14,6 +14,7 @@ void console_add_vga_output( console_t *console, vga_t *vga ); void console_add_serial_output( console_t *console, serial_t *serial ); void console_put_char( console_t *console, const char c ); void console_put_string( console_t *console, const char *s ); +void console_put_hex( console_t *console, const uint32_t v ); void console_put_newline( console_t *console ); #endif // CONSOLE_H diff --git a/src/kernel.c b/src/kernel.c index 2cbe40a..69a3870 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -3,6 +3,7 @@ #include "vga.h" #include "serial.h" #include "console.h" +#include "stdlib.h" void entry( void ) { @@ -11,14 +12,17 @@ void entry( void ) vga_t vga; vga_init( &vga ); + vga_set_color( &vga, VGA_COLOR_LIGHT_GREY ); + vga_set_background_color( &vga, VGA_COLOR_BLACK ); console_t console; console_init( &console ); console_add_vga_output( &console, &vga ); console_add_serial_output( &console, &serial ); - - vga_set_color( &vga, VGA_COLOR_LIGHT_GREY ); - vga_set_background_color( &vga, VGA_COLOR_BLACK ); + +// for IDT testing +// int y = 0; +// int x = 12 / y; console_put_string( &console, "Initializing hardware" ); @@ -43,6 +47,7 @@ void entry( void ) console_put_string( &console, "Terminating" ); console_put_newline( &console ); + //~ vga_set_color( &vga, VGA_COLOR_WHITE ); //~ vga_set_background_color( &vga, VGA_COLOR_RED ); diff --git a/src/magic.asm b/src/magic.asm index c8c580e..56f16c5 100644 --- a/src/magic.asm +++ b/src/magic.asm @@ -1,6 +1,11 @@ ; pad rest of sector with zeroes so we get 512 bytes in the end -times 512-11-($-$$) db 0 +times 512-31-($-$$) db 0 ; the magic string we search for in stage 2 to ensure we don't read ; a truncated kernel image -db "ABAOSMAGIC", 0 +; we make it unique per compilation to avoid funny problems if +; the size of the image differs between compilation stpes and the +; host system doens't initialize or randomize the RAM. +; __UTC_DATE_NUM__ is YYYY-MM-DD +; __UTC_TIME_NUM__ is HH:mm:SS +db "ABAOSMAGIC ", __UTC_DATE__, " ", __UTC_TIME__, 0 diff --git a/src/serial.c b/src/serial.c index c67f765..0ca3063 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,5 +1,6 @@ #include "serial.h" #include "string.h" +#include "stdlib.h" void serial_init( serial_t *serial ) { @@ -26,6 +27,15 @@ void serial_put_string( serial_t *serial, const char *s ) } } +void serial_put_hex( serial_t *serial, const uint32_t v ) +{ + char buf[19]; + + serial_put_string( serial, "0x" ); + itoa( v, (char *)buf, 16 ); + serial_put_string( serial, (const char *)buf ); +} + void serial_put_newline( serial_t *serial ) { serial_put_char( serial, '\n' ); diff --git a/src/serial.h b/src/serial.h index 4f665b2..f50a62d 100644 --- a/src/serial.h +++ b/src/serial.h @@ -11,6 +11,7 @@ typedef struct serial_t { void serial_init( serial_t *serial ); void serial_put_char( serial_t *serial, const char c ); void serial_put_string( serial_t *serial, const char *s ); +void serial_put_hex( serial_t *serial, const uint32_t v ); void serial_put_newline( serial_t *serial ); #endif // SERIAL_H diff --git a/src/stage1_functions.asm b/src/stage1_functions.asm index 854b3b4..6a145f6 100644 --- a/src/stage1_functions.asm +++ b/src/stage1_functions.asm @@ -2,7 +2,7 @@ ; 3 * 512 for bootloader stage2 and the kernel code ; (note: the first sector gets loaded by the BIOS, so ; subtract 1 here!) -NOF_LOAD_SECTORS equ 13 +NOF_LOAD_SECTORS equ 14 ; IN bx: begin of memory area to dump ; IN ax: number of words to dump @@ -64,13 +64,13 @@ print_newline: ; IN si print_string: push ax -_loop_print_string: +.loop: lodsb cmp al, 0 - je print_string_fini + je .fini call print_char - jmp _loop_print_string -print_string_fini: + jmp .loop +.fini: pop ax ret @@ -120,14 +120,14 @@ read_from_disk: int 0x13 - jc read_error + jc .read_error cmp al, NOF_LOAD_SECTORS ; 1 sector read? - jne short_read ; if not, short read + jne .short_read ; if not, short read ret -read_error: +.read_error: mov si, DISK_ERROR call print_string mov dh, 0 @@ -135,7 +135,7 @@ read_error: call print_hex jmp $ -short_read: +.short_read: mov si, SHORT_READ call print_string jmp $ diff --git a/src/stage2_functions.asm b/src/stage2_functions.asm index 2954d62..61a574c 100644 --- a/src/stage2_functions.asm +++ b/src/stage2_functions.asm @@ -22,13 +22,13 @@ pm_print_newline: ; IN si pm_print_string: push eax -_loop_pm_print_string: +.loop: lodsb cmp al, 0 - je pm_print_string_fini + je .fini call pm_print_char - jmp _loop_pm_print_string -pm_print_string_fini: + jmp .loop +.fini: pop eax ret @@ -89,16 +89,16 @@ inc_cursor: inc ax mov [CURSOR_X], ax cmp ax, VIDEO_COLS - jl inc_cursor_fini + jl .fini mov [CURSOR_X], word 1 mov ax, [CURSOR_Y] inc ax mov [CURSOR_Y], ax cmp ax, VIDEO_ROWS - jl inc_cursor_fini + jl .fini ; TODO: scoll one line, for now restart on top mov [CURSOR_Y], word 0 -inc_cursor_fini: +.fini: call update_vga_cursor pop eax ret @@ -184,23 +184,24 @@ check_magic: sub edx, MAGICLEN ; subtract the length of the magic string mov esi, edx ; now use edx as first string address to compare to mov edi, COMPARE_MAGIC ; position of second string - mov ecx, MAGICLEN ; length of the magic string + mov ecx, MAGICLEN-2 ; length of the magic string, we can have a second + ; (one digit) tolerance when comparing repe cmpsb - jne MAGIC_MISMATCH - jmp MAGIC_OK -MAGIC_MISMATCH: + jne .ok + jmp .mismatch +.ok: mov si, MAGIC_OK_MSG call pm_print_string call pm_print_newline xor eax, eax - jmp MAGIC_END -MAGIC_OK: + jmp .end +.mismatch: mov si, MAGIC_NOT_OK_MSG call pm_print_string call pm_print_newline xor eax, eax mov eax, 1 -MAGIC_END: +.end: pop edi pop esi pop edx @@ -209,7 +210,7 @@ MAGIC_END: ret COMPARE_MAGIC: -db "ABAOSMAGIC", 0 +db "ABAOSMAGIC ", __UTC_DATE__, " ", __UTC_TIME__, 0 MAGICLEN equ $ - COMPARE_MAGIC MAGIC_NOT_OK_MSG: diff --git a/src/vga.c b/src/vga.c index 498bb20..aba3564 100644 --- a/src/vga.c +++ b/src/vga.c @@ -188,7 +188,7 @@ void vga_put_string( vga_t *vga, const char *s ) void vga_put_hex( vga_t *vga, const uint32_t v ) { - char buf[9]; + char buf[19]; vga_put_string( vga, "0x" ); itoa( v, (char *)buf, 16 ); -- cgit v1.2.3-54-g00ecf