Memory detection - Int 0x15, ax = 0xE802

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Memory detection - Int 0x15, ax = 0xE802

Post by Brendan »

Hi,

I'm currently doing a revision of my memory detection code, and have found several places saying that "int 0x15, ax = 0xE802" should be used if "int 0x15, eax = 0xE820" isn't supported (including Ralph Brown's Interrupt List, the OS Dev Wiki page and a few other places).

Does anyone have a description of this BIOS function?

The information for this function from Ralph Brown's Interrupt list says:
Compaq Contura - GET ???

EAX = E802h

Return:
CF clear AX = 0000h BX = ??? CX = 0000h
Obviously this isn't very descriptive, and I haven't been able to find anything else that says anything about this BIOS function....


Thanks,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

edit: shorter link
http://lkml.org/lkml/1998/11/18/48

These are the only other references I found. From the sounds of both, e802 is really rare. The first one also mentions that some of the int 15h functions can crash the system if they are used and the bios doesn't support it, although it doesn't say whether e802 is one that would.

I don't have any experience using it (I've used e820 in my own bootloader and nowadays just rely on grub) so can't really advise you. I wonder if its worth the hassle as I understand the contura is a 486 notebook. Obviously if you plan to support 486s then you may want to look into it, but if you compile for i586 and above for other reasons then I guess the argument is redundant.

I suppose you could do a linux type way and accept a ram= kernel command line to override anything found by e820, e801, e881 et al, and maybe also accept the option ram=e802 which would use the e802 test but only if the user asks for it (or automate its use with the installer option: Do you have a Compaq Contura?).

Regards,
John.
Last edited by jnc100 on Sun Jul 29, 2007 4:08 pm, edited 1 time in total.
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Post by B.E »

I had a quick look, and found nothing extra. From what I can see, it's a bios specific interrupt. I did however search though the source code of grub & grub2 and Freebsd's bootloader and couldn't find any reference to the use of the interrupt.

If it's really needed I would reverse engineer(i.e call the interrupt and see what it returns). Otherwise I would just use the E801 interrupt.

@jnc100: Fix up you links (i.e make them shorter).
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

B.E wrote:@jnc100: Fix up you links (i.e make them shorter).
Happy now? :wink: Blame google if you must. Besides, they fit the screen perfectly on my shiny new widescreen laptop.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,

Thanks - at least I know which computers use this (badly documented) BIOS function now.. :)
jnc100 wrote:These are the only other references I found. From the sounds of both, e802 is really rare. The first one also mentions that some of the int 15h functions can crash the system if they are used and the bios doesn't support it, although it doesn't say whether e802 is one that would.
The BIOS functions themselves shouldn't crash - they may set the carry flag, return "ah=0x86 (unsupported function)", return "ah = 0x80 (invalid command)" or (for seriously buggy BIOSs) return with nothing changed.

An OS that uses these BIOS functions and doesn't detect misleading return values can crash though. For an example, Int 0x15, AH=0x88 is meant to return the number of KB above 1 MB in AX, but if it's not supported it could return "ah = 0x86". A badly written OS might think this means there's more than 34 MB (more than 0x8600 KB of RAM above 1 MB), and then crash when it tries to use the "RAM"...

For Int 0x15, ah = 0xC7 there's another function that you need to use to determine if Int 0x15, ah = 0xC7 is supported. See Int 0x15, ah = 0xC0 (feature byte #2, bit 4), or alternatively, see my old code memory detection code for Int 0x15, ah = 0xC7.
jnc100 wrote:I suppose you could do a linux type way and accept a ram= kernel command line to override anything found by e820, e801, e881 et al, and maybe also accept the option ram=e802 which would use the e802 test but only if the user asks for it (or automate its use with the installer option: Do you have a Compaq Contura?).
In my exaggerated opinion, the Linux/GRUB way is to do a half-assed job and then expect the user to fix things when it goes wrong... ;)

My way is to do as much as I possibly can to ensure code does work right, and then expect the user to let me know when things don't work right so I can fix the problem (for them and everyone else). This means doing everything I can to avoid the need for a "mem=" kernel option, and then not providing any "mem=" option.

BTW I do support 80486 - there's lots of people with old/obsolete computers that aren't "good enough" for newer operating systems (including me).


Thanks,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
B.E wrote:I had a quick look, and found nothing extra. From what I can see, it's a bios specific interrupt. I did however search though the source code of grub & grub2 and Freebsd's bootloader and couldn't find any reference to the use of the interrupt.
I tried that too - checked GRUB, Linux, Plan9, etc. Most seem to use Int 0x15 eax = 0xE820, Int 0x15 eax = 0xE801, Int 0x15 eax = 0x88, CMOS locations, and nothing else.
B.E wrote:If it's really needed I would reverse engineer(i.e call the interrupt and see what it returns). Otherwise I would just use the E801 interrupt.
Unfortunately (AFAIK) none of my computers support the interrupt - they just return "ah = 0x86 (unsupported function)"....


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Post by B.E »

