Index: kernel/arch/ia32/include/boot/memmap.h
===================================================================
--- kernel/arch/ia32/include/boot/memmap.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/include/boot/memmap.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32	
+/** @addtogroup ia32
  * @{
  */
@@ -36,21 +36,26 @@
 #define KERN_ia32_MEMMAP_H_
 
-/* E820h memory range types - other values*/
-	/* Free memory */
-#define MEMMAP_MEMORY_AVAILABLE	1
-	/* Not available for OS */
-#define MEMMAP_MEMORY_RESERVED	2 
-	/* OS may use it after reading ACPI table */
-#define MEMMAP_MEMORY_ACPI	3 
-	/* Unusable, required to be saved and restored across an NVS sleep */
-#define MEMMAP_MEMORY_NVS	4 
-	/* Corrupted memory */
-#define MEMMAP_MEMORY_UNUSABLE	5 
+/* E820h memory range types */
 
-	 /* size of one entry */
-#define MEMMAP_E820_RECORD_SIZE 20 
-	/* maximum entries */
-#define MEMMAP_E820_MAX_RECORDS 32 
+/* Free memory */
+#define MEMMAP_MEMORY_AVAILABLE  1
 
+/* Not available for OS */
+#define MEMMAP_MEMORY_RESERVED   2
+
+/* OS may use it after reading ACPI table */
+#define MEMMAP_MEMORY_ACPI       3
+
+/* Unusable, required to be saved and restored across an NVS sleep */
+#define MEMMAP_MEMORY_NVS        4
+
+/* Corrupted memory */
+#define MEMMAP_MEMORY_UNUSABLE   5
+
+/* Size of one entry */
+#define MEMMAP_E820_RECORD_SIZE  20
+
+/* Maximum entries */
+#define MEMMAP_E820_MAX_RECORDS  32
 
 #ifndef __ASM__
Index: kernel/arch/ia32/include/mm/frame.h
===================================================================
--- kernel/arch/ia32/include/mm/frame.h	(revision 5f0f29ce3c25993ee100bdb9354b66dc6b762ae7)
+++ kernel/arch/ia32/include/mm/frame.h	(revision e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
@@ -36,6 +36,6 @@
 #define KERN_ia32_FRAME_H_
 
-#define FRAME_WIDTH	12	/* 4K */
-#define FRAME_SIZE	(1 << FRAME_WIDTH)
+#define FRAME_WIDTH  12  /* 4K */
+#define FRAME_SIZE   (1 << FRAME_WIDTH)
 
 #ifdef KERNEL
@@ -45,5 +45,4 @@
 
 extern uintptr_t last_frame;
-extern uintptr_t end_frame;
 
 extern void frame_arch_init(void);
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 e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -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 e49e2348e7647a4dd4d4e2879082790396c4f4f3)
@@ -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);
 }
 
