From eea5bf4b859eb56c5772c58ca54937a90a10e7ee Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 10 Jun 2017 20:55:56 +0200 Subject: moved bootloader to subdirectory --- src/boot/stage2_real_functions.asm | 169 +++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 src/boot/stage2_real_functions.asm (limited to 'src/boot/stage2_real_functions.asm') diff --git a/src/boot/stage2_real_functions.asm b/src/boot/stage2_real_functions.asm new file mode 100644 index 0000000..d49bfce --- /dev/null +++ b/src/boot/stage2_real_functions.asm @@ -0,0 +1,169 @@ +; number of sectors to be read for the kernel itself +; (note: the first sector gets loaded by the BIOS, the +; next 3 sectors are read by the simple stage 1 loader, +; so subtract 3 here!) +NOF_LOAD_SECTORS equ 37 + +; data sections used for reading the kernel from disk +SECTORS_PER_CYLINDER: + db 0x3F ; detect parameters enters the correct value here (sectors + 1) + ; if detection fails, force int13 to read ahead +NOF_HEADS: + db 0x01 ; number of heads + 1 +SECTORS_TO_LOAD: + db NOF_LOAD_SECTORS ; load NOF_LOAD_SECTORS sectors in total +CURRENT_SECTOR: + db 5 ; first sector after stage 2 +CURRENT_CYLINDER: + db 0 +CURRENT_HEAD: + db 0 + +; detect disk geometry +; IN dl: drive +detect_disk_geometry: + mov dx, 0 + mov es, dx + mov ah, 0x08 + int 0x13 + jc .error + jmp .ok + +.error: + mov si, DISK_ERROR + call print_string + mov dh, 0 + mov dl, ah + call print_hex + ret + +.ok: + add dh, 1 + mov [NOF_HEADS], BYTE dh + call print_hex + mov dx, cx + call print_hex + and cl, 0x3F + add cl, 1 + mov [SECTORS_PER_CYLINDER], BYTE cl + ret + +probe_and_fix_disk_geometry: + mov cl, 0x1 ; from 1 to 63 + mov BYTE [SECTORS_PER_CYLINDER], cl + +.loop: + mov dl, [BOOT_DRIVE] + mov ah, 0x02 ; read sectors from drive + mov al, 1 ; read 1 sector + mov cl, BYTE [SECTORS_PER_CYLINDER] + mov ch, BYTE 0 + mov dh, BYTE 0 + + int 0x13 + + jnc .next_sector ; on error, remeber cl being the highest sector + +.fix_heads: + cmp [NOF_HEADS], BYTE 0 ; 0 heads, the BIOS is playing tricks to us! + je .illegal_heads + jmp .end + +.illegal_heads: + mov [NOF_HEADS], BYTE 1 + jmp .end + +.next_sector: + mov cl, BYTE [SECTORS_PER_CYLINDER] + inc cl ; next sector + mov BYTE [SECTORS_PER_CYLINDER], cl + cmp cl, 0x40 ; to a max of 63, if so, this is the default + jbe .loop + jmp .fix_heads + +.end: + ret + +; read the whole stage2 and kernel from the disk +; IN dl: drive to read from +read_from_disk: + + mov bx, 0 ; where to store the data + mov es, bx + mov bx, 0x8400 ; 2'048 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 + mov ch, [SECTORS_PER_CYLINDER] + cmp [CURRENT_SECTOR], ch ; after the end of the current track? + 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 + mov ch, [NOF_HEADS] + cmp [CURRENT_HEAD], ch ; after the number of heads? + 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, 1 ; 1 sector read? + jne .short_read ; if not, short read + + mov al, '.' + call print_char + + ret + +.read_error: + mov si, DISK_ERROR + call print_string + mov dh, 0 + mov dl, ah + call print_hex + jmp $ + +.short_read: + mov si, SHORT_READ + call print_string + jmp $ + +kill_motor: + mov dx, 0x3F2 + mov al, 0x00 + out dx, al + ret -- cgit v1.2.3-54-g00ecf