Index: arch/amd64/src/mm/page.c
===================================================================
--- arch/amd64/src/mm/page.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ arch/amd64/src/mm/page.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -45,5 +45,5 @@
 
 	if (config.cpu_active == 1) {
-		dba = frame_alloc(FRAME_KA | FRAME_PANIC);
+		dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
 		memsetb(dba, PAGE_SIZE, 0);
 
@@ -68,5 +68,5 @@
 		 */
 
-		dba = frame_alloc(FRAME_KA | FRAME_PANIC);
+		dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
 		memcpy((void *)dba, (void *)bootstrap_dba , PAGE_SIZE);
 		write_cr3(KA2PA(dba));
Index: arch/ia32/src/mm/frame.c
===================================================================
--- arch/ia32/src/mm/frame.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ arch/ia32/src/mm/frame.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -34,4 +34,5 @@
 #include <arch/boot/memmap.h>
 #include <panic.h>
+#include <debug.h>
 
 size_t hardcoded_unmapped_ktext_size = 0;
@@ -41,21 +42,21 @@
 {
 	zone_t *z;
+	__address start, stop;
+	size_t size;
 	__u8 i;
 	
 	if (config.cpu_active == 1) {
+
+		/* Reserve frame 0 (BIOS data) */
+		frame_region_not_free(0, FRAME_SIZE);
+		
+		/* Reserve real mode bootstrap memory */
+		frame_region_not_free(BOOTSTRAP_OFFSET, hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
+		
 		for (i=0;i<e820counter;i++) {
 			if (e820table[i].type==MEMMAP_MEMORY_AVAILABLE) {
-				z = zone_create(e820table[i].base_address, e820table[i].size & ~(FRAME_SIZE-1), 0);
-				if (!z) {
-					panic("Cannot allocate zone (%dB).\n", e820table[i].size & ~(FRAME_SIZE-1));
-				}
-				zone_attach(z);
+				zone_create_in_region(e820table[i].base_address,  e820table[i].size & ~(FRAME_SIZE-1));
 			}
 		}
-		
-		frame_not_free(0);
-
-		/* Reserve real mode bootstrap memory */
-                frame_region_not_free(BOOTSTRAP_OFFSET, BOOTSTRAP_OFFSET + hardcoded_unmapped_ktext_size + hardcoded_unmapped_kdata_size);
 	}
 }
Index: arch/ia32/src/mm/page.c
===================================================================
--- arch/ia32/src/mm/page.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ arch/ia32/src/mm/page.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -48,5 +48,5 @@
 
 	if (config.cpu_active == 1) {
-		dba = frame_alloc(FRAME_KA | FRAME_PANIC);
+		dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
 		memsetb(dba, PAGE_SIZE, 0);
 
@@ -70,5 +70,5 @@
 		 */
 
-		dba = frame_alloc(FRAME_KA | FRAME_PANIC);
+		dba = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
 		memcpy((void *)dba, (void *)bootstrap_dba , PAGE_SIZE);
 		write_cr3(KA2PA(dba));
Index: arch/ia64/src/mm/frame.c
===================================================================
--- arch/ia64/src/mm/frame.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ arch/ia64/src/mm/frame.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -34,10 +34,4 @@
 void frame_arch_init(void)
 {
-	zone_t *z;
-	
-	z = zone_create(0, config.memory_size, 0);
-	if (!z) {
-		panic("Can't allocate zone (%dB).\n", config.memory_size);
-	}
-	zone_attach(z);
+        zone_create_in_region(0, config.memory_size & ~(FRAME_SIZE-1));
 }
Index: arch/mips32/src/mm/frame.c
===================================================================
--- arch/mips32/src/mm/frame.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ arch/mips32/src/mm/frame.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -33,16 +33,10 @@
 #include <config.h>
 #include <panic.h>
+#include <print.h>
 
 void frame_arch_init(void)
 {
-	zone_t *z;
-	
-	z = zone_create(0, config.memory_size, 0);
-	if (!z) {
-		panic("Can't allocate zone (%dB).\n", config.memory_size);
-	}
-	zone_attach(z);
-
 	/* Disable Everything until load address */
-	frame_region_not_free(0, KA2PA(KERNEL_LOAD_ADDRESS));
+	frame_region_not_free(0, KA2PA(KERNEL_LOAD_ADDRESS) + FRAME_SIZE);
+        zone_create_in_region(0, config.memory_size & ~(FRAME_SIZE-1));
 }
Index: arch/mips32/src/mm/page.c
===================================================================
--- arch/mips32/src/mm/page.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ arch/mips32/src/mm/page.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -40,5 +40,5 @@
 	__address ptl0;
 	
-	ptl0 = frame_alloc(FRAME_KA | FRAME_PANIC);
+	ptl0 = frame_alloc(FRAME_KA | FRAME_PANIC, 0);
 	memsetb(ptl0, FRAME_SIZE, 0);
 	
Index: arch/ppc32/src/mm/frame.c
===================================================================
--- arch/ppc32/src/mm/frame.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ arch/ppc32/src/mm/frame.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -34,10 +34,4 @@
 void frame_arch_init(void)
 {
-        zone_t *z;
-
-        z = zone_create(0, config.memory_size & ~(FRAME_SIZE-1), 0);
-        if (!z) {
-                panic("Can't allocate zone (%dB).\n", config.memory_size & ~(FRAME_SIZE-1));
-        }
-        zone_attach(z);
+	zone_create_in_region(0, config.memory_size & ~(FRAME_SIZE-1));
 }
Index: generic/include/mm/buddy.h
===================================================================
--- generic/include/mm/buddy.h	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/include/mm/buddy.h	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -42,4 +42,5 @@
 	void (*set_order)(buddy_system_t *, link_t *, __u8);		/**< Set order of block passed as argument. */
 	__u8 (*get_order)(buddy_system_t *, link_t *);			/**< Return order of block passed as argument. */
+	void (*mark_busy)(buddy_system_t *, link_t *);			/**< Mark block as busy */
 };
 
@@ -53,4 +54,5 @@
 extern buddy_system_t *buddy_system_create(__u8 max_order, buddy_system_operations_t *op, void *data);
 extern link_t *buddy_system_alloc(buddy_system_t *b, __u8 i);
+extern bool buddy_system_can_alloc(buddy_system_t *b, __u8 order);
 extern void buddy_system_free(buddy_system_t *b, link_t *block);
 
Index: generic/include/mm/frame.h
===================================================================
--- generic/include/mm/frame.h	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/include/mm/frame.h	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -43,8 +43,9 @@
 #define ADDR2FRAME(zone, addr)			(&((zone)->frames[((addr) - (zone)->base) / FRAME_SIZE]))
 #define FRAME_INDEX(zone, frame)		((count_t)((frame) - (zone)->frames))
-#define IS_BUDDY_LEFT_BLOCK(zone, frame)	((FRAME_INDEX((zone), (frame)) % (1 >> ((frame)->buddy_order + 1))) == 0)
-#define IS_BUDDY_RIGHT_BLOCK(zone, frame)	((FRAME_INDEX((zone), (frame)) % (1 >> ((frame)->buddy_order + 1))) == (1 >> (frame)->buddy_order))
+#define FRAME_INDEX_VALID(zone, index)		(((index) >= 0) && ((index) < ((zone)->free_count + (zone)->busy_count)))
+#define IS_BUDDY_LEFT_BLOCK(zone, frame)	((FRAME_INDEX((zone), (frame)) % (1 << ((frame)->buddy_order + 1))) == 0)
+#define IS_BUDDY_RIGHT_BLOCK(zone, frame)	((FRAME_INDEX((zone), (frame)) % (1 << ((frame)->buddy_order + 1))) == (1 << (frame)->buddy_order))
 
-
+#define ZONE_BLACKLIST_SIZE	3
 
 struct zone {
@@ -69,4 +70,14 @@
 };
 
+struct region {
+	__address base;
+	size_t size;
+};
+
+extern region_t zone_blacklist[];
+extern count_t zone_blacklist_count;
+extern void frame_region_not_free(__address base, size_t size);
+extern void zone_create_in_region(__address base, size_t size);
+
 extern spinlock_t zone_head_lock;	/**< this lock protects zone_head list */
 extern link_t zone_head;		/**< list of all zones in the system */
@@ -78,8 +89,6 @@
 extern void frame_init(void);
 extern void frame_initialize(frame_t *frame, zone_t *zone);
-__address frame_alloc(int flags);
+__address frame_alloc(int flags, __u8 order);
 extern void frame_free(__address addr);
-extern void frame_not_free(__address addr);
-extern void frame_region_not_free(__address start, __address stop);
 zone_t * get_zone_by_frame(frame_t * frame);
 
@@ -92,7 +101,5 @@
 void zone_buddy_set_order(buddy_system_t *b, link_t * block, __u8 order);
 __u8 zone_buddy_get_order(buddy_system_t *b, link_t * block);
-
-__address zone_buddy_frame_alloc(int flags, __u8 order);
-void zone_buddy_frame_free(__address addr);
+void zone_buddy_mark_busy(buddy_system_t *b, link_t * block);
 
 /*
Index: generic/include/typedefs.h
===================================================================
--- generic/include/typedefs.h	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/include/typedefs.h	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -69,4 +69,5 @@
 typedef struct zone zone_t;
 typedef struct frame frame_t;
+typedef struct region region_t;
 
 typedef enum vm_type vm_type_t;
Index: generic/src/cpu/cpu.c
===================================================================
--- generic/src/cpu/cpu.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/src/cpu/cpu.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -61,5 +61,5 @@
 
 		for (i=0; i < config.cpu_count; i++) {
-			cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC);
+			cpus[i].stack = (__u8 *) frame_alloc(FRAME_KA | FRAME_PANIC,0);
 			if (!cpus[i].stack)
 				panic("malloc/cpus[%d].stack\n", i);
Index: generic/src/mm/buddy.c
===================================================================
--- generic/src/mm/buddy.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/src/mm/buddy.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -34,4 +34,5 @@
 #include <list.h>
 #include <debug.h>
+#include <print.h>
 
 /** Create buddy system
@@ -57,4 +58,5 @@
 	ASSERT(op->bisect);
 	ASSERT(op->coalesce);
+	ASSERT(op->mark_busy);
 
 	/*
@@ -84,4 +86,26 @@
 }
 
+/** Check if buddy system can allocate block
+ *
+ * @param b Buddy system pointer
+ * @param i Size of the block (2^i)
+ *
+ * @return True if block can be allocated
+ */
+bool buddy_system_can_alloc(buddy_system_t *b, __u8 i) {
+	__u8 k;
+	
+	ASSERT(i < b->max_order);
+	
+	for (k=i; k < b->max_order; k++) {
+		if (!list_empty(&b->order[k])) {
+			return true;
+		}
+	}
+	
+	return false;
+	
+}
+
 /** Allocate block from buddy system.
  *
@@ -104,4 +128,5 @@
 		res = b->order[i].next;
 		list_remove(res);
+		b->op->mark_busy(b, res);
 		return res;
 	}
@@ -137,5 +162,7 @@
 	/*
 	 * Return the other half to buddy system.
-	 */
+	 * PROBLEM!!!! FILL FIND OTHER PART AS BUDDY AND LINK TOGETHER
+	 */
+	b->op->mark_busy(b, res);
 	buddy_system_free(b, hlp);
 	
@@ -153,5 +180,5 @@
 	link_t *buddy, *hlp;
 	__u8 i;
-	
+
 	/*
 	 * Determine block's order.
@@ -169,5 +196,4 @@
 
 			ASSERT(b->op->get_order(b, buddy) == i);
-		
 			/*
 			 * Remove buddy from the list of order i.
Index: generic/src/mm/frame.c
===================================================================
--- generic/src/mm/frame.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/src/mm/frame.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -38,7 +38,11 @@
 #include <arch/asm.h>
 #include <arch.h>
+#include <print.h>
 
 spinlock_t zone_head_lock;       /**< this lock protects zone_head list */
 link_t zone_head;                /**< list of all zones in the system */
+
+region_t zone_blacklist[ZONE_BLACKLIST_SIZE];
+count_t zone_blacklist_count = 0;
 
 static struct buddy_system_operations  zone_buddy_system_operations = {
@@ -48,4 +52,5 @@
 	.set_order = zone_buddy_set_order,
 	.get_order = zone_buddy_get_order,
+	.mark_busy = zone_buddy_mark_busy,
 };
 
@@ -58,11 +63,8 @@
 	if (config.cpu_active == 1) {
 		zone_init();
+		frame_region_not_free(config.base, config.base + config.kernel_size + CONFIG_STACK_SIZE);
 	}
 
 	frame_arch_init();
-	
-	if (config.cpu_active == 1) {
-                frame_region_not_free(config.base, config.base + config.kernel_size + CONFIG_STACK_SIZE);
-        }	
 }
 
@@ -75,5 +77,5 @@
  * @return Allocated frame.
  */
-__address frame_alloc(int flags)
+__address frame_alloc(int flags, __u8 order) 
 {
 	ipl_t ipl;
@@ -87,5 +89,5 @@
 	ipl = interrupts_disable();
 	spinlock_lock(&zone_head_lock);
-	
+
 	/*
 	 * First, find suitable frame zone.
@@ -95,11 +97,11 @@
 		
 		spinlock_lock(&z->lock);
-		/*
-		 * Check if the zone has any free frames.
-		 */
-		if (z->free_count) {
+
+		/* Check if the zone has 2^order frames area available  */
+		if (buddy_system_can_alloc(z->buddy_system, order)) {
 			zone = z;
 			break;
 		}
+		
 		spinlock_unlock(&z->lock);
 	}
@@ -119,24 +121,22 @@
 	}
 		
-	tmp = zone->free_head.next;
-	frame = list_get_instance(tmp, frame_t, link);
-
-	frame->refcount++;
-	list_remove(tmp);			/* remove frame from free_head */
-	zone->free_count--;
-	zone->busy_count++;
-	
-	//v = zone->base + (frame - zone->frames) * FRAME_SIZE;
+
+	/* Allocate frames from zone buddy system */
+	cur = buddy_system_alloc(zone->buddy_system, order);
+	
+	/* frame will be actually a first frame of the block */
+	frame = list_get_instance(cur, frame_t, buddy_link);
+	
+	/* get frame address */
 	v = FRAME2ADDR(zone, frame);
-	
+
 	if (flags & FRAME_KA)
 		v = PA2KA(v);
 	
 	spinlock_unlock(&zone->lock);
-	
 	spinlock_unlock(&zone_head_lock);
 	interrupts_restore(ipl);
-	
 	return v;
+
 }
 
