I wrote a boot code that print some stuff on the screen then relocate itself and load the next boot code (VBR). I tested the code on virtual machine using vmware and it's working as it should, I see the right output from the vbr code. Click here to see the output of the code.
I want to be able to debug my code and since vmware doesn't have this feature, I want to use bochs which can be used with IDA. After running the code on bochs, I got the error:
>>PANIC<< IO write(0x01f0): current command is 20h
The error occurred after calling the interrupt that handles extended reading (int 13h, function 42). I checked for extensions and they are supported so I wrote another real mode program which only load 1 sector using the same bios function, and for some reason it worked. There is only small difference between the codes. In the boot code I wrapped the code that loads the sector with function that gets the parameters, and in the second code it wasn't wrapped with a function. I will post here the codes.
Boot code (only the relevant function, for a full version click here):
%define AdjustAddress(addr) addr - BASE_ADDRESS + NEW_ADDRESS
%define DAP(obj, member) [obj + DiskAddressPacket. %+ member]
NEW_ADDRESS equ 0x0600
BASE_ADDRESS equ 0x7C00
DAP_SIZE equ DiskAddressPacket_size
struc DiskAddressPacket
.size resb 1
.resv resb 1
.num_of_sectors resb 2
.offset resb 2
.segment resb 2
.lba_start resb 8
endstruc
main:
; code
; ....
; Read the VBR
push 0x01
mov si, [AdjustAddress(parti_pointer)]
push dword PE(si, starting_lba)
push BASE_ADDRESS
push 0x00
call ReadSectors
; code
; ....
; void __stdcall ReadSectors(WORD segment, WORD offset, DWORD lba, WORD count)
ReadSectors:
push bp ; Save bp register value
mov bp, sp ; Setting up stack frame
sub sp, DAP_SIZE ; Allocate a buffer for the DAP data
; Zero out DAP buffer
std ; Set direction flag (decrease di)
mov di, bp
xor al, al
mov cx, DAP_SIZE
repnz stosb ; di = DAP buffer at the end of this operation
; Initialize DAP with correct data
mov byte DAP(di, size), DAP_SIZE
mov bx, word [bp + 0x0C] ; count parameter
mov word DAP(di, num_of_sectors), bx
mov bx, word [bp + 0x04] ; segment parameter
mov word DAP(di, segment), bx
mov bx, word [bp + 0x06] ; offset parameter
mov word DAP(di, offset), bx
mov bx, word [bp + 0x08] ; Low word of LBA parameter
mov word DAP(di, lba_start), bx
mov bx, word [bp + 0x0A] ; High word of LBA parameter
mov word DAP(di, lba_start + 0x02), bx
; Prepare parameters
mov ax, 0x4200 ; Extended read sectors function of int 0x13
mov dx, word [AdjustAddress(drive_index)] ; Drive index
mov si, di ; si = DAP buffer
int 0x13 ; Read the sectors from the disk
jc CheckLBASupport.no_lba_support
mov sp, bp ; Clear the allocated memory
pop bp ; Restore bp register value
ret 0x0A ; Clean the stack and return to the calling code
Second code:
cli ; Cancel interrupts
; Set up segments registers
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7c00
mov ax, 0x4100
mov bx, 0x55aa
int 0x13
; Checking returned value with the debugger
sub sp, DiskAddressPacket_size
mov bp, sp
mov byte [bp], DiskAddressPacket_size
mov byte [bp + 0x01], 0x00
mov word [bp + 0x02], 0x01
mov word [bp + 0x04], 0x7C00
mov word [bp + 0x06], 0x00
mov dword [bp + 0x08], 0x80
mov dword [bp + 0x0c], 0x00
mov ax, 0x4200
mov si, bp
int 0x13
I checked the DAP buffer in the memory for both code, and it is the same. I cant figure out why on the boot code I get the error and on the second code I dont. Is there something I miss?
repnz stosbwill store the first value (0) at ES:DI. Assuming you set up ES correctly, DI is pointing to BP. BP actually points to the first byte of BP that was stored on the stack (withpush bp) meaning data is zeroed out on the stack you don't want to set to 0. It seems to me you have an off by error that would cause DI to be one higher than what you expect whenrepnz stosbfinishes . Seems to me you want to decrement DI by one beforerepnz stosb? Might not be cause of your issues, but seems like a bug. - Michael Petchrepnz stosbtodec direpnz stosbinc di. Theinc diafter has to adjust for the fact that the laststosbwould have decremented DI by one. - Michael Petchinc diafterrepnz stosb. since the code is kinda large to put on the original post, i didn't want to copy it all so it will be easier to focus on the problem, but i'll put a link to paste bin with the full code (pastebin.com/eUZXx1hE) - 0x0066FF