summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-09 17:43:01 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-09 17:43:01 +0200
commit13e26c52945650293ccc5c6c31e1470f043d7d10 (patch)
tree7d0771bd8b609c85d146cc2aa04b98534423d731 /src
parentc5320e104bf9cf6f8ec897d5a2b6679d21885906 (diff)
downloadabaos-13e26c52945650293ccc5c6c31e1470f043d7d10.tar.gz
abaos-13e26c52945650293ccc5c6c31e1470f043d7d10.tar.bz2
fixed stage 1 boot loader problems (worked in some BIOSes across
the 2 times sector/track limit). loading sectors one by one now fixed also spin down problem after loading stage 2 and the kernel for now tested with 1.44 MB floppies (both real and in bochs/qemu)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile8
-rw-r--r--src/boot.asm6
-rw-r--r--src/stage1_functions.asm88
3 files changed, 76 insertions, 26 deletions
diff --git a/src/Makefile b/src/Makefile
index 615c3b6..24d0088 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -14,10 +14,14 @@ all: image.bin kernel.sym
# + 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 38)
+# then we make sure the image has the size of a 1.44 MB floppy
+# (emulators like qemu do some guess work for CHS resolution based
+# on the size of the image)
image.bin: boot.bin kernel.bin magic.bin
cat boot.bin kernel.bin > image.tmp
truncate -s 19456 image.tmp
cat image.tmp magic.bin > image.bin
+ truncate -s 1474560 image.bin
boot.bin: boot.asm boot_gdt.asm stage1_functions.asm stage2_functions.asm stage2_switch_mode.asm stage2_a20.asm
$(NASM) boot.asm -DMAGIC='"$(MAGIC)"' -f bin -o boot.bin
@@ -94,11 +98,11 @@ clean:
-rm -f boot.bin kernel.bin kernel.sym kernel.elf image.bin magic.bin *.o boot.map image.tmp
run-qemu: image.bin
- qemu-system-i386 -net nic,model=ne2k_pci -d guest_errors -m 32 -drive "file=image.bin,if=ide,format=raw" \
+ qemu-system-i386 -net nic,model=ne2k_pci -d guest_errors -m 32 -drive "file=image.bin,if=floppy,format=raw" \
-serial file:serial.log
run-qemu-debug: image.bin
- qemu-system-i386 -net nic,model=ne2k_pci -S -s -d guest_errors -m 32 -drive "file=image.bin,if=ide,format=raw" \
+ qemu-system-i386 -net nic,model=ne2k_pci -S -s -d guest_errors -m 32 -drive "file=image.bin,if=floppy,format=raw" \
-serial file:serial.log
run-bochs:
diff --git a/src/boot.asm b/src/boot.asm
index 9620fcc..3f9c127 100644
--- a/src/boot.asm
+++ b/src/boot.asm
@@ -44,6 +44,10 @@
; after the boot sector)
mov dl, [BOOT_DRIVE]
call read_from_disk
+ call print_newline
+
+; turn off disk motor
+ call kill_motor
; jump over variables and subroutines of stage 1 and execute stage 2
jmp stage2
@@ -63,7 +67,7 @@ MESSAGE_BOOT_DRIVE:
db "Booting from drive ", 0
MESSAGE_LOADING_STAGE_2:
- db "Loading stage 2 boot loader", 13, 10, 0
+ db "Loading stage 2 boot loader and kernel", 0
BOOT_DRIVE:
db 0
diff --git a/src/stage1_functions.asm b/src/stage1_functions.asm
index c9ed1a5..8a73a9b 100644
--- a/src/stage1_functions.asm
+++ b/src/stage1_functions.asm
@@ -4,20 +4,6 @@
; subtract 1 here!)
NOF_LOAD_SECTORS equ 38
-; IN bx: begin of memory area to dump
-; IN ax: number of words to dump
-dump_range:
- mov dx, bx
- call print_hex
- mov dx, [bx]
- call print_hex
- call print_newline
- add bx, 2
- dec ax
- cmp ax, 0
- jnz dump_range
- ret
-
; IN dx: hex value to print
print_hex:
push bx
@@ -104,25 +90,76 @@ current_row:
pop ax
ret
+; data sections used for reading from disk
+SECTORS_TO_LOAD:
+ db NOF_LOAD_SECTORS ; load NOF_LOAD_SECTORS sectors in total
+CURRENT_SECTOR:
+ db 2 ; second sector after boot sector
+CURRENT_CYLINDER:
+ db 0
+CURRENT_HEAD:
+ db 0
+
+; read the whole stage2 and kernel from the disk
; IN dl: drive to read from
read_from_disk:
- mov ah, 0x02 ; read sectors from drive
-
- mov al, NOF_LOAD_SECTORS ; read 1 sector
- mov ch, 0 ; select first cylinder
- mov dh, 0 ; first head
- mov cl, 2 ; second sector after boot sector
-
+
mov bx, 0 ; where to store the data
mov es, bx
mov bx, 0x7e00 ; 512 bytes after first sector
-
+
+.read_next_sector:
+
+ call read_one_sector_from_disk
+
+ sub [SECTORS_TO_LOAD], BYTE 1 ; one less to load
+ cmp [SECTORS_TO_LOAD], BYTE 0 ; finished?
+ je .finished
+
+ add bx, 0x200 ; advance write buffer position
+ add [CURRENT_SECTOR], BYTE 1 ; next sector
+ cmp [CURRENT_SECTOR], BYTE 0x13 ; assuming 18 sectors per track for now
+ je .next_head
+ jmp .read_next_sector
+
+.next_head:
+ mov [CURRENT_SECTOR], BYTE 1 ; start from first sector again
+ add [CURRENT_HEAD], BYTE 1 ; advance head
+ cmp [CURRENT_HEAD], BYTE 0x02 ; 2 heads on floppies
+ je .next_track
+ jmp .read_next_sector
+
+.next_track:
+ mov [CURRENT_HEAD], BYTE 0 ; start from head 0 again
+ add [CURRENT_CYLINDER], BYTE 1 ; advance track
+ jmp .read_next_sector
+
+.finished:
+ ret
+
+; Read one sector after the other, if we get illegal parameter
+; errors we assume we have gone over the limit of number of
+; sectors per cylinder. This avoids to probe for this number with
+; shacky BIOS functions or with probing (as LILO does). It's not
+; very efficient though..
+; IN dl: drive to read from
+read_one_sector_from_disk:
+ mov ah, 0x02 ; read sectors from drive
+
+ mov al, 1 ; read 1 sector
+ mov ch, BYTE [CURRENT_CYLINDER]
+ mov dh, BYTE [CURRENT_HEAD]
+ mov cl, BYTE [CURRENT_SECTOR]
+
int 0x13
jc .read_error
- cmp al, NOF_LOAD_SECTORS ; 1 sector read?
+ cmp al, 1 ; 1 sector read?
jne .short_read ; if not, short read
+
+ mov al, '.'
+ call print_char
ret
@@ -139,3 +176,8 @@ read_from_disk:
call print_string
jmp $
+kill_motor:
+ mov dx, 0x3F2
+ mov al, 0x00
+ out dx, al
+ ret