diff --git a/boot/common/bootinfo.inc b/boot/common/bootinfo.inc
index e628c8c..0382330 100644
--- a/boot/common/bootinfo.inc
+++ b/boot/common/bootinfo.inc
@@ -23,6 +23,16 @@ boot_info_add_memmap:
 	jbe @f
 	ret
 @@:
+
+	; ----------------------------------------------------------------------
+	; dirty hack - TODO: clean this mess
+	cmp eax, 0x100000
+	jne @f
+	mov [boot_structure.high_mem], edx
+@@:
+	; end hack
+	; ----------------------------------------------------------------------
+
 	push ebx
 	xor ecx, ecx
 .loop:
diff --git a/kernel/kernel.asm b/kernel/kernel.asm
index 053235a..a216787 100644
--- a/kernel/kernel.asm
+++ b/kernel/kernel.asm
@@ -28,6 +28,7 @@ kmain:
 	mov ecx, sizeof.BootInfo
 	mov esi, ebx
 	mov edi, boot_structure
+	rep movsb
 
 	; print hello world 
 	mov [0xC00B8000], dword 0x08740953
@@ -46,6 +47,11 @@ kmain:
 	; init vmm
 	call mm_init
 
+	mov eax, 0xC0400000
+	mov ebx, [boot_structure.high_mem]
+	add ebx, KERNEL_VIRT_BASE
+	call pmm_free_range
+
 	; map whole memory
 
 	;  idt, gdt
diff --git a/kernel/mm/mm.inc b/kernel/mm/mm.inc
index 0e53c97..d47b1b6 100644
--- a/kernel/mm/mm.inc
+++ b/kernel/mm/mm.inc
@@ -37,28 +37,26 @@ macro KV2P reg {
 }
 
 	;; Macro: KP2V
+	;; Convert physical address to virtual
 macro KP2V reg {
 	add reg, KERNEL_VIRT_BASE
 }
 
+	;; Function: mm_kmap
 mm_kmap:
-	ret
-
-	;; Function: mm_init
-mm_init:
-	mov esi, szMsgMmInit
-	call klog
+	push esp
+	mov ebp, esp
+	sub esp, 0x10
 
 	call pmm_alloc_page
-	mov [pKernelPgDir], eax
+	mov [ebp-4], eax
 
 	; clear page dir
+	mov edi, eax
 	mov ecx, 4096
 	xor al, al
-	mov edi, [pKernelPgDir]
 	rep stosb
 
-	;; Map kernel and kmemory
 	call pmm_alloc_page
 	xor esi, esi
 	xor ecx, ecx
@@ -74,13 +72,52 @@ mm_init:
 	jb @b
 
 	or eax, (PDE_P or PDE_W)
-	mov edx, [pKernelPgDir]
+	mov edx, [ebp-4]
 	add edx, (768 * 4)
 	KV2P eax
 	mov [edx], eax
 
-	;; Map free memory
+	mov eax, [ebp-4]
 
+	leave
+	ret
+
+	;; Function: mm_init
+mm_init:
+	mov esi, szMsgMmInit
+	call klog
+
+	call mm_kmap
+	mov [pKernelPgDir], eax
+
+	; map whole memory 
+	mov esi, 0x400000
+	mov ebx, (769 * 4)
+.loop:
+	call pmm_alloc_page
+	xor ecx, ecx
+	mov edi, eax
+@@:
+	mov edx, esi
+	or edx, (PTE_P or PTE_W)
+	mov [edi], edx
+	add edi, 4
+	add esi, 4096
+	inc ecx
+	cmp ecx, 1024
+	jb @b
+
+	or eax, (PDE_P or PDE_W)
+	mov edx, [pKernelPgDir]
+	add edx, ebx
+	add ebx, 4
+	KV2P eax
+	mov [edx], eax
+
+	cmp esi, [boot_structure.high_mem]
+	jb .loop
+
+	; reload cr3
 	mov eax, [pKernelPgDir]
 	KV2P eax
 	mov cr3, eax
@@ -91,6 +128,12 @@ mm_init:
 
 	ret
 
+mm_alloc:
+	ret
+
+mm_dealloc:
+	ret
+
 mm_wallk_pagedir:
 	ret
 
diff --git a/kernel/mm/pmm.inc b/kernel/mm/pmm.inc
index e5bc4b7..1e2c5be 100644
--- a/kernel/mm/pmm.inc
+++ b/kernel/mm/pmm.inc
@@ -1,5 +1,18 @@
 	;; File: pmm.inc
 
+macro ALIGN reg {
+	local end
+
+	push reg
+	and reg, 0xFFF
+	pop reg
+	jz end
+	and reg, 0xFFFFF000
+	add reg, 0x1000
+end:
+
+}
+
 	;; Function: pmm_init
 	;; 
 	;; In:
@@ -55,6 +68,8 @@ pmm_free_range:
 	push ebp
 	mov ebp, esp
 	sub esp, 0x10
+	ALIGN eax
+	ALIGN ebx
 	mov [ebp-4], eax
 	mov [ebp-8], ebx
 
diff --git a/kernel/sys/bootinfo.inc b/kernel/sys/bootinfo.inc
index 3ee34dc..913b613 100644
--- a/kernel/sys/bootinfo.inc
+++ b/kernel/sys/bootinfo.inc
@@ -13,6 +13,7 @@ struc BootInfo {
 	.mmap         dd 4*2*20 dup(0)
 	.kernel_start dd ?
 	.kernel_size  dd ?
+	.high_mem     dd ?
 }
 virtual at 0
   BootInfo BootInfo