Page 1 of 1
BDA 0:0x046c is not updated in Bochs
Posted: Fri Dec 30, 2016 5:11 am
by alexeikom
Hi!
I wrote a primitive delay procedure that reads the BDA 0:0x046c. I use Bochs and I've noticed that during the POST process the value in memory is updated but once control passed to 0x7c00, the value is no longer updated (checked this with Bochs debugger). Is this a known issue or I'm missing something? Or perhaps this is legacy and is not a standard anymore in BIOS?
Thanks a lot!
Alexei
Re: BDA 0:0x046c is not updated in Bochs
Posted: Fri Dec 30, 2016 5:25 am
by BrightLight
When possible, you shouldn't depend on the BIOS for anything. In a boot loader, you should use the BIOS only for output, video modes, memory detection and disk access. When you need a proper delay function after you are in protected or long mode, you can use the PIT (or eventually the APIC and/or HPET). If you absolutely must use the BIOS for a delay function, try having a look at the time functions of interrupt 0x1A, as most fields in the BIOS data area are obsolete and I wouldn't trust them on any real HW.
Re: BDA 0:0x046c is not updated in Bochs
Posted: Fri Dec 30, 2016 5:36 am
by alexeikom
omarrx024 wrote:When possible, you shouldn't depend on the BIOS for anything. In a boot loader, you should use the BIOS only for output, video modes, memory detection and disk access. When you need a proper delay function after you are in protected or long mode, you can use the PIT (or eventually the APIC and/or HPET). If you absolutely must use the BIOS for a delay function, try having a look at the time functions of interrupt 0x1A, as most fields in the BIOS data area are obsolete and I wouldn't trust them on any real HW.
I absolutely agree with you! This delay was something that I've made quickly for temporary use.
Thanks for your answer!
Re: BDA 0:0x046c is not updated in Bochs
Posted: Fri Dec 30, 2016 12:47 pm
by Brendan
Hi,
alexeikom wrote:I wrote a primitive delay procedure that reads the BDA 0:0x046c. I use Bochs and I've noticed that during the POST process the value in memory is updated but once control passed to 0x7c00, the value is no longer updated (checked this with Bochs debugger). Is this a known issue or I'm missing something? Or perhaps this is legacy and is not a standard anymore in BIOS?
I tested it on Bochs here and BDA 0:0x046c is updated after the BIOS passes control to 0x7C00.
I'd assume that your code is "buggy". The PIT chip sends an IRQ to the master PIC chip, which sends an IRQ to the CPU if interrupts are enabled in the CPU, which causes CPU to use the IDT or IVT to find the associated interrupt handler, where the BIOS IRQ/interrupt handler increments the value at 0:0x046c. If you've touched anything in that chain then...
Cheers,
Brendan
Re: BDA 0:0x046c is not updated in Bochs
Posted: Sat Dec 31, 2016 5:27 pm
by alexeikom
Brendan wrote:Hi,
alexeikom wrote:I wrote a primitive delay procedure that reads the BDA 0:0x046c. I use Bochs and I've noticed that during the POST process the value in memory is updated but once control passed to 0x7c00, the value is no longer updated (checked this with Bochs debugger). Is this a known issue or I'm missing something? Or perhaps this is legacy and is not a standard anymore in BIOS?
I tested it on Bochs here and BDA 0:0x046c is updated after the BIOS passes control to 0x7C00.
I'd assume that your code is "buggy"....
Cheers,
Brendan
Hi! I thought that either but then I checked it on real machine and it worked.
Re: BDA 0:0x046c is not updated in Bochs
Posted: Sat Dec 31, 2016 9:12 pm
by Brendan
Hi,
alexeikom wrote:Brendan wrote:I'd assume that your code is "buggy"....
Hi! I thought that either but then I checked it on real machine and it worked.
So you're saying that your code is buggy, but the bug depends on something that might be different on different computers (like CPU features, or memory map, or timing, or the presence or absence of certain devices, or the initial contents of uninitialised RAM, or the initial contents of registers when BIOS passes control to your code, or how the firmware happens to use part of its BDA or EBDA that gets accidentally corrupted, or....), and so it's only a problem on some computers (e.g. Bochs and possibly millions of others) and not other computers (e.g. one real computer)?
My suggestion would be to test on Bochs using something like this:
Code: Select all
mov ax,[0x046C]
sti
.wait:
hlt
cmp [0x046C],ax
je .wait
The idea is that you put this as early as possible in your boot code and see if it waits forever, then shift it somewhere else and see if it waits forever, and keep shifting it like that using a kind of binary search pattern (e.g. each time, shift it to approximately half-way between where it was working last and where it stopped working last) to find the point in your code immediately before it stops working.
Cheers,
Brendan
Re: BDA 0:0x046c is not updated in Bochs
Posted: Sat Jan 07, 2017 12:17 pm
by alexeikom
Brendan wrote:Hi,
alexeikom wrote:Brendan wrote:I'd assume that your code is "buggy"....
Hi! I thought that either but then I checked it on real machine and it worked.
So you're saying that your code is buggy, but the bug depends on something that might be different on different computers (like CPU features, or memory map, or timing, or the presence or absence of certain devices, or the initial contents of uninitialised RAM, or the initial contents of registers when BIOS passes control to your code, or how the firmware happens to use part of its BDA or EBDA that gets accidentally corrupted, or....), and so it's only a problem on some computers (e.g. Bochs and possibly millions of others) and not other computers (e.g. one real computer)?
My suggestion would be to test on Bochs using something like this:
Code: Select all
mov ax,[0x046C]
sti
.wait:
hlt
cmp [0x046C],ax
je .wait
The idea is that you put this as early as possible in your boot code and see if it waits forever, then shift it somewhere else and see if it waits forever, and keep shifting it like that using a kind of binary search pattern (e.g. each time, shift it to approximately half-way between where it was working last and where it stopped working last) to find the point in your code immediately before it stops working.
Cheers,
Brendan
Hi! Thanks for a great suggestion. I did the check and the code suggested by you worked everywhere! I then compared it to my code:
Code: Select all
push es
push ax
xor ax,ax
mov es,ax
mov ax,[es:0x046C]
inc ax
comp:
cmp ax,[es:0x046C]
jae comp
pop ax
pop es
ret
You have sti in your code. But I didn't issue cli. So who did? Apparently, cli is issued when I call int 0x1A with AX=0xB101 (check PCI BIOS availability) or AX=0xB103 (find PCI class code). Perhaps more functions related to PCI do that. When I put sti right after their execution, everything works fine!