Page 1 of 1
Detecting memory with INT 0x15, EAX=0xE820
Posted: Wed Dec 23, 2015 6:58 am
by onlyonemac
Hi,
I'm working on initialising the bitmap for my bitmap memory allocator. Obviously I need to exclude the numerous unusable areas, such as reserved BIOS areas, memory-mapped hardware, and memory that doesn't exist. Thus it seems that I need to use INT 0x15, EAX=0xE820 to get a map of the system's physical memory. I've read the wiki page on this interrupt, however nowhere can I find out whether I need to call this from real mode or protected mode. As it's a BIOS interrupt, I would assume real mode, however it uses the extended registers which I believe are only available in protected mode. If it's real mode, then I also need to use it sometime before I enter protected mode, which is quite early on in my bootloader.
Also, as a matter of principle, is it best to ignore all memory below 16MB and use just the "neat" memory above that up to the 0xC0000000 memory-mapped I/O area, or is it better to try to make use of the various scraps of low memory that are available? Should I maybe use the low memory just for the GDT and IDT, to keep those nicely out of the way? Also, is the upper memory above 16MB guaranteed to be contiguous, or does it depend on how the memory modules are inserted into the motherboard?
Thanks,
onlyonemac
Re: Detecting memory with INT 0x15, EAX=0xE820
Posted: Wed Dec 23, 2015 7:16 am
by iansjack
The extended registers are available in real mode.
Re: Detecting memory with INT 0x15, EAX=0xE820
Posted: Wed Dec 23, 2015 7:19 am
by Octocontrabass
onlyonemac wrote:As it's a BIOS interrupt, I would assume real mode, however it uses the extended registers which I believe are only available in protected mode.
Extended registers are available in real mode.
onlyonemac wrote:Also, as a matter of principle, is it best to ignore all memory below 16MB and use just the "neat" memory above that up to the 0xC0000000 memory-mapped I/O area, or is it better to try to make use of the various scraps of low memory that are available?
Do you want your OS to support hardware that uses ISA DMA? Do you want your OS to run on computers with low amounts of RAM?
If you answered "no" to both of those questions, then you can ignore it.
onlyonemac wrote:Also, is the upper memory above 16MB guaranteed to be contiguous, or does it depend on how the memory modules are inserted into the motherboard?
It's not contiguous on any computer I've ever tested, and it has nothing to do with how the memory modules are installed. The BIOS reserves several ranges of memory for its own purposes.
Re: Detecting memory with INT 0x15, EAX=0xE820
Posted: Wed Dec 23, 2015 7:24 am
by alexfru
I'm not aware of any BIOS functions available for calling from protected mode (except VESA VBE extensions).
32-bit registers are available in all 16-bit modes as long as they exist in the CPU (that is, i80386+).
I'd not assume contiguity of memory anywhere above the 640KB mark. When you enable page translation, physical contiguity ceases to be a show stopper.
Legacy DMA (e.g. for FDD, Sound Blaster and such) is limited to physical memory below the 16MB mark (it has 24-bit addresses), so you may want to set aside some of it instead of all of it being immediately available to your memory manager's general-purpose allocate and free routines.
To simplify things you should probably start with the GDT and IDT identity-mapped (that is, virtual address = physical address). Anyway, they're small and can't be a problem. Oh, one odd thing to look out for... If LGDT/LIDT's memory operand size is 16-bit (e.g. [bx] as opposed to [ebx]), it will ignore bits 24 through 31 of the address of the table (I suppose, this is for compatibility with i80286, which had at most 24 address lines).
Re: Detecting memory with INT 0x15, EAX=0xE820
Posted: Wed Dec 23, 2015 7:36 am
by Octocontrabass
alexfru wrote:Oh, one odd thing to look out for... If LGDT/LIDT's memory operand size is 16-bit (e.g. [bx] as opposed to [ebx]), it will ignore bits 24 through 31 of the address of the table (I suppose, this is for compatibility with i80286, which had at most 24 address lines).
No, you're confusing address size and operand size. If you need it, you can specify a 32-bit operand using the o32 prefix in NASM syntax, but it isn't affected by the address size.
Re: Detecting memory with INT 0x15, EAX=0xE820
Posted: Wed Dec 23, 2015 8:16 am
by onlyonemac
OK, I think I'll put the GDT and IDT in the low memory area where they can be easily set up while still in real mode. Then I'll put the kernel in the 1MB - 15MB range below the ISA memory hole, as it's small enough to fit there and I don't envisage it getting larger than a few hundred kilobytes any time soon (it's currently 16KB and about 25% to 50% complete). Then I'll mark the whole first 16MB of memory as in use, and any additional areas that the BIOS says are unavailable. I'm not fussed about computers with low amount of RAM (less than 128MB of RAM) so I'll use the available memory above 16MB for general-purpose memory; this should leave plenty enough memory below 1MB for floppy disk access. Furthermore, I can fairly easily change this setup if I decide to, for example, try running the OS on my old 486 PC, as most (if not all) of the memory map configuration is going to be moved to the bootloader and the kernel's pretty flexible about the memory map (it gets passed various values and table pointers to describe the system that it is running on, one of which will describe the memory layout as determined by the bootloader - this means that all of the memory detection can be done in the bootloader, and the bootloader can easily load the kernel somewhere else and allow use of the memory below 16MB if it detects that there isn't enough memory elsewhere).
Re: Detecting memory with INT 0x15, EAX=0xE820
Posted: Wed Dec 23, 2015 3:34 pm
by alexfru
Octocontrabass wrote:alexfru wrote:Oh, one odd thing to look out for... If LGDT/LIDT's memory operand size is 16-bit (e.g. [bx] as opposed to [ebx]), it will ignore bits 24 through 31 of the address of the table (I suppose, this is for compatibility with i80286, which had at most 24 address lines).
No, you're confusing address size and operand size. If you need it, you can specify a 32-bit operand using the o32 prefix in NASM syntax, but it isn't affected by the address size.
Right, it must've been word [(e)bx] vs dword [(e)bx].