summaryrefslogtreecommitdiff
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
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)
-rw-r--r--BUGS7
-rw-r--r--doc/LINKS.TODO3
-rw-r--r--doc/README.DISK_GEOMETRY70
-rw-r--r--src/Makefile8
-rw-r--r--src/boot.asm6
-rw-r--r--src/stage1_functions.asm88
6 files changed, 150 insertions, 32 deletions
diff --git a/BUGS b/BUGS
index 69b9a8d..6afbc5b 100644
--- a/BUGS
+++ b/BUGS
@@ -1,9 +1,4 @@
-- on AMD-K5 machine, bootloader results in DISK ERROR 0x0004
- (too many sectors read in one row?)
- PS/2 answers with ERROR if PS/2 mouse is not connected,
read_ack should handle error cases correctly. We should
- also probe correctly for the mouse.
-- floppy drive doesn't spin down after reading stage2 and
- kernel from floppy. Do we have to call 0x13, 0x00 reset
- drive?
+ also probe correctly for the mouse. (0xFE on all commands)
diff --git a/doc/LINKS.TODO b/doc/LINKS.TODO
index d58cc0d..81e0466 100644
--- a/doc/LINKS.TODO
+++ b/doc/LINKS.TODO
@@ -67,6 +67,9 @@ http://www.sci.muni.cz/docs/pc/serport.txt
Boot:
https://www.cs.cmu.edu/~410-s07/p4/p4-boot.pdf
+http://www.osdever.net/tutorials/view/loading-sectors
+http://www.osdever.net/tutorials/view/lba-to-chs
+LILO boot loader
C:
http://www.drdobbs.com/extending-c-for-object-oriented-programm/184402731
diff --git a/doc/README.DISK_GEOMETRY b/doc/README.DISK_GEOMETRY
new file mode 100644
index 0000000..54f6092
--- /dev/null
+++ b/doc/README.DISK_GEOMETRY
@@ -0,0 +1,70 @@
+This affects the boot loader in stage 1 using
+BIOS functions to read stage 2 and the kernel
+
+Geometry Specification
+
+
+360 KB 5.25"
+
+
+1.2 MB 5.25"
+
+
+720 KB 3.5"
+
+
+1.44 MB 3.5"
+
+
+2.88 MB 3.5"
+
+Tracks (Cylinders)
+
+
+40
+
+
+80
+
+
+80
+
+
+80
+
+
+80
+
+Sectors Per Track/Cylinder
+
+
+9
+
+
+15
+
+
+9
+
+
+18
+
+
+36
+
+Total Sectors Per Disk
+
+
+720
+
+
+2,400
+
+
+1,440
+
+
+2,880
+
+
+5,760
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