Skip to content

Commit

Permalink
Add disk read features and bochs support
Browse files Browse the repository at this point in the history
  • Loading branch information
manasghandat committed Apr 6, 2023
1 parent 77fa2a4 commit 501dc2d
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 3 deletions.
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ BUILD_DIR = build
# Floppy image
#
floppy_image: $(BUILD_DIR)/main_floppy.img
$(BUILD_DIR)/main_floppy.img: bootloader kernel
dd if=/dev/zero of=$(BUILD_DIR)/main_floppy.img bs=512 count=2880
mkfs.fat -F 12 -n "NBOS" $(BUILD_DIR)/main_floppy.img
dd if=$(BUILD_DIR)/bootloader.bin of=$(BUILD_DIR)/main_floppy.img conv=notrunc
Expand All @@ -19,7 +20,8 @@ floppy_image: $(BUILD_DIR)/main_floppy.img
#

bootloader: $(BUILD_DIR)/bootloader.bin
$(BUILD_DIR)/bootloader.bin: always

$(BUILD_DIR)/bootloader.bin: always
$(ASM) $(SRC_DIR)/bootloader/boot.asm -f bin -o $(BUILD_DIR)/bootloader.bin


Expand Down
7 changes: 7 additions & 0 deletions bochs_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
megs: 128
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xfffe0000
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest,
floppya: 1_44=build/main_floppy.img, status=inserted
boot: floppya
mouse: enabled=0
display_library: sdl, options="gui_debug"
1 change: 1 addition & 0 deletions debug.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bochs -f bochs_config
2 changes: 1 addition & 1 deletion run.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
qemu-system-i386 \
-fda build/main_floppy.img
-fda ./build/main_floppy.img
156 changes: 155 additions & 1 deletion src/bootloader/boot.asm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,34 @@ bits 16

%define ENDL 0x0D,0x0A

;
; FAT12 header record
;

jmp short start
nop

bdb_oem: db 'MSWIN4.1'
bdb_bytes_per_sector: dw 512
bdb_sectors_per_cluster: db 1
bdb_reserved_sectors: dw 1
bdb_fat_count: db 2
bdb_dir_entries_count: dw 0E0h
bdb_total_sectors: dw 2880
bdb_media_descriptor_type: db 0F0h
bdb_sectors_per_fat: dw 9
bdb_sectors_per_track: dw 18
bdb_heads: dw 2
bdb_hidden_sectors: dd 0
bdb_large_sector_count: dd 0

ebr_drive_number: db 0
db 0
ebr_signature: db 0x29
ebr_volume_id: db 0x01,0x02,0x03,0x04
ebr_volume_label: db 'InfoSecIITR'
ebr_system_id: db 'FAT12 '

start:
jmp main

Expand Down Expand Up @@ -40,15 +68,141 @@ main:
; Setup the program stack
mov ss, ax
mov sp, 0x7C00

; Read something from floppy disk
; BIOS should set `dl` to drive number
mov [ebr_drive_number], dl

mov ax, 1 ; LBA = 1, second sector from disk
mov cl, 1 ; 1 sector to read
mov bx, 7E00h ; data should be after the bootloader
call disk_read

; Print the boot message
mov si, msg_boot
call puts

hlt

floppy_error:
mov si, msg_read_fail
call puts
jmp wait_key_and_reboot

wait_key_and_reboot:
mov ah, 0
int 016h ; wait for key press

jmp 0FFFFh:0 ; jump to the beginning of bios.
; This will reboot the system

hlt

.halt:
jmp .halt
cli ; disable interrupts
; THis way CPU cant get out of halt state
hlt

; Converts an LBA address to CHS address
; Parameters:
; - ax : LBA address
; Returns:
; - cx [0-5] : sector number
; - cx [6-15]: cyliinder
; - dh : head

lba_to_chs:

push ax
push dx

xor dx, dx
div word [bdb_sectors_per_track] ; `ax` = lba / sectors per track
; `dx` = lba % sectors per track
inc dx ; `dx` = lba % sectors per track + 1 = sector
mv cx, dx

xor dx, dx
div word [bdb_heads] ; `ax` = (lba / sectors per track) / heads
; `dx` = (lba / sectors per track) % heads
mov dh, dl
mov ch, al
shl ah, 06
or cl, ah

pop ax
mov dl, al
pop ax


; Reads sectors from disk
; Parameters:
; - ax : LBA address
; - cl : number of sectors to read
; - dl : drive number
; - es:bx : memory address where to store read data

disk_read:

push ax ; Save registers on the stack
push bx
push cx
push dx
push di

push cx ; save `cl` -> number of sectors per thread
call lba_to_chs
pop ax ; number of sectors per thread
mov ah, 02h
mov di, 3 ; loop count variable

; floppy being unreliable the call may not always be sucessful.
; Hence operations are performed multiple times.
.retry:
pusha ; push all registers on stack
stc ; store carry flag
int 013h ; if the call is sucessful carry flag is set to 0
jnc .done ; jmp if call not succeful

popa
call disk_reset

dec di
test di, di
jnz .retry

; If operation failed every time
.fail:
jmp floppy_error

.done:
popa

push di
push dx
push cx
push bx
push ax ; restore modified registers
ret
;
; Resets disk controller
; Parameters:
; -dl : drive number
;
disk_reset:
pusha
mov ah, 0
stc
int 13h
jc floppy_error
popa
ret

msg_boot: db "Hello World!",ENDL,0
msg_read_fail: db "Read from disk failed",ENDL,0

times 510-($-$$) db 0
dw 0AA55h

0 comments on commit 501dc2d

Please sign in to comment.