summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-05-11 22:10:07 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-05-11 22:10:07 +0200
commit30596991abc9e452fbad8372f1ddcce12b87ce72 (patch)
tree0268ad64556032ce19cddd43d3629e2bc1ea61db
parent356f485c9cb5f5aa94e39ad25e9e0345682db722 (diff)
downloadabaos-30596991abc9e452fbad8372f1ddcce12b87ce72.tar.gz
abaos-30596991abc9e452fbad8372f1ddcce12b87ce72.tar.bz2
better documentation for the boot loading process and how much
sectors each part needs, fixed truncation problem started a magic signature at the end of the image and started to check it in stage 2 of the boot loader to avoid truncated images in the future
-rw-r--r--doc/LINKS.TODO4
-rw-r--r--src/Makefile37
-rw-r--r--src/boot.asm51
-rw-r--r--src/magic.asm6
-rw-r--r--src/stage1_functions.asm5
-rw-r--r--src/stage2_functions.asm51
6 files changed, 120 insertions, 34 deletions
diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO
index 65e754f..f7a602e 100644
--- a/doc/LINKS.TODO
+++ b/doc/LINKS.TODO
@@ -4,3 +4,7 @@ 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
diff --git a/src/Makefile b/src/Makefile
index c983fb6..4e0755a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -4,30 +4,47 @@ LD := ld
all: image.bin
-image.bin: boot.bin kernel.bin
- cat boot.bin kernel.bin > image.bin
+image.bin: boot.bin kernel.bin magic.bin
+ cat boot.bin kernel.bin > image.tmp
# truncate to correct number of sectors, we have
- # 512 (boot, first stage) + N * 512 (N currenty is 3) + M * 512 (M is currently 3)
- truncate -s 4096 image.bin
+ # 512 (boot, stage 1) + N * 512 (N currenty is 3, stage 2) = 2048 for boot.bin
+ # + M * 512 (M is currently 7) = 3144 for kernel.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 10)
+ truncate -s 5632 image.tmp
+ cat image.tmp magic.bin > image.bin
boot.bin: boot.asm gdt.asm stage1_functions.asm stage2_functions.asm switch_mode.asm
nasm boot.asm -f bin -o boot.bin
-kernel.bin: kernel.o vga.o string.o
+kernel.bin: kernel.o vga.o port.o port_asm.o string.o stdlib.o
$(LD) -o kernel.bin -n -Ttext 0x8000 --oformat binary \
- kernel.o vga.o string.o
+ kernel.o vga.o port.o port_asm.o string.o stdlib.o
+magic.bin: magic.asm
+ nasm magic.asm -f bin -o magic.bin
+
kernel.o: kernel.c
- $(CC) $(CFLAGS) -O0 -c -o kernel.o kernel.c
+ $(CC) $(CFLAGS) -c -o kernel.o kernel.c
+
+port.o: port.c
+ $(CC) $(CFLAGS) -c -o port.o port.c
vga.o: vga.c
- $(CC) $(CFLAGS) -O0 -c -o vga.o vga.c
+ $(CC) $(CFLAGS) -c -o vga.o vga.c
+
+port_asm.o: port.asm
+ nasm port.asm -f elf32 -o port_asm.o
string.o: string.c
- $(CC) $(CFLAGS) -O0 -c -o string.o string.c
+ $(CC) $(CFLAGS) -c -o string.o string.c
+
+stdlib.o: stdlib.c
+ $(CC) $(CFLAGS) -c -o stdlib.o stdlib.c
clean:
- -rm -f boot.bin kernel.bin image.bin *.o
+ -rm -f boot.bin kernel.bin image.bin magic.bin *.o
run-qemu: image.bin
qemu-system-i386 -m 32 -drive "file=image.bin,if=ide,format=raw"
diff --git a/src/boot.asm b/src/boot.asm
index 631a99a..9b130a2 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -5,7 +5,10 @@
; 16-bit real-mode
[bits 16]
-
+
+; export a map of kernel symbols for debugging
+ [map symbols kernel.map]
+
; initialize segment registers
mov ax, 0
mov ds, ax
@@ -18,6 +21,8 @@
mov [BOOT_DRIVE], dl
; make sure we know the location of the stack by setting it on our own
+; this stack is only used in real mode in stage 1, so it's growing from
+; 0xffff down
mov bp, 0xFFFF
mov sp, bp
@@ -34,10 +39,13 @@
; print we are going to load stage 2 of the boot blocks
mov si, MESSAGE_LOADING_STAGE_2
call print_string
-
+
+; load stage 2 and the kernel together to 0x7e00 (directly
+; after the boot sector)
mov dl, [BOOT_DRIVE]
call read_from_disk
-
+
+; jump over variables and subroutines of stage 1 and execute stage 2
jmp stage2
%include "stage1_functions.asm"
@@ -67,13 +75,16 @@ times 510-($-$$) db 0
dw 0xaa55
stage2:
+; print a message that we are indeed in stage 2 now
mov si, MESSAGE_STAGE_2_LOADED
call print_string
-; remember current position on screen
+; remember current position on screen, otherwise we loose this
+; information after switching to protected mode
call current_row
mov [CURSOR_Y], dh
+; enter protected mode
call switch_to_protected_mode
; we should never get here, but just in case
@@ -88,43 +99,39 @@ MESSAGE_STAGE_2_LOADED:
BEGIN_PROTECTED_MODE:
- mov edx, 1
-_loop_test:
- mov si, MESSAGE_INITIALIZING
- call pm_print_string
- call pm_print_newline
- dec edx
- cmp edx, 0
- jnz _loop_test
-_end_of_test:
-
+; we switched to protected mode
mov si, MESSAGE_PROTECTED_MODE
call pm_print_string
call pm_print_newline
-
+
+; check sanity of kernel by searching for MAGIC string at a given
+; position
+ call check_magic
+
+; print a message before we call the C level kernel
mov si, MESSAGE_CALL_C_ENTRY
call pm_print_string
call pm_print_newline
; call our kernel
call c_entry
-
+
+; "kernel halted" message, when we terminate the C kernel
mov si, MESSAGE_HALTED
call pm_print_string
call pm_print_newline
; end of C, disable interupts again, NMIs can still happen
+; make sure we loop endlessly here but without burning too
+; much CPU
cli
_halt_loop:
hlt
jmp _halt_loop
-
+
MESSAGE_PROTECTED_MODE:
db "Switched to 32-bit Protected Mode", 0
-MESSAGE_INITIALIZING:
- db "Initializing the Foo machine..", 0
-
MESSAGE_CALL_C_ENTRY:
db "Calling C entry function", 0
@@ -133,7 +140,9 @@ MESSAGE_HALTED:
%include "stage2_functions.asm"
-; make sure we have full sectors
+; make sure we have full sectors, stage one is 512 bytes, so we
+; have to will up 3 sectors
times 2048-($-$$) db 0
+; position is 0x8400 now for the C entry
c_entry:
diff --git a/src/magic.asm b/src/magic.asm
new file mode 100644
index 0000000..c8c580e
--- /dev/null
+++ b/src/magic.asm
@@ -0,0 +1,6 @@
+; pad rest of sector with zeroes so we get 512 bytes in the end
+times 512-11-($-$$) db 0
+
+; the magic string we search for in stage 2 to ensure we don't read
+; a truncated kernel image
+db "ABAOSMAGIC", 0
diff --git a/src/stage1_functions.asm b/src/stage1_functions.asm
index b32d23d..c43da4d 100644
--- a/src/stage1_functions.asm
+++ b/src/stage1_functions.asm
@@ -1,9 +1,8 @@
; number of sectors to be read
-; this is 512 (the bootloader stage1) +
; 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 7
+NOF_LOAD_SECTORS equ 11
; IN bx: begin of memory area to dump
; IN ax: number of words to dump
@@ -19,7 +18,7 @@ dump_range:
jnz dump_range
ret
-; IN bx: hex value to print
+; IN dx: hex value to print
print_hex:
push bx
push si
diff --git a/src/stage2_functions.asm b/src/stage2_functions.asm
index 018cf6a..d692ed2 100644
--- a/src/stage2_functions.asm
+++ b/src/stage2_functions.asm
@@ -55,6 +55,34 @@ pm_print_char:
call inc_cursor
ret
+; IN dx: hex value to print
+pm_print_hex:
+ push bx
+ push si
+ mov si, HEX_TEMPLATE
+ mov bx, dx
+ shr bx, 12
+ mov bx, [HEXABET+bx]
+ mov [HEX_TEMPLATE+2], bl
+ mov bx, dx
+ and bx, 0x0FFF
+ shr bx, 8
+ mov bx, [HEXABET+bx]
+ mov [HEX_TEMPLATE+3], bl
+ mov bx, dx
+ and bx, 0x00FF
+ shr bx, 4
+ mov bx, [HEXABET+bx]
+ mov [HEX_TEMPLATE+4], bl
+ mov bx, dx
+ and bx, 0x000F
+ mov bx, [HEXABET+bx]
+ mov [HEX_TEMPLATE+5], bl
+ call pm_print_string
+ pop si
+ pop bx
+ ret
+
inc_cursor:
push eax
mov ax, [CURSOR_X]
@@ -106,3 +134,26 @@ update_vga_cursor:
pop ecx
pop ebx
ret
+
+check_magic:
+ push eax
+ push ebx
+ push ecx
+ push edx
+ push esi
+ mov eax, NOF_LOAD_SECTORS ; number of 512-byte sectors
+ shl eax, 9 ; 512 bytes per sector
+ mov ecx, 0x7e00 ; offset of stage 2
+ add ecx, eax
+ sub ecx, 11 ; the length of the magic string
+ mov dx, cx
+ call pm_print_hex
+ mov dx, [ecx]
+ call pm_print_hex
+ call pm_print_newline
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ ret