Brendan wrote:Unfortunately (AFAIK) none of my computers support the interrupt - they just return "ah = 0x86 (unsupported function)"
I have to ask the question, is it worth worrying about if only a little percent of the users have the interrupt, when you can get the same information from a more portable source. Although it's not recommended to do so, I would just use standard calls and when someone actually need the call, than worry about it.
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
B.E wrote:
Brendan wrote:Unfortunately (AFAIK) none of my computers support the interrupt - they just return "ah = 0x86 (unsupported function)"
I have to ask the question, is it worth worrying about if only a little percent of the users have the interrupt, when you can get the same information from a more portable source. Although it's not recommended to do so, I would just use standard calls and when someone actually need the call, than worry about it.
Can I get the same information from a more portable source?

My OS currently tries 5 different BIOS functions and then tries CMOS locations. You'd think that'd be enough, but I've still got an 80486 machine here where all of that fails and the OS does manual probing.

Part of the problem is that if better BIOS functions aren't present, my OS falls back to worse BIOS functions, and can then reject the data returned due to BIOS limitations. For example, for "Int 0x15 AH = 0x88" my OS rejects the returned data if the BIOS says there's 65535 KB above 1 MB (the most this function can return) or if the BIOS says there's 15 MB above 1 MB (a value often returned when there's more that 16 MB of RAM).

I don't want end-users running the OS on 16 MB (or 64 MB) when there's more RAM present, I don't want a "mem=" kernel option, and I don't want to do manual probing. I guess you could say I'm fussy.... ;)

Still, it seems I have no choice - without information about "int 0x15, ax = 0xE802" I can't use it, and will have to forget about it (again).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

If you are unable to detect the memory on that 486 with all the conventional methods, perhaps the fault is in the system.. ;)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Post by B.E »

Brendan wrote:... but I've still got an 80486 machine here where all of that fails and the OS does manual probing.
Have you tried int 0x12, also the bios stores the amount of memory at 0x0040:0x0013
Brendan wrote:Part of the problem is that if better BIOS functions aren't present, my OS falls back to worse BIOS functions, and can then reject the data returned due to BIOS limitations. For example, for "Int 0x15 AH = 0x88" my OS rejects the returned data if the BIOS says there's 65535 KB above 1 MB (the most this function can return) or if the BIOS says there's 15 MB above 1 MB (a value often returned when there's more that 16 MB of RAM).
Don't forget, these interrupts were around before the 32-bit processor was 'invented', and as such can only give you a sixteen bit answer.
Brendan wrote: I don't want end-users running the OS on 16 MB (or 64 MB) when there's more RAM present, I don't want a "mem=" kernel option, and I don't want to do manual probing. I guess you could say I'm fussy.... ;)

Still, it seems I have no choice - without information about "int 0x15, ax = 0xE802" I can't use it, and will have to forget about it (again).
These are problems that (if I remember correctly) some OSes in the past have had to overcome (can't remember details of such operating systems {but that my be due to the fact that it's 12 am ATM}).
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
Brynet-Inc wrote:If you are unable to detect the memory on that 486 with all the conventional methods, perhaps the fault is in the system.. ;)
Hehe, the fault is in the system. Don't you think it's strange that there's at least 5 different BIOS functions to detect RAM to begin with? ;)

IIRC the specific 80486 I mentioned actually does have 16 MB of RAM, and some of the old "get extended memory size" functions probably do say that there's 16 MB of RAM installed. However, my OS can't assume that there's 16 MB of RAM when these BIOS functions say there's 16 MB of RAM because these older BIOS functions are dodgy and say there's 16 MB of RAM installed when there's more.