@@ -156,5 +156,4 @@
 	zone_t *zone = NULL;
 	frame_t *frame;
-	
 	ASSERT(addr % FRAME_SIZE == 0);
 	
@@ -186,11 +185,9 @@
 	
 	frame = ADDR2FRAME(zone, addr);
-	// frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
+
 	ASSERT(frame->refcount);
 
 	if (!--frame->refcount) {
-		list_append(&frame->link, &zone->free_head);	/* append frame to free_head */
-		zone->free_count++;
-		zone->busy_count--;
+		buddy_system_free(zone->buddy_system, &frame->buddy_link);
 	}
 	
@@ -201,64 +198,4 @@
 }
 
-/** Mark frame not free.
- *
- * Find respective frame structrue for supplied addr.
- * Increment frame reference count and remove the frame structure from free list.
- *
- * @param addr Address of the frame to be marked. It must be a multiple of FRAME_SIZE.
- */
-void frame_not_free(__address addr)
-{
-	ipl_t ipl;
-	link_t *cur;
-	zone_t *z;
-	zone_t *zone = NULL;
-	frame_t *frame;
-	
-	ASSERT(addr % FRAME_SIZE == 0);
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&zone_head_lock);
-	
-	/*
-	 * First, find host frame zone for addr.
-	 */
-	for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
-		z = list_get_instance(cur, zone_t, link);
-		
-		spinlock_lock(&z->lock);
-		
-		if (IS_KA(addr))
-			addr = KA2PA(addr);
-		
-		/*
-		 * Check if addr belongs to z.
-		 */
-		if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
-			zone = z;
-			break;
-		}
-		spinlock_unlock(&z->lock);
-	}
-	
-	ASSERT(zone != NULL);
-	
-	//frame = &zone->frames[(addr - zone->base)/FRAME_SIZE];
-	frame = ADDR2FRAME(zone, addr);
-
-	if (!frame->refcount) {
-		frame->refcount++;
-
-		list_remove(&frame->link);			/* remove frame from free_head */
-		zone->free_count--;
-		zone->busy_count++;
-	}
-	
-	spinlock_unlock(&zone->lock);	
-	
-	spinlock_unlock(&zone_head_lock);
-	interrupts_restore(ipl);
-}
-
 /** Mark frame region not free.
  *
@@ -268,12 +205,17 @@
  * @param stop Last address.
  */
-void frame_region_not_free(__address start, __address stop)
-{
-        __address a;
-
-        start /= FRAME_SIZE;
-        stop /= FRAME_SIZE;
-        for (a = start; a <= stop; a++)
-                frame_not_free(a * FRAME_SIZE);
+void frame_region_not_free(__address base, size_t size)
+{
+	count_t index;
+	index = zone_blacklist_count++;
+	ASSERT(base % FRAME_SIZE == 0);
+	
+	if (size % FRAME_SIZE != 0) {
+		size = size + (FRAME_SIZE - size % FRAME_SIZE);
+	}
+	ASSERT(size % FRAME_SIZE == 0);
+	ASSERT(zone_blacklist_count <= ZONE_BLACKLIST_SIZE);
+	zone_blacklist[index].base = base;
+	zone_blacklist[index].size = size;
 }
 
@@ -288,4 +230,41 @@
 	list_initialize(&zone_head);
 }
+
+
+void zone_create_in_region(__address base, size_t size) {
+	int i;
+	zone_t * z;
+	__address s; size_t sz;
+	
+	ASSERT(base % FRAME_SIZE == 0);
+	ASSERT(size % FRAME_SIZE == 0);
+	
+	if (!size) return;
+	
+	for (i = 0; i < zone_blacklist_count; i++) {
+		if (zone_blacklist[i].base >= base && zone_blacklist[i].base < base + size) {
+			s = base; sz = zone_blacklist[i].base - base;
+			ASSERT(base != s || sz != size);
+			zone_create_in_region(s, sz);
+			
+			s = zone_blacklist[i].base + zone_blacklist[i].size;
+			sz = (base + size) - (zone_blacklist[i].base + zone_blacklist[i].size);
+			ASSERT(base != s || sz != size);
+			zone_create_in_region(s, sz);
+			return;
+		
+		}
+	}
+	
+	z = zone_create(base, size, 0);
+
+	if (!z) {
+		panic("Cannot allocate zone (%dB).\n", size);
+	}
+	
+	zone_attach(z);
+}
+
+
 
 /** Create frame zone
@@ -299,5 +278,5 @@
  * @return Initialized zone.
  */
-zone_t *zone_create(__address start, size_t size, int flags)
+zone_t * zone_create(__address start, size_t size, int flags)
 {
 	zone_t *z;
@@ -305,5 +284,9 @@
 	int i;
 	__u8 max_order;
-	
+
+	/* hack for bug #10 */
+	// if (start == 0x100000) size -= (FRAME_SIZE * 256);
+
+	// printf("ZONE_CREATE()   %X - %X (%d kbytes)			\n", start, start+size, size/1024);	
 	ASSERT(start % FRAME_SIZE == 0);
 	ASSERT(size % FRAME_SIZE == 0);
@@ -340,6 +323,11 @@
 		for (max_order = 0; cnt >> max_order; max_order++);
 		z->buddy_system = buddy_system_create(max_order, &zone_buddy_system_operations, (void *) z);
-	}
-	
+		
+		/* Stuffing frames */
+		for (i = 0; i<cnt; i++) {
+			z->frames[i].refcount = 0;
+			buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);	
+		}
+	}
 	return z;
 }
@@ -373,173 +361,9 @@
 void frame_initialize(frame_t *frame, zone_t *zone)
 {
-	frame->refcount = 0;
+	frame->refcount = 1;
+	frame->buddy_order = 0;
 	link_initialize(&frame->link);
 }
 
-
-
-/*
- * buddy system functions (under construction)
- * 
- */
-
-
-/** Allocate 2^order frames
- *
- */
-__address zone_buddy_frame_alloc(int flags, __u8 order) {
-	ipl_t ipl;
-	link_t *cur, *tmp;
-	zone_t *z;
-	zone_t *zone = NULL;
-	frame_t *frame = NULL;
-	__address v;
-	
-loop:
-	ipl = interrupts_disable();
-	spinlock_lock(&zone_head_lock);
-	
-	/*
-	 * First, find suitable frame zone.
-	 */
-	for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
-		z = list_get_instance(cur, zone_t, link);
-		
-		spinlock_lock(&z->lock);
-		/*
-		 * Check if the zone has 2^order frames area available
-		 * TODO: Must check if buddy system has at least block in order >= given order
-		 */
-		if (z->free_count == (1 >> order)) { 
-			zone = z;
-			break;
-		}
-		
-		spinlock_unlock(&z->lock);
-	}
-	
-	if (!zone) {
-		if (flags & FRAME_PANIC)
-			panic("Can't allocate frame.\n");
-		
-		/*
-		 * TODO: Sleep until frames are available again.
-		 */
-		spinlock_unlock(&zone_head_lock);
-		interrupts_restore(ipl);
-
-		panic("Sleep not implemented.\n");
-		goto loop;
-	}
-		
-
-	/* Allocate frames from zone buddy system */
-	cur = buddy_system_alloc(zone->buddy_system, order);
-	
-	/* frame will be actually a first frame of the block */
-	frame = list_get_instance(cur, frame_t, buddy_link);
-	
-	/* get frame address */
-	v = FRAME2ADDR(zone, frame);
-	
-	if (flags & FRAME_KA)
-		v = PA2KA(v);
-	
-	spinlock_unlock(&zone->lock);
-	spinlock_unlock(&zone_head_lock);
-	interrupts_restore(ipl);
-	
-	return v;
-}
-
-
-/** Free frame(s)
- *
- * @param addr Address of the frame(s) to be freed. It must be a multiple of FRAME_SIZE.
- */
-void zone_buddy_frame_free(__address addr)
-{
-	ipl_t ipl;
-	link_t *cur;
-	zone_t *z;
-	zone_t *zone = NULL;
-	frame_t *frame;
-	
-	ASSERT(addr % FRAME_SIZE == 0);
-	
-	ipl = interrupts_disable();
-	spinlock_lock(&zone_head_lock);
-	
-	/*
-	 * First, find host frame zone for addr.
-	 */
-	for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
-		z = list_get_instance(cur, zone_t, link);
-		
-		spinlock_lock(&z->lock);
-		
-		if (IS_KA(addr))
-			addr = KA2PA(addr);
-		
-		/*
-		 * Check if addr belongs to z.
-		 */
-		if ((addr >= z->base) && (addr <= z->base + (z->free_count + z->busy_count) * FRAME_SIZE)) {
-			zone = z;
-			break;
-		}
-		spinlock_unlock(&z->lock);
-	}
-	
-	ASSERT(zone != NULL);
-	
-	frame = ADDR2FRAME(zone, addr);
-
-	ASSERT(frame->refcount);
-
-	if (!--frame->refcount) {
-		buddy_system_free(zone->buddy_system, &frame->buddy_link);
-	}
-	
-	spinlock_unlock(&zone->lock);	
-	
-	spinlock_unlock(&zone_head_lock);
-	interrupts_restore(ipl);
-}
-
-/** Guess zone by frame instance address
- *
- * @param frame Frame
- *
- * @return Zone of given frame
- */
-zone_t * get_zone_by_frame(frame_t * frame) {
-	link_t * cur;
-	zone_t * zone, *z;
-
-	ASSERT(frame);
-	/*
-	 * First, find host frame zone for addr.
-	 */
-	for (cur = zone_head.next; cur != &zone_head; cur = cur->next) {
-		z = list_get_instance(cur, zone_t, link);
-		
-		spinlock_lock(&z->lock);
-		
-		/*
-		 * Check if frame address belongs to z.
-		 */
-		if ((frame >= z->frames) && (frame <= z->frames + (z->free_count + z->busy_count))) {
-			zone = z;
-			break;
-		}
-		spinlock_unlock(&z->lock);
-	}
-	ASSERT(zone);
-	
-	return zone;
-
-
-}
 
 /** Buddy system find_buddy implementation
@@ -554,9 +378,9 @@
 	zone_t * zone;
 	link_t * cur;
+	count_t index;
 	bool is_left, is_right;
 
 	frame = list_get_instance(block, frame_t, buddy_link);
-	zone = get_zone_by_frame(frame);
-	
+	zone = (zone_t *) b->data;
 	
 	/* 
@@ -564,5 +388,5 @@
 	 * (FRAME_INDEX % 2^(ORDER+1)) == 2^(ORDER) ===> RIGHT BUDDY
 	 */
-	 
+
 	is_left = IS_BUDDY_LEFT_BLOCK(zone, frame);
 	is_right = IS_BUDDY_RIGHT_BLOCK(zone, frame);
@@ -570,27 +394,21 @@
 	ASSERT((is_left || is_right) && (!is_left || !is_right));
 	
-	for (cur = &zone->buddy_system->order[frame->buddy_order]; cur; cur = cur->next) {
-		f = list_get_instance(cur, frame_t, buddy_link);
-		
-		ASSERT(f->buddy_order == frame->buddy_order);
-		
-		/* 
-		 * if found frame is coherent with our frame from the left 
-		 */
-		if ((FRAME_INDEX(zone, f) + 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_right) {
-			return cur;
-		}
-		
-		/* 
-		 * if found frame is coherent with our frame from the right 
-		 */
-		if ((FRAME_INDEX(zone,f) - 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_left) {
-			return cur;
-		}
-		
+	/*
+	 * test left buddy
+	 */
+	if (is_left) {
+		index = (FRAME_INDEX(zone, frame)) + (1 << frame->buddy_order);
+	} else if (is_right) {
+		index = (FRAME_INDEX(zone, frame)) - (1 << frame->buddy_order);
+	}
+	
+	if (FRAME_INDEX_VALID(zone, index)) {
+		if (	zone->frames[index].buddy_order == frame->buddy_order && 
+			zone->frames[index].refcount == 0) {
+			return &zone->frames[index].buddy_link;
+		}
 	}
 	
 	return NULL;
-	
 	
 }
@@ -605,11 +423,7 @@
 link_t * zone_buddy_bisect(buddy_system_t *b, link_t * block) {
 	frame_t * frame_l, * frame_r;
-	
 	frame_l = list_get_instance(block, frame_t, buddy_link);
-
-	frame_r = (frame_t *) (&frame_l + (1>>frame_l->buddy_order-1));
-
+	frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
 	return &frame_r->buddy_link;
-	
 }
 
@@ -624,9 +438,7 @@
 link_t * zone_buddy_coalesce(buddy_system_t *b, link_t * block_1, link_t * block_2) {
 	frame_t * frame1, * frame2;
-	
 	frame1 = list_get_instance(block_1, frame_t, buddy_link);
 	frame2 = list_get_instance(block_2, frame_t, buddy_link);
-	
-	return &frame1 < &frame2 ? block_1 : block_2;
+	return frame1 < frame2 ? block_1 : block_2;
 }
 
@@ -655,2 +467,14 @@
 	return frame->buddy_order;
 }
+
+/** Buddy system mark_busy implementation
+ *
+ * @param b Buddy system
+ * @param block Buddy system block
+ *
+ */
+void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) {
+	frame_t * frame;
+	frame = list_get_instance(block, frame_t, buddy_link);
+	frame->refcount = 1;
+}
Index: generic/src/mm/page.c
===================================================================
--- generic/src/mm/page.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/src/mm/page.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -80,5 +80,5 @@
 
 	if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = frame_alloc(FRAME_KA);
