OSD Home

Physical memory layout of the PC

linear address rangereal-mode address rangememory typeuse
0- 3FF 0000:0000-0000:03FF RAMreal-mode interrupt vector table (IVT)
400- 4FF 0040:0000-0040:00FF BIOS data area (BDA)
500- 9FBFF 0050:0000-9000:FBFF free conventional memory (below 1 meg)
9FC00- 9FFFF 9000:FC00-9000:FFFF extended BIOS data area (EBDA)
A0000- BFFFF A000:0000-B000:FFFF video RAM VGA framebuffers
C0000- C7FFF C000:0000-C000:7FFF ROM video BIOS (32K is typical size)
C8000- EFFFF C800:0000-E000:FFFF NOTHING
F0000- FFFFF F000:0000-F000:FFFF ROM motherboard BIOS (64K is typical size)
100000- FEBFFFFF RAM free extended memory (1 meg and above)
FEC00000- FFFFFFFF various motherboard BIOS, PnP NVRAM, ACPI, etc.

The IVT and BDA contain information that is useful even to pmode OSes. For information on the contents of these structures, see Ralf Brown's Interrupt List: http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html

Bootsectors and MBRs are loaded at addresses 7C00h - 7DFFh. Depending on how it's written, this code may use additional memory outside this range. The DOS 7 MBR copies itself to 600h - 7FFh, leaving 7C00h - 7DFFh free for successive MBRs or bootsectors.

The EBDA shown here is 1K. Some computers don't have an EBDA, others have an EBDA larger than 1K.

Determining RAM sizes

The top of conventional memory may contain an extended BIOS data area (EBDA). Use INT 12h (or read the 16-bit value at linear address 0413h) to get the top of conventional memory, and don't use conventional memory above this limit. When DOS is running, it's possible to have more than 640K of conventional memory if EMM386 is loaded like this:
        DEVICE=C:\DOS\EMM386.EXE I=A000-AFFF
Real-mode code may be able to take advantage of the extra 64K, but switching to protected mode in this situation will probably cause the extra memory to 'disappear'. If INT 12h returns a value greater than 0x280 (640), limit this value to 0x280.

Determining extended memory size is surprisingly difficult:

Allocating RAM

xxx
Physical memory allocation:
- Heap algorithms to use if paging is not used, or on top of paging:
	BogoMalloc, first-fit, dlmalloc (bins), object-based (slab), other?
- Algorithms for allocating pages: bitmap, stack, buddy, trees?
  Page coloring (x86 CPU uses associative L1 cache, so page coloring
  is more for other CPUs with direct-mapped cache -- right?)
- Zone memory: low RAM for ISA DMA, slow NUMA or uncached memory for
  page tables (since they're cached in the TLB)

DMA restrictions on physical memory

Memory used by ISA (8- and 16-bit) DMA must be below 16 meg. This type of DMA is used by the floppy drive and by ISA sound boards. Memory used by 8-bit DMA (DMA channels 0-3) can not cross a 64K boundary; memory used by 16-bit DMA (channels 4-7) can not cross a 128K boundary.

PCI (32-bit) DMA; also known as bus-mastering, does not have these restrictions.

Code snippets

Get memory size with BIOS calls or from CMOS: see bootstrap code snippets

Simple malloc(): first-fit, free() coalesces adjacent free blocks, fixed- or variable-sized heap, no mmap()

ROMs can be detected with INT 15h AX=E820h (look for type 2 memory), or by scanning for 16-bit BIOS ROM extensions

Links

Doug Lea's malloc(): http://g.oswego.edu/dl/html/malloc.html. Public domain, portable, good performance. Can use sbrk() or mmap() or both to enlarge the heap.

John Walker's BGET: http://www.fourmilab.ch/bget/. Reasonably portable. Public-domain.

  http://www.cs.colorado.edu/~zorn/Malloc.html
  http://nondot.org/sabre/os/articles/MemoryManagement/

TO DO

REPORT BUGS OR ERRORS IN THIS DOCUMENT