Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision 1b0673154d95f4f1bd78a65c9fc775c3cbe11cc8)
+++ kernel/generic/include/config.h	(revision 8ccd2ea277c15d5df7f5e27ff901bafaa18515df)
@@ -70,5 +70,4 @@
 
 	uintptr_t base;
-	size_t memory_size;		/**< Size of detected memory in bytes. */
 	size_t kernel_size;		/**< Size of memory in bytes taken by kernel and stack */
 	
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision 1b0673154d95f4f1bd78a65c9fc775c3cbe11cc8)
+++ kernel/generic/include/macros.h	(revision 8ccd2ea277c15d5df7f5e27ff901bafaa18515df)
@@ -67,4 +67,7 @@
 #define PA_overlaps(x, szx, y, szy)	overlaps(KA2PA(x), szx, KA2PA(y), szy)
 
+#define SIZE2KB(size) (size >> 10)
+#define SIZE2MB(size) (size >> 20)
+
 #define STRING(arg) STRING_ARG(arg)
 #define STRING_ARG(arg) #arg
Index: kernel/generic/include/mm/frame.h
===================================================================
--- kernel/generic/include/mm/frame.h	(revision 1b0673154d95f4f1bd78a65c9fc775c3cbe11cc8)
+++ kernel/generic/include/mm/frame.h	(revision 8ccd2ea277c15d5df7f5e27ff901bafaa18515df)
@@ -85,4 +85,9 @@
 }
 
+static inline size_t FRAMES2SIZE(count_t frames)
+{
+	return (size_t) (frames << FRAME_WIDTH);
+}
+
 #define IS_BUDDY_ORDER_OK(index, order)		\
 	((~(((unative_t) -1) << (order)) & (index)) == 0)
@@ -105,10 +110,11 @@
 
 extern int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags);
-void *frame_get_parent(pfn_t frame, unsigned int hint);
-void frame_set_parent(pfn_t frame, void *data, unsigned int hint);
-void frame_mark_unavailable(pfn_t start, count_t count);
-uintptr_t zone_conf_size(count_t count);
-void zone_merge(unsigned int z1, unsigned int z2);
-void zone_merge_all(void);
+extern void *frame_get_parent(pfn_t frame, unsigned int hint);
+extern void frame_set_parent(pfn_t frame, void *data, unsigned int hint);
+extern void frame_mark_unavailable(pfn_t start, count_t count);
+extern uintptr_t zone_conf_size(count_t count);
+extern void zone_merge(unsigned int z1, unsigned int z2);
+extern void zone_merge_all(void);
+extern uint64_t zone_total_size(void);
 
 /*
@@ -116,5 +122,5 @@
  */
 extern void zone_print_list(void);
-void zone_print_one(unsigned int znum);
+extern void zone_print_one(unsigned int znum);
 
 #endif
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 1b0673154d95f4f1bd78a65c9fc775c3cbe11cc8)
+++ kernel/generic/src/main/main.c	(revision 8ccd2ea277c15d5df7f5e27ff901bafaa18515df)
@@ -64,5 +64,4 @@
 #include <align.h>
 #include <interrupt.h>
-#include <arch/mm/memory_init.h>
 #include <mm/frame.h>
 #include <mm/page.h>
@@ -144,6 +143,4 @@
 	
 	config.base = hardcoded_load_address;
-	config.memory_size = get_memory_size();
-	
 	config.kernel_size = ALIGN_UP(hardcoded_ktext_size +
 	    hardcoded_kdata_size, PAGE_SIZE);
@@ -220,20 +217,20 @@
 	ddi_init();
 	arch_post_mm_init();
-
+	
 	version_print();
-	printf("kernel: %.*p hardcoded_ktext_size=%zdK, "
-	    "hardcoded_kdata_size=%zdK\n", sizeof(uintptr_t) * 2,
-	    config.base, hardcoded_ktext_size >> 10,
-	    hardcoded_kdata_size >> 10);
-	printf("stack:  %.*p size=%zdK\n", sizeof(uintptr_t) * 2,
-	    config.stack_base, config.stack_size >> 10);
-
+	printf("kernel: %.*p hardcoded_ktext_size=%zd KB, "
+	    "hardcoded_kdata_size=%zd KB\n", sizeof(uintptr_t) * 2,
+		config.base, SIZE2KB(hardcoded_ktext_size),
+		SIZE2KB(hardcoded_kdata_size));
+	printf("stack:  %.*p size=%zd KB\n", sizeof(uintptr_t) * 2,
+	    config.stack_base, SIZE2KB(config.stack_size));
+	
 	arch_pre_smp_init();
 	smp_init();
 	/* Slab must be initialized after we know the number of processors. */
 	slab_enable_cpucache();
-
-	printf("config.memory_size=%zdM\n", config.memory_size >> 20);
-	printf("config.cpu_count=%zd\n", config.cpu_count);
+	
+	printf("Detected %zu CPU(s), %llu MB free memory\n",
+		config.cpu_count, SIZE2MB(zone_total_size()));
 	cpu_init();
 	
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 1b0673154d95f4f1bd78a65c9fc775c3cbe11cc8)
+++ kernel/generic/src/mm/frame.c	(revision 8ccd2ea277c15d5df7f5e27ff901bafaa18515df)
@@ -105,17 +105,21 @@
 
 
-/*********************************/
+/********************/
 /* Helper functions */
+/********************/
+
 static inline index_t frame_index(zone_t *zone, frame_t *frame)
 {
-	return (index_t)(frame - zone->frames);
-}
+	return (index_t) (frame - zone->frames);
+}
+
 static inline index_t frame_index_abs(zone_t *zone, frame_t *frame)
 {
-	return (index_t)(frame - zone->frames) + zone->base;
-}
+	return (index_t) (frame - zone->frames) + zone->base;
+}
+
 static inline int frame_index_valid(zone_t *zone, index_t index)
 {
-	return index >= 0 && index < zone->count;
+	return (index >= 0) && (index < zone->count);
 }
 
@@ -123,5 +127,5 @@
 static index_t make_frame_index(zone_t *zone, frame_t *frame)
 {
-	return frame - zone->frames;
+	return (frame - zone->frames);
 }
 
@@ -138,6 +142,7 @@
 }
 
-/*************************************/
+/**********************/
 /* Zoneinfo functions */
+/**********************/
 
 /**
@@ -155,12 +160,17 @@
 	ipl = interrupts_disable();
 	spinlock_lock(&zones.lock);
+	
 	/* Try to merge */
-	if (zones.count + 1 == ZONES_MAX)
-		panic("Maximum zone(%d) count exceeded.", ZONES_MAX);
+	if (zones.count + 1 == ZONES_MAX) {
+		printf("Maximum zone count %u exceeded!\n", ZONES_MAX);
+		spinlock_unlock(&zones.lock);
+		interrupts_restore(ipl);
+		return -1;
+	}
+	
 	for (i = 0; i < zones.count; i++) {
 		/* Check for overflow */
 		z = zones.info[i];
-		if (overlaps(newzone->base,newzone->count, z->base,
-		    z->count)) {
+		if (overlaps(newzone->base, newzone->count, z->base, z->count)) {
 			printf("Zones overlap!\n");
 			return -1;
@@ -169,9 +179,12 @@
 			break;
 	}
+	
 	/* Move other zones up */
 	for (j = i; j < zones.count; j++)
 		zones.info[j + 1] = zones.info[j];
+	
 	zones.info[i] = newzone;
 	zones.count++;
+	
 	spinlock_unlock(&zones.lock);
 	interrupts_restore(ipl);
@@ -182,7 +195,7 @@
 /**
  * Try to find a zone where can we find the frame
- 
+ *
  * Assume interrupts are disabled.
- 
+ *
  * @param frame Frame number contained in zone
  * @param pzone If not null, it is used as zone hint. Zone index
@@ -901,5 +914,5 @@
 	}
 
-	z = (zone_t *)PA2KA(PFN2ADDR(confframe));
+	z = (zone_t *) PA2KA(PFN2ADDR(confframe));
 	zone_construct(start, count, z, flags);
 	znum = zones_add_zone(z);
@@ -1110,4 +1123,30 @@
 
 
+/** Return total size of all zones
+ *
+ */
+uint64_t zone_total_size(void) {
+	zone_t *zone = NULL;
+	unsigned int i;
+	ipl_t ipl;
+	uint64_t total = 0;
+
+	ipl = interrupts_disable();
+	spinlock_lock(&zones.lock);
+	
+	for (i = 0; i < zones.count; i++) {
+		zone = zones.info[i];
+		spinlock_lock(&zone->lock);
+		total += (uint64_t) FRAMES2SIZE(zone->count);
+		spinlock_unlock(&zone->lock);
+	}
+	
+	spinlock_unlock(&zones.lock);
+	interrupts_restore(ipl);
+	
+	return total;
+}
+
+
 
 /** Prints list of zones
@@ -1161,5 +1200,5 @@
 
 	for (i = 0; i < zones.count; i++) {
-		if (i == num || PFN2ADDR(zones.info[i]->base) == num) {
+		if ((i == num) || (PFN2ADDR(zones.info[i]->base) == num)) {
 			zone = zones.info[i];
 			break;
@@ -1175,13 +1214,13 @@
 	printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2,
 	    PFN2ADDR(zone->base));
-	printf("Zone size: %zd frames (%zdK)\n", zone->count,
-	    ((zone->count) * FRAME_SIZE) >> 10);
-	printf("Allocated space: %zd frames (%zdK)\n", zone->busy_count,
-	    (zone->busy_count * FRAME_SIZE) >> 10);
-	printf("Available space: %zd frames (%zdK)\n", zone->free_count,
-	    (zone->free_count * FRAME_SIZE) >> 10);
+	printf("Zone size: %zd frames (%zd KB)\n", zone->count,
+		SIZE2KB(FRAMES2SIZE(zone->count)));
+	printf("Allocated space: %zd frames (%zd KB)\n", zone->busy_count,
+		SIZE2KB(FRAMES2SIZE(zone->busy_count)));
+	printf("Available space: %zd frames (%zd KB)\n", zone->free_count,
+		SIZE2KB(FRAMES2SIZE(zone->free_count)));
 	buddy_system_structure_print(zone->buddy_system, FRAME_SIZE);
-	
 	spinlock_unlock(&zone->lock);
+	
 out:
 	spinlock_unlock(&zones.lock);
