Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/src/mm/frame.c	(revision c1f7f6eaa570166428a8687a4e9c7cd839cd666d)
@@ -51,32 +51,60 @@
 
 uintptr_t last_frame = 0;
-uintptr_t end_frame = 0;
 
 static void init_e820_memory(pfn_t minconf)
 {
 	unsigned int i;
-	pfn_t start, conf;
-	size_t size;
-	
 	for (i = 0; i < e820counter; i++) {
+		uint64_t base = e820table[i].base_address;
+		uint64_t size = e820table[i].size;
+		
+#ifdef __32_BITS__
+		
+		/* Ignore physical memory above 4 GB */
+		if ((base >> 32) != 0)
+			continue;
+		
+		/* Clip regions above 4 GB */
+		if (((base + size) >> 32) != 0)
+			size = 0xffffffff - base;
+		
+#endif
+		pfn_t pfn;
+		count_t count;
+		
 		if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
-			start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE));
-			size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE));
+			/* To be safe, make available zone possibly smaller */
+			pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE));
+			count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE));
 			
-			if ((minconf < start) || (minconf >= start + size))
-				conf = start;
+			pfn_t conf;
+			if ((minconf < pfn) || (minconf >= pfn + count))
+				conf = pfn;
 			else
 				conf = minconf;
 			
-			zone_create(start, size, conf, 0);
+			zone_create(pfn, count, conf, ZONE_AVAILABLE);
 			
-			if (last_frame < ALIGN_UP(e820table[i].base_address +
-			    e820table[i].size, FRAME_SIZE))
-				last_frame =
-				    ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
+			// XXX this has to be removed
+			if (last_frame < ALIGN_UP(base + size, FRAME_SIZE))
+				last_frame = ALIGN_UP(base + size, FRAME_SIZE);
+		}
+		
+		if (e820table[i].type == MEMMAP_MEMORY_RESERVED) {
+			/* To be safe, make reserved zone possibly larger */
+			pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE));
+			count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE));
+			
+			zone_create(pfn, count, 0, ZONE_RESERVED);
+		}
+		
+		if (e820table[i].type == MEMMAP_MEMORY_ACPI) {
+			/* To be safe, make firmware zone possibly larger */
+			pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE));
+			count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE));
+			
+			zone_create(pfn, count, 0, ZONE_FIRMWARE);
 		}
 	}
-	
-	end_frame = last_frame;
 }
 
Index: kernel/arch/ia32/src/mm/page.c
===================================================================
--- kernel/arch/ia32/src/mm/page.c	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/src/mm/page.c	(revision c1f7f6eaa570166428a8687a4e9c7cd839cd666d)
@@ -35,6 +35,4 @@
 #include <arch/mm/page.h>
 #include <genarch/mm/page_pt.h>
-#include <genarch/drivers/ega/ega.h>
-#include <genarch/drivers/legacy/ia32/io.h>
 #include <arch/mm/frame.h>
 #include <mm/frame.h>
@@ -51,9 +49,4 @@
 #include <print.h>
 #include <interrupt.h>
-#include <ddi/ddi.h>
-
-/** Physical memory area for devices. */
-static parea_t dev_area;
-static parea_t ega_area;
 
 void page_arch_init(void)
@@ -61,5 +54,5 @@
 	uintptr_t cur;
 	int flags;
-
+	
 	if (config.cpu_active == 1) {
 		page_mapping_operations = &pt_mapping_operations;
@@ -74,10 +67,10 @@
 			page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
 		}
-
+		
 		exc_register(14, "page_fault", (iroutine) page_fault);
 		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 	} else
 		write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
-
+	
 	paging_on();
 }
@@ -99,15 +92,4 @@
 	
 	return virtaddr;
-}
-
-void hw_area(void)
-{
-	dev_area.pbase = end_frame;
-	dev_area.frames = SIZE2FRAMES(0xffffffff - end_frame);
-	ddi_parea_register(&dev_area);
-	
-	ega_area.pbase = EGA_VIDEORAM;
-	ega_area.frames = SIZE2FRAMES(EGA_VRAM_SIZE);
-	ddi_parea_register(&ega_area);
 }
 
