Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision 59fb782a51d15d6df341976b45edaf3497af36fc)
+++ kernel/arch/ia32/src/mm/frame.c	(revision 39c4d1fcc4ef3db6fd729c7933a9c29213dab92d)
@@ -47,4 +47,5 @@
 
 #define PHYSMEM_LIMIT32  UINT64_C(0x100000000)
+#define PHYSMEM_LIMIT_DMA   UINT64_C(0x1000000)
 
 size_t hardcoded_unmapped_ktext_size = 0;
@@ -91,11 +92,26 @@
 				else
 					conf = minconf;
-				zone_create(pfn, count, conf,
-				    ZONE_AVAILABLE | ZONE_LOWMEM);
+
+				if ((pfn * PAGE_SIZE) < PHYSMEM_LIMIT_DMA) {
+					size_t dma_count = min(
+					    PHYSMEM_LIMIT_DMA / PAGE_SIZE - pfn,
+					    count);
+					zone_create(pfn, dma_count, conf,
+					    ZONE_AVAILABLE | ZONE_DMA);
+					count -= dma_count;
+					pfn += dma_count;
+				}
+
+				conf = pfn;
+				if (count) {
+					zone_create(pfn, count, conf,
+					    ZONE_AVAILABLE | ZONE_LOWMEM);
+				}
 			} else {
 				conf = zone_external_conf_alloc(count);
-				if (conf != 0)
+				if (conf != 0) {
 					zone_create(pfn, count, conf,
 					    ZONE_AVAILABLE | ZONE_HIGHMEM);
+				}
 			}
 		} else if ((e820table[i].type == MEMMAP_MEMORY_ACPI) ||
