Detecting memory with INT 0x15, EAX=0xE820

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.
Post Reply
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Detecting memory with INT 0x15, EAX=0xE820

Post 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
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Detecting memory with INT 0x15, EAX=0xE820

Post by iansjack »

The extended registers are available in real mode.
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: Detecting memory with INT 0x15, EAX=0xE820

Post 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.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Detecting memory with INT 0x15, EAX=0xE820

Post 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).
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: Detecting memory with INT 0x15, EAX=0xE820

Post 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.
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Detecting memory with INT 0x15, EAX=0xE820

Post 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).
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Detecting memory with INT 0x15, EAX=0xE820

Post 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].
Post Reply