Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision cae54046b82d245b0cf3dad7ced8e4d5d09d006e)
+++ kernel/arch/ia32/src/mm/frame.c	(revision 720db0cb39d8d5d31bf09f36c79eb82c68f03d68)
@@ -47,5 +47,5 @@
 #include <print.h>
 
-#define PHYSMEM_LIMIT  0x7C000000
+#define PHYSMEM_LIMIT  0x7C000000ull
 
 size_t hardcoded_unmapped_ktext_size = 0;
@@ -88,11 +88,12 @@
 #endif
 		
-		pfn_t pfn;
-		size_t count;
-		
 		if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) {
-			/* To be safe, make available zone possibly smaller */
-			pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE));
-			count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE));
+			/* To be safe, make the available zone possibly smaller */
+			uint64_t new_base = ALIGN_UP(base, FRAME_SIZE);
+			uint64_t new_size = ALIGN_DOWN(size - (new_base - base),
+			    FRAME_SIZE);
+			
+			pfn_t pfn = ADDR2PFN(new_base);
+			size_t count = SIZE2FRAMES(new_size);
 			
 			pfn_t conf;
@@ -105,22 +106,26 @@
 			
 			// XXX this has to be removed
-			if (last_frame < ALIGN_UP(base + size, FRAME_SIZE))
-				last_frame = ALIGN_UP(base + size, FRAME_SIZE);
+			if (last_frame < ALIGN_UP(new_base + new_size, FRAME_SIZE))
+				last_frame = ALIGN_UP(new_base + new_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));
+			/* To be safe, make the reserved zone possibly larger */
+			uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE);
+			uint64_t new_size = ALIGN_UP(size + (base - new_base),
+			    FRAME_SIZE);
 			
-			zone_create(pfn, count, 0, ZONE_RESERVED);
+			zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 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));
+			/* To be safe, make the firmware zone possibly larger */
+			uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE);
+			uint64_t new_size = ALIGN_UP(size + (base - new_base),
+			    FRAME_SIZE);
 			
-			zone_create(pfn, count, 0, ZONE_FIRMWARE);
+			zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0,
+			    ZONE_FIRMWARE);
 		}
 	}
Index: kernel/arch/ppc32/src/mm/frame.c
===================================================================
--- kernel/arch/ppc32/src/mm/frame.c	(revision cae54046b82d245b0cf3dad7ced8e4d5d09d006e)
+++ kernel/arch/ppc32/src/mm/frame.c	(revision 720db0cb39d8d5d31bf09f36c79eb82c68f03d68)
@@ -60,19 +60,23 @@
 	
 	for (i = 0; i < memmap.cnt; i++) {
-		pfn_t start = ADDR2PFN(ALIGN_UP((uintptr_t) memmap.zones[i].start,
-		    FRAME_SIZE));
-		size_t size = SIZE2FRAMES(ALIGN_DOWN(memmap.zones[i].size, FRAME_SIZE));
+		/* To be safe, make the available zone possibly smaller */
+		uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+		    FRAME_SIZE);
+		size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
+		    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
+		
+		pfn_t pfn = ADDR2PFN(new_start);
+		size_t count = SIZE2FRAMES(new_size);
 		
 		pfn_t conf;
-		if ((minconf < start) || (minconf >= start + size))
-			conf = start;
+		if ((minconf < pfn) || (minconf >= pfn + count))
+			conf = pfn;
 		else
 			conf = minconf;
 		
-		zone_create(start, size, conf, 0);
-		if (last_frame < ALIGN_UP((uintptr_t) memmap.zones[i].start
-		    + memmap.zones[i].size, FRAME_SIZE))
-			last_frame = ALIGN_UP((uintptr_t) memmap.zones[i].start
-			    + memmap.zones[i].size, FRAME_SIZE);
+		zone_create(pfn, count, conf, 0);
+		
+		if (last_frame < ALIGN_UP(new_start + new_size, FRAME_SIZE))
+			last_frame = ALIGN_UP(new_start + new_size, FRAME_SIZE);
 	}
 	
Index: kernel/arch/sparc64/src/mm/sun4u/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision cae54046b82d245b0cf3dad7ced8e4d5d09d006e)
+++ kernel/arch/sparc64/src/mm/sun4u/frame.c	(revision 720db0cb39d8d5d31bf09f36c79eb82c68f03d68)
@@ -49,27 +49,30 @@
 void frame_arch_init(void)
 {
-	unsigned int i;
-	pfn_t confdata;
-
 	if (config.cpu_active == 1) {
+		unsigned int i;
+		
 		for (i = 0; i < memmap.cnt; i++) {
-			uintptr_t start = (uintptr_t) memmap.zones[i].start;
-			size_t size = memmap.zones[i].size;
-
+			/* To be safe, make the available zone possibly smaller */
+			uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+			    FRAME_SIZE);
+			size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
+			    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
+			
 			/*
 			 * The memmap is created by HelenOS boot loader.
 			 * It already contains no holes.
 			 */
-
-			confdata = ADDR2PFN(start);
+			
+			pfn_t confdata = ADDR2PFN(new_start);
+			
 			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
 				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
-			zone_create(ADDR2PFN(start),
-			    SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
+			
+			zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),
 			    confdata, 0);
-			last_frame = max(last_frame, start + ALIGN_UP(size,
-			    FRAME_SIZE));
+			
+			last_frame = max(last_frame, new_start + new_size);
 		}
-
+		
 		/*
 		 * On sparc64, physical memory can start on a non-zero address.
@@ -80,5 +83,5 @@
 		frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
 	}
-
+	
 	end_of_identity = PA2KA(last_frame);
 }
Index: kernel/arch/sparc64/src/mm/sun4v/frame.c
===================================================================
--- kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision cae54046b82d245b0cf3dad7ced8e4d5d09d006e)
+++ kernel/arch/sparc64/src/mm/sun4v/frame.c	(revision 720db0cb39d8d5d31bf09f36c79eb82c68f03d68)
@@ -47,25 +47,28 @@
 void frame_arch_init(void)
 {
-	unsigned int i;
-	pfn_t confdata;
-
 	if (config.cpu_active == 1) {
+		unsigned int i;
+		
 		for (i = 0; i < memmap.cnt; i++) {
-			uintptr_t start = (uintptr_t) memmap.zones[i].start;
-			size_t size = memmap.zones[i].size;
-
+			/* To be safe, make the available zone possibly smaller */
+			uintptr_t new_start = ALIGN_UP((uintptr_t) memmap.zones[i].start,
+			    FRAME_SIZE);
+			size_t new_size = ALIGN_DOWN(memmap.zones[i].size -
+			    (new_start - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE);
+			
 			/*
 			 * The memmap is created by HelenOS boot loader.
 			 * It already contains no holes.
 			 */
-
-			confdata = ADDR2PFN(start);
+			
+			pfn_t confdata = ADDR2PFN(new_start);
+			
 			if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
 				confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
-			zone_create(ADDR2PFN(start),
-			    SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
+			
+			zone_create(ADDR2PFN(new_start), SIZE2FRAMES(new_size),
 			    confdata, 0);
 		}
-
+		
 		/*
 		 * On sparc64, physical memory can start on a non-zero address.
