diff --git a/bootloader-legacy/Makefile b/bootloader-legacy/Makefile
index ce6142a3fe43fb3407c00dc7d4e2c76796b12804..8fa0ceedd9f63dadef517e984786b05031cca5c4 100644
--- a/bootloader-legacy/Makefile
+++ b/bootloader-legacy/Makefile
@@ -1,6 +1,11 @@
 build:
 	nasm -f bin boot.asm -o boot.img
 
+build_x86:
+
+build_x86_64:
+
+
 run: build
 	qemu-system-x86_64 boot.img
 
diff --git a/bootloader-legacy/README.md b/bootloader-legacy/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c32922a2fcfbe03ff9155b65f9b047a6885cfa26
--- /dev/null
+++ b/bootloader-legacy/README.md
@@ -0,0 +1,36 @@
+# notes
+
+## register usage rule
+
+volatile (caller saved): rax, rcx, rdx
+
+non-volatile: others
+
+arguments and return value: rax, rcx, rdx, stack
+
+## bootloader(legacy) memory model
+
+- common
+
+0x7c00 - 0x7e00 : bootloader.img, executes from beginning 0x7c00  
+0x7e00 - 0x17c00 : kernel.img, called by bootloader, from beginning 0x7e00
+
+- bios age
+
+![](../res/1.png)
+
+- 32bit protected mode age
+
+Just used this mode to launch 64bit long mode. No paging enabled. 
+
+- 64bit long mode age
+
+0x1000 - 0x5000 : 64bit long mode paging table**s**
+0x00100000 - 0x00300000 : 512 * 4K pages, before kernel initializing page table in C++.
+
+## bootloader(legacy) disk model
+
+0-511Byte : bootloader.img from boot.asm, MBR flag  
+512B - 64KiB : kernel.img. executes from 512Byte first instruction. 
+
+
diff --git a/bootloader-legacy/x64lib.inc b/bootloader-legacy/x64lib.inc
new file mode 100644
index 0000000000000000000000000000000000000000..4193e86e9f8dd17adc90197c63246b4052b0f2f6
--- /dev/null
+++ b/bootloader-legacy/x64lib.inc
@@ -0,0 +1,122 @@
+
+; requires: str.32.inc
+; runs in 32bit protection mode
+
+test_cpuid_support:
+    ; Check if CPUID is supported by attempting to flip the ID bit (bit 21) in
+    ; the FLAGS register. If we can flip it, CPUID is available.
+ 
+    ; Copy FLAGS in to EAX via stack
+    pushfd
+    pop eax
+ 
+    ; Copy to ECX as well for comparing later on
+    mov ecx, eax
+ 
+    ; Flip the ID bit
+    xor eax, 1 << 21
+ 
+    ; Copy EAX to FLAGS via the stack
+    push eax
+    popfd
+ 
+    ; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported)
+    pushfd
+    pop eax
+ 
+    ; Restore FLAGS from the old version stored in ECX (i.e. flipping the ID bit
+    ; back if it was ever flipped).
+    push ecx
+    popfd
+ 
+    ; Compare EAX and ECX. If they are equal then that means the bit wasn't
+    ; flipped, and CPUID isn't supported.
+    sub eax, ecx
+    ; eax != 0 if CPUID supported, eax==0 if not supported. 
+    ret
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+test_support_long_mode:
+    ; test if possible to enter x64 mode. 
+    ; return value in eax. 
+    ; return 0 = OK. 1 = CPUID_NOT_AVAIL, 2 = CPUID_EXT_NOT_AVAIL, 3 = LONGMODE_NOT_AVAIL
+    call test_cpuid_support
+    cmp eax, 0
+    jne _cpuid_supported
+    mov eax, 1
+    ret
+_cpuid_supported:
+    mov eax, 0x80000000     ; Set the A-register to 0x80000000.
+    cpuid                   ; CPU identification.
+    cmp eax, 0x80000001     ; Compare the A-register with 0x80000001.
+    jb _fail_no_long_mode_2 ; It is less, there is no long mode.
+    mov eax, 0x80000001     ; Set the A-register to 0x80000001.
+    cpuid                   ; CPU identification.
+    test edx, 1 << 29       ; Test if the LM-bit, which is bit 29, is set in the D-register.
+    jz _fail_no_long_mode_3 ; They aren't, there is no long mode.
+    mov eax, 0
+    ret
+_fail_no_long_mode_2:
+    mov eax, 2
+    ret
+_fail_no_long_mode_3:
+    mov eax, 3
+    ret
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+enter_long_mode:
+    ;;;;;;;;;;;;; section 1: paging
+    ; disable paging in 32bit protected mode (if any)
+    mov eax, cr0
+    and eax, 01111111111111111111111111111111b     ; Clear the PG-bit, which is bit 31. 
+    mov cr0, eax
+
+    ; prepare paging for long mode. Using memory 0x1000 - 0x5000, to put 4-level page tables.
+    mov edi, 0x1000    ; begin addr
+    xor eax, eax
+    mov ecx, 0x1000    ; size
+    rep stosd          ; memset, 0x1000 * 4Bytes to set this memory area to ZERO.
+
+    ; set PML4T
+    mov edi, 0x1000
+    mov cr3, edi
+
+    ; fill first entry of PML4T, PDPT, PDT. 
+    mov DWORD [edi], 0x2003 ; 0x2003 IS NOT the address. it contains many flags, and another DWORD is zero. Just a trick. 
+    mov edi, 0x2000
+    mov DWORD [edi], 0x3003
+    mov edi, 0x3000
+    mov DWORD [edi], 0x4003
+    mov edi, 0x4000
+
+    ; fill all entries of the PT. This is a trick, which not setting all bits in entry. 
+    ; This page table has 512 4K page, 0x00100000 - 0x00300000.
+    mov ebx, 0x00100003 ; BIT M--12 contains PageFrameNumber. 
+    mov ecx, 512 ; counter
+_set_one_entry:
+    mov DWORD [edi], ebx
+    add ebx, 0x1000 ; each page is 4K
+    add edi, 8 ; each entry is 64bit. 
+    loop _set_one_entry
+
+    ; Page table prepared. Enable PAE-paging. 
+    mov eax, cr4
+    or eax, 1<<5
+    mov cr4, eax
+
+    ;;;;;;;;;;;;;;;; Section 2: enter compatibility mode
+    mov ecx, 0xC0000080          ; Set the C-register to 0xC0000080, which is the EFER MSR.
+    rdmsr                        ; Read from the model-specific register.
+    or eax, 1 << 8               ; Set the LM-bit which is the 9th bit (bit 8).
+    wrmsr                        ; Write to the model-specific register.
+
+    mov eax, cr0                 ; Set the A-register to control register 0.
+    or eax, 1 << 31              ; Set the PG-bit, which is the 32nd bit (bit 31).
+    mov cr0, eax                 ; Set control register 0 to the A-register.
+
+
+
+
+
diff --git a/kernel/Makefile b/kernel/Makefile
index a766e15dec5a6c6809bab16af49c686eba673e0a..48aa802f839c99a99b527aab4f5bd148365348bf 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -12,6 +12,9 @@ head:
 kernel:
 	g++ -ffreestanding -fno-pie -c kernel.cc -o kernel.o -m32 -std=c++17
 
+kernel_x64:
+	g++ -ffreestanding -fno-pie -c kernel.cc -o kernel.o -m64 -std=c++17
+
 clean:
 	rm *.o *.img
 
diff --git a/res/1.png b/res/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..732f6644a26bc32a4be02483e4dca48c9ce42e79
Binary files /dev/null and b/res/1.png differ