+		newpt = frame_alloc(FRAME_KA, 0);
 		memsetb(newpt, PAGE_SIZE, 0);
 		SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
@@ -89,5 +89,5 @@
 
 	if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = frame_alloc(FRAME_KA);
+		newpt = frame_alloc(FRAME_KA, 0);
 		memsetb(newpt, PAGE_SIZE, 0);
 		SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
@@ -98,5 +98,5 @@
 
 	if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
-		newpt = frame_alloc(FRAME_KA);
+		newpt = frame_alloc(FRAME_KA, 0);
 		memsetb(newpt, PAGE_SIZE, 0);
 		SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
Index: generic/src/mm/vm.c
===================================================================
--- generic/src/mm/vm.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/src/mm/vm.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -70,5 +70,5 @@
 		
 			src_ptl0 = (pte_t *) PA2KA((__address) GET_PTL0_ADDRESS());
-			dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC);
+			dst_ptl0 = (pte_t *) frame_alloc(FRAME_KA | FRAME_PANIC, 0);
 
 //			memsetb((__address) dst_ptl0, PAGE_SIZE, 0);
@@ -116,5 +116,5 @@
 		
 		for (i=0; i<size; i++)
-			a->mapping[i] = frame_alloc(0);
+			a->mapping[i] = frame_alloc(0,0);
 		
 		spinlock_initialize(&a->lock);
Index: generic/src/proc/thread.c
===================================================================
--- generic/src/proc/thread.c	(revision d7ac642a8ebe46655e453a1113dbb2fda847fbd1)
+++ generic/src/proc/thread.c	(revision 328f2934a2a54acf4fd30f747291bf5e58f9d7a2)
@@ -176,7 +176,7 @@
 		spinlock_initialize(&t->lock);
 	
-		frame_ks = frame_alloc(FRAME_KA);
+		frame_ks = frame_alloc(FRAME_KA,0);
 		if (THREAD_USER_STACK & flags) {
-			frame_us = frame_alloc(FRAME_KA);
+			frame_us = frame_alloc(FRAME_KA,0);
 		}
 
