From 501dc2d044ddb43c4b8d58b4ce330bfc076de446 Mon Sep 17 00:00:00 2001 From: manasghandat Date: Thu, 6 Apr 2023 18:07:14 +0530 Subject: [PATCH] Add disk read features and bochs support --- Makefile | 4 +- bochs_config | 7 ++ debug.sh | 1 + run.sh | 2 +- src/bootloader/boot.asm | 156 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 bochs_config create mode 100755 debug.sh diff --git a/Makefile b/Makefile index 8f52cee..73e9fe8 100644 --- a/Makefile +++ b/Makefile @@ -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 @@ -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 diff --git a/bochs_config b/bochs_config new file mode 100644 index 0000000..404b304 --- /dev/null +++ b/bochs_config @@ -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" \ No newline at end of file diff --git a/debug.sh b/debug.sh new file mode 100755 index 0000000..eef588c --- /dev/null +++ b/debug.sh @@ -0,0 +1 @@ +bochs -f bochs_config \ No newline at end of file diff --git a/run.sh b/run.sh index afca7b9..d50506a 100755 --- a/run.sh +++ b/run.sh @@ -1,2 +1,2 @@ qemu-system-i386 \ - -fda build/main_floppy.img \ No newline at end of file + -fda ./build/main_floppy.img \ No newline at end of file diff --git a/src/bootloader/boot.asm b/src/bootloader/boot.asm index da4ce00..06a3b64 100644 --- a/src/bootloader/boot.asm +++ b/src/bootloader/boot.asm @@ -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 @@ -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 \ No newline at end of file