Trouble with int 0x13 ah = 0x42 in VMware
Trouble with int 0x13 ah = 0x42 in VMware
I feel really dumb for posting this, but anyway.
I have made a bootloader and it works on QEMU, VirtualBox and Bochs, but not on VMware. I have done some debugging and narrowed it down to int 0x13 ah = 0x42. Now if I change it to ah=2, it works! While this may seem to be the obvious solution, I have already written a stage 2 using the extended bios functions.
Cut it short my question is; has anyone else had trouble with int 0x13 ah = 0x42 in VMware and what was your/their fix.
Some side notes; I have not tested it on real hardware(getting my second computer to work before I do) and if I must do it I can change it to use ah=2.
The code for the boot loader(in case your curious): https://github.com/cxleb/MochaOS/blob/m ... stage1.asm
I have made a bootloader and it works on QEMU, VirtualBox and Bochs, but not on VMware. I have done some debugging and narrowed it down to int 0x13 ah = 0x42. Now if I change it to ah=2, it works! While this may seem to be the obvious solution, I have already written a stage 2 using the extended bios functions.
Cut it short my question is; has anyone else had trouble with int 0x13 ah = 0x42 in VMware and what was your/their fix.
Some side notes; I have not tested it on real hardware(getting my second computer to work before I do) and if I must do it I can change it to use ah=2.
The code for the boot loader(in case your curious): https://github.com/cxleb/MochaOS/blob/m ... stage1.asm
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Trouble with int 0x13 ah = 0x42 in VMware
Your DAP is all messed up. You can find its format in the EDD specification, the latest being version 4.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
Re: Trouble with int 0x13 ah = 0x42 in VMware
I followed the spec, but still same result? i tried another os using extended bios read and it failed too, maybe it is just VMware?Love4Boobies wrote:Your DAP is all messed up. You can find its format in the EDD specification, the latest being version 4.
-
- Member
- Posts: 5587
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Trouble with int 0x13 ah = 0x42 in VMware
You're relying on the (undefined) initial value of DS on line 24.
MOV to SS only disables interrupts long enough for one more instruction to run. Since line 33 is not a MOV to SP, interrupts can occur with an invalid stack. (You can use "mov sp, 0x7c00".)
MOV to SS only disables interrupts long enough for one more instruction to run. Since line 33 is not a MOV to SP, interrupts can occur with an invalid stack. (You can use "mov sp, 0x7c00".)
Re: Trouble with int 0x13 ah = 0x42 in VMware
For a working example of DAP see here: https://github.com/ReturnInfinity/Pure6 ... fs_mbr.asm
BareMetal OS - http://www.returninfinity.com/
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
Mono-tasking 64-bit OS for x86-64 based computers, written entirely in Assembly
-
- Member
- Posts: 5587
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Trouble with int 0x13 ah = 0x42 in VMware
flicki wrote:Code: Select all
dap: db 16 ; size db 0 ; unused dw 16 ; sector count dw 0x0500 ; offset dw 0 ; segment dq 1 ; sector read start
I don't think the problem is the DAP.IanSeyler wrote:For a working example of DAP see here:Code: Select all
DAP: db 0x10 db 0x00 dw SECTORS dw ADDRESS dw SEGMENT dq STARTSECTOR
Re: Trouble with int 0x13 ah = 0x42 in VMware
... particularly as the code works on some platforms and not others. I would guess that your point about an assumed value of register DS is the most likely explanation.
Re: Trouble with int 0x13 ah = 0x42 in VMware
I've found that when one VM works and another doesn't, it's because you are making an assumption about the initial state of the machine.
My loader works on VMware, and the only differences that I can see are as follows:
1. You need to clear the direction flag. The BIOS may have left it set when your loader is called.
2. Make sure that your initial JMP is a long jump. You have no idea what CS is set to when your loader is called. (Or, add a second long jump after the first one. I don't think you have room for a long jmp before your MBR.)
3. Try setting your stack pointer to zero instead of 7c00. I doubt this is a problem, but it's worth a shot.
4. Try enabling the A20 address line. Shouldn't matter in your case, but you might as well.
5. If all else fails, try changing your sector count to 1 to see if that works at all.
I'm 99% sure your problem is #2.
Edit: 6. You should also probably clear your FS and GS registers. Just to be safe.
My loader works on VMware, and the only differences that I can see are as follows:
1. You need to clear the direction flag. The BIOS may have left it set when your loader is called.
2. Make sure that your initial JMP is a long jump. You have no idea what CS is set to when your loader is called. (Or, add a second long jump after the first one. I don't think you have room for a long jmp before your MBR.)
3. Try setting your stack pointer to zero instead of 7c00. I doubt this is a problem, but it's worth a shot.
4. Try enabling the A20 address line. Shouldn't matter in your case, but you might as well.
5. If all else fails, try changing your sector count to 1 to see if that works at all.
I'm 99% sure your problem is #2.
Edit: 6. You should also probably clear your FS and GS registers. Just to be safe.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Re: Trouble with int 0x13 ah = 0x42 in VMware
I'm actually curious to what the outcome of this is. I also think it is an assumption that VMware emulates different than other emulators.
However, I am pretty sure that it is not that you need to set your CS:IP pair with a long jump. This is a common misunderstanding for boot loaders.
As long as you do not use the CS: override or anything that relies on the CS:IP pair, it doesn't matter what the CS:IP pair evaluates to, and a long jump is not needed at all.
As long as you don't do one of the following:Along with a few other "so far off" items, it doesn't matter what the CS:IP pair is.
Even doesn't rely on the CS:IP pair. It *does* rely on the ORG (origin) you give the source file, but it does not rely on the CS:IP pair.
For example, the CS:IP pair could be 0020:7A00h or 0123:69D0h for that matter as long as the combined physical address is 0x07C00.
Anyway, I am curious to what you found out. Was it the assumption of the DS value? A bad stack? What?
Thanks,
Ben
However, I am pretty sure that it is not that you need to set your CS:IP pair with a long jump. This is a common misunderstanding for boot loaders.
As long as you do not use the CS: override or anything that relies on the CS:IP pair, it doesn't matter what the CS:IP pair evaluates to, and a long jump is not needed at all.
As long as you don't do one of the following:
Code: Select all
mov ax,cs
mov ds,ax
call get_ip
get_ip:
pop ax
mov cs:[some_data],ax
Even
Code: Select all
...
this_location:
mov ax,offset this_location
For example, the CS:IP pair could be 0020:7A00h or 0123:69D0h for that matter as long as the combined physical address is 0x07C00.
Anyway, I am curious to what you found out. Was it the assumption of the DS value? A bad stack? What?
Thanks,
Ben
Re: Trouble with int 0x13 ah = 0x42 in VMware
It actually may be the very first line that's the problem...
Since, afaik, you have no idea what DS is set to, this will only work (as intended) if DS is set to zero by the BIOS before your loader is called. Your drive letter value is getting stored somewhere, but probably not where you think, and probably not the same place that you pull it from at the end of your loader.
Simply moving this line below your DS/ES reset code will probably fix the problem.
Also, since your DAP structure is inline with your code, I'm thinking that passing the address to int 13h will only work if CS and DS are set to the same value. Which means that you probably want to do a long jmp somewhere near the top of your code.
If this were an exe file, with proper segments, you could probably get away with this, but in this case, you have to keep an eye on your segment registers.
Edit: octocontrabass called the first issue, but I'm sticking by my long jmp call.
Another option would be to copy CS to DS. Ironically, BenLunt did exactly this in his example code, when he was trying to prove that this wasn't necessary.
And, technically, it has nothing to do with VMWare, and more to do with the BIOS. Making assumptions about the initial state of the machine will always fail on any machine that doesn't match your assumptions.
Code: Select all
mov byte [driveNum], dl
Simply moving this line below your DS/ES reset code will probably fix the problem.
Also, since your DAP structure is inline with your code, I'm thinking that passing the address to int 13h will only work if CS and DS are set to the same value. Which means that you probably want to do a long jmp somewhere near the top of your code.
If this were an exe file, with proper segments, you could probably get away with this, but in this case, you have to keep an eye on your segment registers.
Edit: octocontrabass called the first issue, but I'm sticking by my long jmp call.
Another option would be to copy CS to DS. Ironically, BenLunt did exactly this in his example code, when he was trying to prove that this wasn't necessary.
And, technically, it has nothing to do with VMWare, and more to do with the BIOS. Making assumptions about the initial state of the machine will always fail on any machine that doesn't match your assumptions.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
-
- Member
- Posts: 5587
- Joined: Mon Mar 25, 2013 7:01 pm
Re: Trouble with int 0x13 ah = 0x42 in VMware
The value of CS doesn't matter for that. What matters is that you tell the assembler (with an org statement) how to calculate the offsets in the segment you're using. Since the extended read function uses DS:SI, you need DS to agree with your org statement.SpyderTL wrote:Also, since your DAP structure is inline with your code, I'm thinking that passing the address to int 13h will only work if CS and DS are set to the same value.
You only need a long jump (or some equivalent) if you rely on the value of CS. It's still a good idea, but it's unnecessary in this situation.SpyderTL wrote:Edit: octocontrabass called the first issue, but I'm sticking by my long jmp call.
No irony here, BenLunt is correct. You don't know the value of CS, so copying it to DS means you still don't know the value of DS.SpyderTL wrote:Another option would be to copy CS to DS. Ironically, BenLunt did exactly this in his example code, when he was trying to prove that this wasn't necessary.
Re: Trouble with int 0x13 ah = 0x42 in VMware
It's no use guessing (as the other respondents, even if they are right, are doing). Here is a simple (probably too simple for most)flicki wrote:I feel really dumb for posting this, but anyway.
I have made a bootloader and it works on QEMU, VirtualBox and Bochs, but not on VMware. I have done some debugging and
narrowed it down to int 0x13 ah = 0x42. Now if I change it to ah=2, it works! While this may seem to be the obvious solution,
I have already written a stage 2 using the extended bios functions.
Cut it short my question is; has anyone else had trouble with int 0x13 ah = 0x42 in VMware and what was your/their fix.
boot program (FASM/NASM) which prints the relevant register values on startup.
Code: Select all
org 0x7C00
start:
push sp
push 0xBEEF
push ss
push es
push ds
push cs
push 0xFEED
pushf
xor ax, ax
mov ds, ax
mov es, ax
mov cx, 7
mov si, strings
call print
pop ax
call print_binary
call print_return
.1:
call print
pop ax
call print_hex
call print_return
loop .1
jmp $
print:
cld
.1:
mov ah, 0x0E
xor bh, bh
lodsb
test al, al
je .2
int 0x10
jmp .1
.2:
ret
print_hex:
push cx
mov dx, ax
mov ah, 0Eh
xor bx, bx
mov cx, 4
.1:
rol dx, 4
mov al, dl
and al, 0Fh
add al, '0'
cmp al, '9'
jbe .2
add al, 'A'-('9'+1)
.2:
int 10h
loop .1
pop cx
ret
print_binary:
push cx
mov dx, ax
mov ah, 0Eh
xor bx, bx
mov cx, 16
.1:
rol dx, 1
mov al, dl
and al, 1
add al, '0'
int 10h
loop .1
pop cx
ret
print_return:
mov ah, 0Eh
xor bx, bx
mov al, 0x0D
int 10h
mov al, 0x0A
int 10h
ret
strings:
db "FLAGS = ", 0
db "FEED = ", 0
db "CS = 0x", 0
db "DS = 0x", 0
db "ES = 0x", 0
db "SS = 0x", 0
db "BEEF = ", 0
db "SP = 0x", 0
times 510 - ($-$$) db 0
dw 0xAA55
an org 0x7c00.
So, it seems that assuming a DS value was the issue here. Of course neither int 0x13 should have worked with an incorrect DL value,
so it's more than likely not the only issue here.
Remember, when you ASSUME you make an ASS out of yoU and other forum MEmbers.
Last edited by mikegonta on Mon Feb 06, 2017 9:07 am, edited 1 time in total.
Re: Trouble with int 0x13 ah = 0x42 in VMware
I was thinking that you would also run into problems with near jmp/call instructions if the address was absolute, but it turns out that no such instruction exists on the x86.
There are a few indirect absolute jump functions... those probably wouldn't work.
EDIT: Nevermind. Indirect jumps are basically pointers with a CS value and an offset. You guys are right... CS doesn't matter at all. But I'm still not removing my far jmp...
There are a few indirect absolute jump functions... those probably wouldn't work.
EDIT: Nevermind. Indirect jumps are basically pointers with a CS value and an offset. You guys are right... CS doesn't matter at all. But I'm still not removing my far jmp...
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott