Page 1 of 1
APM BIOS Calls
Posted: Tue May 22, 2012 5:14 am
by 10thProtocol
Quick question anout the : APM Protected Mode 32-bit Interface Connect (03H) call in APM 1.2
I noticed some other postings from about 4 years ago but didn't seem to get resolved. I know its ACPI now, but still curious about use of this call.
One of the params the call returns is:
AX = PM 32-bit code segment (real mode segment base address)
I'm a little confused about the term: real mode segment base address
As this is only a 16 bit value, does this mean it can only point to a base within the first 64K. Or is it actually returning the base address used in the descriptor cache, i.e. x16 this value. This would allow it to point antwhere in 1MB real mode space.
The previous posting put the value direct into the LSB's of the Segment Base Address in the Segment Descriptor structure, thus limiting it to first 64K. The size was hardwired at 0xFFFF. He couldn't make it work, but maybe for other reasons.
As the BIOS is mapped to 0xFFFF0 or 0xFFFFFFF0 etc., seems a bit strange.
Any comments appreciated
Re: APM BIOS Calls
Posted: Tue May 22, 2012 6:00 am
by Nable
I think that this is the comprehensive answer:
http://www.ctyme.com/intr/rb-1397.htm
Re: APM BIOS Calls
Posted: Tue May 22, 2012 6:23 am
by 10thProtocol
Thanks, but it is only a slightly fuller description than the spec.
I still don't fully understand 'Real Mode Segment Base', in this context.
Re: APM BIOS Calls
Posted: Tue May 22, 2012 1:29 pm
by Nable
Sorry, it's really non-obvious.
Here's example of code:
http://psomas.wordpress.com/2011/04/09/ ... ation-apm/
Hope it helps, it was a 4th link in google.
Re: APM BIOS Calls
Posted: Wed May 23, 2012 4:26 am
by 10thProtocol
Thanks, Nable
Well, I had seen that before but it all looked a little hard to digest.
I've now had another go at it but I'm afraid my Linux+C+In-line assembly is not up to it at the moment.
So can I ask a more general question, which is at the root of my confusion:
Assuming you return a Segement base + offset for a code segment. If you are in Protected Mode, then a long call using this represents a virtual memory reference that must be translated into a physical address if paging is enabled.
How is this resolved??
Sorry to burden you with this but you're the only responder.
Re: APM BIOS Calls
Posted: Wed May 23, 2012 5:01 am
by Nable
BIOS call gives you physical addresses, so you just have to setup page tables that contains mappings for that memory + setup GDT or LDT entries that have required base:
set_desc_base(&gdt[APM_CS >> 3], (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
set_desc_base(&gdt[APM_CS_16 >> 3], (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
set_desc_base(&gdt[APM_DS >> 3], (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
AFAIR, __va() is a linux function (or macro) that resolves physical address into virtual one. So, for example, (apm_info.bios.cseg << 4) is a physical base address of APM 32bit code area and __va(apm_info.bios.cseg << 4) is a virtual address of it.
Re: APM BIOS Calls
Posted: Wed May 23, 2012 7:31 am
by 10thProtocol
Very interesting, 2 points:
1 I have no knowledge of Linux, only windows, so your useful sample code was unintelligable but accurate.
2 The previous post,
http://forum.osdev.org/viewtopic.php?f=1&t=16898, which started my confusion, now seems very far off the plot.
So, in conclusion, the physical addresses returned by the BIOS call are used to:
1 Create Segment Descriptors
2 Create GDT/LDT entries to point to them
3 Create mappings to virtual memory that can then be used to access the physical block provided by the initial BIOS Connect call.
4 In Windows, step 4 would be achived via call to some memory mapping function
Incidentally, in the Linux code, I see this <<4 which I noticed previously but was too confused about other things to react.
Going back to my original post, do you think that <<4 is the x16 I was looking for to yield a 'real' segment base that is 20 bits long.
I'll leave you alone after this, many thanks.
walter