If the same 80486 had 8 MB of RAM then my OS would detect it with BIOS functions correctly (and wouldn't reject the BIOSs results). If the same 80486 had 32 MB of RAM the BIOS functions would probably still tell me there's 16 MB of RAM like they do now, and I'd have to do manual probing.

It is possible that all computers that don't support better "get extended memory size" functions aren't designed to handle more than 16 MB of RAM and can't have more than 16 MB installed. In this case, if better BIOS functions aren't present I would be able to trust the older BIOS functions when they say 16 MB of RAM is installed (instead of rejecting them).

However this is more complicated than it sounds - the computer might support more than 16 MB of RAM and provide "int 0x15, ax = 0xE802" (or any other BIOS function that the OS doesn't support) or better BIOS functions may be present but may have been rejected by the OS for some reason. There's also no way I can be sure that "better BIOS functions not present" does imply "maximum of 16 MB or less".

Again, I should point out I'm seeking perfection here. My existing code probably does work on 99.9% of all (80486 and later) computers, and is already much better than the memory detection code I've seen in any other OS and GRUB. It's the last 0.1% I'm worried about, because (unlike other OSs) I really do not want to provide kernel options so that users can get that last 0.1% working correctly... ;)
B.E wrote:Have you tried int 0x12, also the bios stores the amount of memory at 0x0040:0x0013
Yes, but Int 0x12 (and 0x0040:0x0013) only return the amount of usable RAM below 1 MB - even though it always works it can't tell the OS how much memory there is above 1 MB.
B.E wrote:
Brendan wrote:Part of the problem is that if better BIOS functions aren't present, my OS falls back to worse BIOS functions, and can then reject the data returned due to BIOS limitations. For example, for "Int 0x15 AH = 0x88" my OS rejects the returned data if the BIOS says there's 65535 KB above 1 MB (the most this function can return) or if the BIOS says there's 15 MB above 1 MB (a value often returned when there's more that 16 MB of RAM).
Don't forget, these interrupts were around before the 32-bit processor was 'invented', and as such can only give you a sixteen bit answer.
It's worse than that. For example, "Int 0x15 ax = 0x88" returns "number of KB above 1 MB" as a 16-bit number. In theory this should work if there's up to 65535 KB at 1 MB. In practice often the BIOS limits this value to 15 MB or 63 MB (depending on the BIOS), and if there's an ISA hole at 0x000F00000 it won't return more than 14 MB regardless of how much more RAM is installed (because it's not contiguous RAM).



Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

Just an idea, but like you said.. the older BIOS functions usually have a limit of detecting 16MB..

How about prompting the user? for example.. you know that 486 has 16MB of ram so you could simply "confirm" that's the size of RAM.

If a user is prompted with the "Does your system have 16MB of RAM" message and actually has 32MB, then couldn't manual probing be used?

Just rambling - Sorry.. But I agree.. detecting memory is so flaky.. :(

(Let's all just support i2c and read the EEPROM information off of SDRAM!! :lol:)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
SpooK
Member
Member
Posts: 260
Joined: Sun Jun 18, 2006 7:21 pm

Post by SpooK »

Personally, I support E820->E881->E801->CMOS in order and that should be more than enough for any modern operating system. You can't save the world.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
Brynet-Inc wrote:How about prompting the user? for example.. you know that 486 has 16MB of ram so you could simply "confirm" that's the size of RAM.
That's difficult for me (the OS supports headless systems with no keyboard present). It's also the sort of thing that horrifies users - would you honestly trust an OS that can't even detect the amount of RAM installed correctly?
Brynet-Inc wrote:If a user is prompted with the "Does your system have 16MB of RAM" message and actually has 32MB, then couldn't manual probing be used?
My current code uses the following methods in order, stopping when one of them works:
  • BIOS interrupt 0x15, EAX=0xE820 (ACPI 3.0)
    BIOS interrupt 0x15, EAX=0xE820
    BIOS interrupt 0x15, AX=0xE881
    BIOS interrupt 0x15, AX=0xE801
    BIOS interrupt 0x15, AH=0xC7
    BIOS interrupt 0x15, AH=0x88
    CMOS locations 0x17 and 0x18
    Manual probing
So far I've modified the original code so that if "Int 0x15, AH=0x88" or CMOS says there's either 14 MB or 15 MB at 0x00100000 then it'll probe for memory above 0x01000000; and if "Int 0x15, AH=0x88" or CMOS says there's either 64 MB or 65535 KB at 0x00100000 then it'll probe for memory above 0x04000000. The original code would just reject the values and manually probe for all memory starting at 0x00100000 - the newer code still does some probing (it just does less probing)...

I'm also considering removing the "Int 0x15, AH=0xC7" code. I've tried 6 computers so far without finding a machine that supports it, and I'm only guessing which values mean what (Ralph Brown's Interrupt list isn't very specific and I'm having trouble finding better documentation for this BIOS function too). I've still got a more computers to check before I remove this code, but it looks like it'll be gone soon.

Lastly, there's a few other BIOS functions - "int 0x15, ah = 0x8A" and "int 0x15, ax = 0xDA88". I might try them to see if they're present on any of my machines (especially that 80486), and add support for them (regardless of whether I can test them or not - they're both simple and unambiguous).

BTW in my testing I plugged that old 80486 in to check some things (half my computers live in a closet with nothing plugged into them), and found out my new code uses CMOS locations 0x17 and 0x18, and that there's actually only 8 MB of RAM installed (and that the CMOS battery has gone flat ;) ).
Brynet-Inc wrote:Just rambling - Sorry.. But I agree.. detecting memory is so flaky.. :(

(Let's all just support i2c and read the EEPROM information off of SDRAM!! :lol:)
Hehe, no - computers that are new enough to have SPD data are also new enough to support decent BIOS functions... ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Post by inflater »

I think AX=E820 with INT 15h should work. I use it borrowed from DexOS, and it works in Bochs, QEMU, MS VPC, VMware Workstation, and my development computer and the testbed (testbed is a pentium-s 120 MHz, 40 MB RAM, and dev PC is pentium 4 1.8 GHz, 256 MB RAM). :) Note that detecting memory from CMOS may return strange results if the memory is above 64 MB RAM. So I wouldn't use this. And INT 12h, that's almost 0x280 - 640 kB, except if some MBR protector program, viruses or something other (if running under DOS) is present in RAM. Or you may get a lower value too :), do you have the original IBM PC from 1981 or PCjr in your house somewhere? :)

inflater
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
Post Reply