Index: kernel/arch/ia32/include/types.h
===================================================================
--- kernel/arch/ia32/include/types.h	(revision aecf79fdaee472e18edbe8432718b356d591c455)
+++ kernel/arch/ia32/include/types.h	(revision c59dd1a2d9e5081afa75cef4614ee394981aa341)
@@ -62,3 +62,2 @@
 /** @}
  */
-
Index: kernel/arch/xen32/include/asm.h
===================================================================
--- kernel/arch/xen32/include/asm.h	(revision aecf79fdaee472e18edbe8432718b356d591c455)
+++ kernel/arch/xen32/include/asm.h	(revision c59dd1a2d9e5081afa75cef4614ee394981aa341)
@@ -155,11 +155,11 @@
 static inline ipl_t interrupts_enable(void)
 {
-	ipl_t v;
-	__asm__ volatile (
+	ipl_t v = 0;
+/*	__asm__ volatile (
 		"pushf\n\t"
 		"popl %0\n\t"
 		"sti\n"
 		: "=r" (v)
-	);
+	);*/
 	return v;
 }
@@ -174,11 +174,11 @@
 static inline ipl_t interrupts_disable(void)
 {
-	ipl_t v;
-	__asm__ volatile (
+	ipl_t v = 0;
+/*	__asm__ volatile (
 		"pushf\n\t"
 		"popl %0\n\t"
 		"cli\n"
 		: "=r" (v)
-	);
+	);*/
 	return v;
 }
@@ -192,9 +192,9 @@
 static inline void interrupts_restore(ipl_t ipl)
 {
-	__asm__ volatile (
+/*	__asm__ volatile (
 		"pushl %0\n\t"
 		"popf\n"
 		: : "r" (ipl)
-	);
+	);*/
 }
 
@@ -205,10 +205,10 @@
 static inline ipl_t interrupts_read(void)
 {
-	ipl_t v;
-	__asm__ volatile (
+	ipl_t v = 0;
+/*	__asm__ volatile (
 		"pushf\n\t"
 		"popl %0\n"
 		: "=r" (v)
-	);
+	);*/
 	return v;
 }
Index: kernel/arch/xen32/include/boot/boot.h
===================================================================
--- kernel/arch/xen32/include/boot/boot.h	(revision aecf79fdaee472e18edbe8432718b356d591c455)
+++ kernel/arch/xen32/include/boot/boot.h	(revision c59dd1a2d9e5081afa75cef4614ee394981aa341)
@@ -47,14 +47,14 @@
 	char magic[32];             /**< "xen-<version>-<platform>" */
 	unsigned long nr_pages;     /**< Total pages allocated to this domain */
-	unsigned long shared_info;  /**< Physical address of shared info struct */
+	void *shared_info;          /**< Machine address of shared info struct */
 	uint32_t flags;             /**< SIF_xxx flags */
-	unsigned long store_mfn;    /**< Physical page number of shared page */
+	void *store_mfn;            /**< Machine page number of shared page */
 	uint32_t store_evtchn;      /**< Event channel for store communication */
-	unsigned long console_mfn;  /**< Physical address of console page */
+	void *console_mfn;          /**< Machine address of console page */
 	uint32_t console_evtchn;    /**< Event channel for console messages */
-	unsigned long pt_base;      /**< Virtual address of page directory */
+	unsigned long *pt_base;     /**< Virtual address of page directory */
 	unsigned long nr_pt_frames; /**< Number of bootstrap p.t. frames */
-	unsigned long mfn_list;     /**< Virtual address of page-frame list */
-	unsigned long mod_start;    /**< Virtual address of pre-loaded module */
+	unsigned long *mfn_list;    /**< Virtual address of page-frame list */
+	void *mod_start;            /**< Virtual address of pre-loaded module */
 	unsigned long mod_len;      /**< Size (bytes) of pre-loaded module */
 	int8_t cmd_line[GUEST_CMDLINE];
Index: kernel/arch/xen32/include/hypercall.h
===================================================================
--- kernel/arch/xen32/include/hypercall.h	(revision aecf79fdaee472e18edbe8432718b356d591c455)
+++ kernel/arch/xen32/include/hypercall.h	(revision c59dd1a2d9e5081afa75cef4614ee394981aa341)
@@ -34,5 +34,27 @@
 
 
+typedef uint16_t domid_t;
+
+typedef struct {
+    uint64_t ptr;  /**< Machine address of PTE */
+    uint64_t val;  /**< New contents of PTE */
+} mmu_update_t;
+
+typedef struct {
+    unsigned int cmd;
+    union {
+        unsigned long mfn;
+        unsigned long linear_addr;
+    } arg1;
+    union {
+        unsigned int nr_ents;
+        void *vcpumask;
+    } arg2;
+} mmuext_op_t;
+
+
+#define XEN_MMU_UPDATE	1
 #define XEN_CONSOLE_IO	18
+#define XEN_MMUEXT_OP	26
 
 
@@ -44,4 +66,25 @@
 
 
+#define MMUEXT_PIN_L1_TABLE      0
+#define MMUEXT_PIN_L2_TABLE      1
+#define MMUEXT_PIN_L3_TABLE      2
+#define MMUEXT_PIN_L4_TABLE      3
+#define MMUEXT_UNPIN_TABLE       4
+#define MMUEXT_NEW_BASEPTR       5
+#define MMUEXT_TLB_FLUSH_LOCAL   6
+#define MMUEXT_INVLPG_LOCAL      7
+#define MMUEXT_TLB_FLUSH_MULTI   8
+#define MMUEXT_INVLPG_MULTI      9
+#define MMUEXT_TLB_FLUSH_ALL    10
+#define MMUEXT_INVLPG_ALL       11
+#define MMUEXT_FLUSH_CACHE      12
+#define MMUEXT_SET_LDT          13
+#define MMUEXT_NEW_USER_BASEPTR 15
+
+
+#define DOMID_SELF (0x7FF0U)
+#define DOMID_IO   (0x7FF1U)
+
+
 #define hypercall0(id)	\
 	({	\
@@ -142,8 +185,18 @@
 
 
-static inline int xen_console_io(const int cmd, const int count, const char *str)
+static inline int xen_console_io(const unsigned int cmd, const unsigned int count, const char *str)
 {
 	return hypercall3(XEN_CONSOLE_IO, cmd, count, str);
 }
 
+static inline int xen_mmu_update(const mmu_update_t *req, const unsigned int count, unsigned int *success_count, domid_t domid)
+{
+	return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid);
+}
+
+static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, unsigned int *success_count, domid_t domid)
+{
+	return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid);
+}
+
 #endif
Index: kernel/arch/xen32/src/mm/frame.c
===================================================================
--- kernel/arch/xen32/src/mm/frame.c	(revision aecf79fdaee472e18edbe8432718b356d591c455)
+++ kernel/arch/xen32/src/mm/frame.c	(revision c59dd1a2d9e5081afa75cef4614ee394981aa341)
@@ -39,4 +39,5 @@
 #include <config.h>
 #include <arch/boot/boot.h>
+#include <arch/hypercall.h>
 #include <panic.h>
 #include <debug.h>
@@ -44,5 +45,4 @@
 #include <macros.h>
 
-#include <print.h>
 #include <console/cmd.h>
 #include <console/kconsole.h>
@@ -50,9 +50,91 @@
 uintptr_t last_frame = 0;
 
+#define L1_PT_SHIFT	10
+#define L2_PT_SHIFT	0
+
+#define L1_OFFSET_MASK			0x3ff
+#define L2_OFFSET_MASK			0x3ff
+
+#define PFN2PTL1_OFFSET(pfn)	((pfn >> L1_PT_SHIFT) & L1_OFFSET_MASK)
+#define PFN2PTL2_OFFSET(pfn)	((pfn >> L2_PT_SHIFT) & L2_OFFSET_MASK)
+
+#define PAGE_MASK	(~(PAGE_SIZE - 1))
+
+#define PTE2ADDR(pte)	(pte & PAGE_MASK)
+
+#define _PAGE_PRESENT	0x001UL
+#define _PAGE_RW		0x002UL
+#define _PAGE_USER		0x004UL
+#define _PAGE_PWT		0x008UL
+#define _PAGE_PCD		0x010UL
+#define _PAGE_ACCESSED	0x020UL
+#define _PAGE_DIRTY		0x040UL
+#define _PAGE_PAT		0x080UL
+#define _PAGE_PSE		0x080UL
+#define _PAGE_GLOBAL	0x100UL
+
+#define L1_PROT	(_PAGE_PRESENT | _PAGE_ACCESSED)
+#define L2_PROT	(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
+
 void frame_arch_init(void)
 {
 	if (config.cpu_active == 1) {
+		/* The only memory zone starts just after page table */
 		pfn_t start = ADDR2PFN(ALIGN_UP(KA2PA(start_info.pt_base), PAGE_SIZE)) + start_info.nr_pt_frames;
 		size_t size = start_info.nr_pages - start;
+		
+		/* Create identity mapping */
+		pfn_t phys;
+		for (phys = start; phys < start + size; phys++) {
+			mmu_update_t updates[1];
+			pfn_t virt = ADDR2PFN(PA2KA(PFN2ADDR(phys)));
+			
+			size_t ptl1_offset = PFN2PTL1_OFFSET(virt);
+			size_t ptl2_offset = PFN2PTL2_OFFSET(virt);
+			
+			unsigned long *ptl2_base = (unsigned long *) PTE2ADDR(start_info.pt_base[ptl1_offset]);
+			
+			if (ptl2_base == 0) {
+				mmuext_op_t mmu_ext;
+				
+				pfn_t virt2 = ADDR2PFN(PA2KA(PFN2ADDR(start)));
+				
+				/* New L1 page table entry needed */
+				memsetb(PFN2ADDR(virt2), PAGE_SIZE, 0);
+				
+				size_t ptl1_offset2 = PFN2PTL1_OFFSET(virt2);
+				size_t ptl2_offset2 = PFN2PTL2_OFFSET(virt2);
+				unsigned long *ptl2_base2 = (unsigned long *) PTE2ADDR(start_info.pt_base[ptl1_offset2]);
+				
+				if (ptl2_base2 == 0)
+					panic("Unable to find page table reference");
+				
+				updates[0].ptr = (uintptr_t) &ptl2_base2[ptl2_offset2];
+				updates[0].val = PFN2ADDR(start_info.mfn_list[start]) | L1_PROT;
+				if (xen_mmu_update(updates, 1, NULL, DOMID_SELF) < 0)
+					panic("Unable to map new page table");
+				
+				mmu_ext.cmd = MMUEXT_PIN_L1_TABLE;
+				mmu_ext.arg1.mfn = start_info.mfn_list[start];
+				if (xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) < 0)
+					panic("Error pinning new page table");
+				
+				unsigned long *ptl0 = (unsigned long *) PFN2ADDR(start_info.mfn_list[ADDR2PFN(KA2PA(start_info.pt_base))]);
+				
+				updates[0].ptr = (uintptr_t) &ptl0[ptl1_offset];
+				updates[0].val = PFN2ADDR(start_info.mfn_list[start]) | L2_PROT;
+				if (xen_mmu_update(updates, 1, NULL, DOMID_SELF) < 0)
+					panic("Unable to update PTE for page table");
+				
+				ptl2_base = (unsigned long *) PTE2ADDR(start_info.pt_base[ptl1_offset]);
+				start++;
+				size--;
+			}
+			
+			updates[0].ptr = (uintptr_t) &ptl2_base[ptl2_offset];
+			updates[0].val = PFN2ADDR(start_info.mfn_list[phys]) | L2_PROT;
+			if (xen_mmu_update(updates, 1, NULL, DOMID_SELF) < 0)
+				panic("Unable to update PTE");
+		}
 		
 		zone_create(start, size, start, 0);
Index: kernel/arch/xen32/src/mm/page.c
===================================================================
--- kernel/arch/xen32/src/mm/page.c	(revision aecf79fdaee472e18edbe8432718b356d591c455)
+++ kernel/arch/xen32/src/mm/page.c	(revision c59dd1a2d9e5081afa75cef4614ee394981aa341)
@@ -69,11 +69,11 @@
 
 		exc_register(14, "page_fault", (iroutine) page_fault);
-		write_cr3((uintptr_t) AS_KERNEL->page_table);
+//		write_cr3((uintptr_t) AS_KERNEL->page_table);
 	}
 	else {
-		write_cr3((uintptr_t) AS_KERNEL->page_table);
+//		write_cr3((uintptr_t) AS_KERNEL->page_table);
 	}
 
-	paging_on();
+//	paging_on();
 }
 
