I am trying to write a bootloader and a kernel in an assembly for training. When I compile my code and boot the virtual machine with it, the bootloader seems to work correctly, but the kernel never starts. I think I am retelling the wrong instruction, but I donβt know what corrections I need to make in order to solve my problem. It is also likely that I am trying to make a floppy disk incorrectly, but I do not think this is a problem. When I look at image files in a hex editor, it seems that they were added correctly. Another reason might be reading the wrong sector from the floppy disk. I am trying to get the kernel to be turned on and read from the sector right after the bootloader.
To create and run this code, I do the following in Windows Vista x64:
nasm bootloader_2.asm -f bin -o bootloader_2.bin nasm kernel_2.asm -f bin -o kernel.bin partcopy bootloader_2.bin bootloader_2.img 0d 511d partcopy kernel_2.bin kernel_2.img 0d 511d copy bootloader.img /b + kernel.img POS_2.img
Then I use Virtual VM Virtual Box to mount POS_2.img as a floppy drive and run it on the guest system.
results
The Patrick bootloader started. Floppy was reset. Reading kernel Loaded kernel sector
. And the kernel never starts.
Here is my code
bootloader_2.asm
bits 16 org 0x7C00 boot: jmp loader ; OEM Parameter block / BIOS Parameter block (wtf is this for?) times 0Bh-$+boot DB 0 bpbBytesPerSector: DW 512 bpbSectorsPerCluster: DB 1 bpbReservedSectors: DW 1 bpbNumberOfFATs: DB 2 bpbRootEntries: DW 224 bpbTotalSectors: DW 2880 bpbMedia: DB 0xF0 bpbSectorsPerFAT: DW 9 bpbSectorsPerTrack: DW 18 bpbHeadsPerCylinder: DW 2 bpbHiddenSectors: DD 0 bpbTotalSectorsBig: DD 0 bsDriveNumber: DB 0 bsUnused: DB 0 bsExtBootSignature: DB 0x29 bsSerialNumber: DD 0xa0a1a2a3 bsVolumeLabel: DB "MOS FLOPPY" bsFileSystem: DB "FAT12" ; END PARAMETER BLOCK ; ----- Variables ----- started db "Patrick Bootloader Started...", 0x0D, 0x0A, 0 floppy_reset_done db "Floppy has been reset.", 0x0D, 0x0A, 0 loading_msg db "Reading Kernel Sector", 0x0D, 0x0A, 0 loading_sucess db "Kernel Sector Loaded", 0x0D, 0x0A, 0 done db "Bootloader Done.", 0x0D, 0x0A, 0 ; ----- End Variables ----- ; ----- Calls ----- reset_floppy: mov ah, 0 mov dl, 0 int 0x13 jc reset_floppy mov si, floppy_reset_done call print_string ret read_kernel: mov si, loading_msg call print_string mov si, 0x0 mov ax, 0x1000 ; setting up the address to read into mov es, ax ; moving the value in to es xor bx, bx ; clearing bx mov ah, 0x02 ; floppy function mov al, 1 ; read 1 sector mov ch, 1 ; track mov cl, 2 ; sector to read mov dh, 0 ; head number mov dl, 0 ; drive number int 0x13 ; BIOS Interrupt Call jc read_kernel mov si, loading_sucess call print_string ret print_string: lodsb or al, al jz .done mov ah, 0x0E int 0x10 jmp print_string .done: ret ; input is ax, cx is destroyed print_hex: mov cx, 4 .next_digit: push cx mov cl, 4 rol ax, cl push ax and al, 0x0F add al, '0' cmp al, '9' jle .not_a_leter add al, 'A'-'9'-1 .not_a_leter: mov ah, 0x0E int 0x10 pop ax pop cx loop .next_digit ret ; ----- End of Calls ----- ; ===== Bootloader Main ===== loader: mov si, started call print_string call reset_floppy call read_kernel jmp 0x1000:0x0 mov si, done ; never reached. Intentional for debugging call print_string ; these lines failure to produce a result tell us that the jmp was attempted ; ===== End of Bootloader Main ===== times 510-($-$$) db 0 dw 0xAA55
kernel_2.asm
kernel: jmp k_main welcome_msg db "Welcome to Patrick Operating System!", 0x0D, 0x0A, 0 print_string: lodsb or al, al jz .done mov ah, 0x0E int 0x10 jmp print_string .done: ret k_main: mov si, welcome_msg call print_string .k_main_loop: jmp .k_main_loop cli hlt times 512-($-$$) db 0