diff --git a/Kernel/arch/arm7/include/mm_virt.h b/Kernel/arch/arm7/include/mm_virt.h
index abbbe6c724db70eb57f957a5c6bcf0a71d6b20d6..27bfbfded0e1310ff57615fb78a89527a41666db 100644
--- a/Kernel/arch/arm7/include/mm_virt.h
+++ b/Kernel/arch/arm7/include/mm_virt.h
@@ -5,23 +5,32 @@
 #ifndef _MM_VIRT_H_
 #define _MM_VIRT_H_
 
-#define KERNEL_BASE	0x80000000	// 2GiB
-
 #define MM_USER_MIN	0x00001000
 #define USER_LIB_MAX	0x7F800000
-#define MM_PPD_VFS	0x7F800000
+#define MM_PPD_HANDLES	0x7F800000
+#define MM_TABLE0USER	0x7F900000	// 2 GiB - 16 KiB
+#define MM_TABLE1USER	0x7FC00000	// 2 GiB - 4 MiB
 
 // Page Blocks are 12-bits wide (12 address bits used)
 // Hence, the table is 16KiB large (and must be so aligned)
 // and each block addresses 1MiB of data
 
+// First level table is aligned to 16KiB (restriction of TTBR reg)
+// - VMSAv6 uses two TTBR regs, determined by bit 31
+
+#define KERNEL_BASE	0x80000000	// 2GiB
+
 #define MM_KHEAP_BASE	0x80800000	// 8MiB of kernel code
-#define MM_KHEAP_MAX	0xC0000000	// 1GiB of kernel heap
+#define MM_KHEAP_MAX	0xC0000000	// ~1GiB of kernel heap
 
-#define MM_MODULE_MIN	0xC0000000
+#define MM_MODULE_MIN	0xC0000000	// - 0xD0000000
 #define MM_MODULE_MAX	0xD0000000
 
-#define MM_KERNEL_VFS	0xFF800000	// 
-#define MM_FRACTAL	0xFFE00000	// 2nd last block
+#define MM_KHEAP_MIN	0xE0000000
+#define MM_KHEAP_MAX	0xF0000000
+
+#define MM_KERNEL_VFS	0xFF000000	// 
+#define MM_TABLE1KERN	0xFF800000	// - 0x???????? 4MiB
+#define MM_TABLE0KERN	0xFFC00000	// - 0xFFE04000 16KiB
 
 #endif
diff --git a/Kernel/arch/arm7/mm_phys.c b/Kernel/arch/arm7/mm_phys.c
new file mode 100644
index 0000000000000000000000000000000000000000..76a8880929c1b27ccaf6440e9d5c0ccc8573c8a1
--- /dev/null
+++ b/Kernel/arch/arm7/mm_phys.c
@@ -0,0 +1,6 @@
+/*
+ * Acess2
+ *
+ * ARM7 Physical Memory Manager
+ * arch/arm7/mm_phys.c
+ */
diff --git a/Kernel/arch/arm7/mm_virt.c b/Kernel/arch/arm7/mm_virt.c
new file mode 100644
index 0000000000000000000000000000000000000000..218dc85e74690d01e12ca47b59e26902311cdbc6
--- /dev/null
+++ b/Kernel/arch/arm7/mm_virt.c
@@ -0,0 +1,115 @@
+/*
+ * Acess2
+ * 
+ * ARM7 Virtual Memory Manager
+ * - arch/arm7/mm_virt.c
+ */
+#include <mm_virt.h>
+
+// === TYPES ===
+typedef struct
+{
+	tPAddr	PhysAddr;
+	Uint8	Size;
+	Uint8	Domain;
+} tMM_PageInfo;
+
+// === GLOBALS ===
+Uint32	*gMM_KernelTable0 = (void*)MM_TABLE0KERN;
+Uint32	*gMM_KernelTable1 = (void*)MM_TABLE1KERN;
+
+// === CODE ===
+int MM_InitialiseVirtual(void)
+{
+}
+
+int MM_int_GetPageInfo(tVAddr VAddr, tMM_PageInfo *pi)
+{
+	Uint32	*table0, table1;
+	Uint32	desc;
+
+	if(VAddr & 0x80000000 ) {
+		table0 = MM_TABLE0KERN;
+		table1 = MM_TABLE1KERN;
+	}
+	else {
+		table0 = MM_TABLE0USER;
+		table1 = MM_TABLE1USER;
+	}
+	VAddr & 0x7FFFFFFF;
+
+	desc = table0[ VAddr >> 20 ];
+
+	switch( (desc & 3) )
+	{
+	// 0: Unmapped
+	case 0:
+		pi->PhysAddr = 0;
+		pi->Size = 20;
+		pi->Domain = 0;
+		return 1;
+
+	// 1: Coarse page table
+	case 1:
+		// Domain from top level table
+		pi->Domain = (desc >> 5) & 7;
+		// Get next level
+		desc = table1[ VAddr >> 12 ];
+		switch( desc & 3 )
+		{
+		// 0: Unmapped
+		case 0:	
+			pi->Size = 12;
+			return 1;
+		// 1: Large Page (64KiB)
+		case 1:
+			pi->Size = 16;
+			pi->PhysAddr = desc & 0xFFFF0000;
+			return 0;
+		// 2/3: Small page
+		case 2:
+		case 3:
+			pi->Size = 12;
+			pi->PhysAddr = desc & 0xFFFFF000;
+			pi->bExecutable = desc & 1;
+			pi->bGlobal = !(desc >> 11);
+			pi->bSharec = (desc >> 10) & 1;
+			return 1;
+		}
+		return 1;
+	
+	// 2: Section (or Supersection)
+	case 2:
+		if( desc & (1 << 18) ) {
+			// Supersection
+			pi->PhysAddr = desc & 0xFF000000;
+			pi->PhysAddr |= ((desc >> 20) & 0xF) << 32;
+			pi->PhysAddr |= ((desc >> 5) & 0x7) << 36;
+			pi->Size = 24;
+			pi->Domain = 0;	// Superpages default to zero
+			return 0;
+		}
+		
+		// Section
+		pi->PhysAddr = desc & 0xFFF80000;
+		pi->Size = 20;
+		pi->Domain = (desc >> 5) & 7;
+		return 0;
+
+	// 3: Reserved (invalid)
+	case 3:
+		pi->PhysAddr = 0;
+		pi->Size = 20;
+		pi->Domain = 0;
+		return 2;
+	}
+}
+
+// --- Exports ---
+tPAddr MM_GetPhysAddr(tVAddr VAddr)
+{
+	tMM_PageInfo	pi;
+	if( MM_int_GetPageInfo(VAddr, &pi) )
+		return 0;
+	return pi.PhysAddr;
+}