+;
+; Acess2 x86_64 port
+;
+
+%include "arch/x86_64/include/common.inc.asm"
[BITS 32]
+;KERNEL_BASE equ 0xFFFF800000000000
+KERNEL_BASE equ 0xFFFFFFFF80000000
+
[section .multiboot]
mboot:
- MULTIBOOT_MAGIC equ 0x1BADB002
- dd MULTIBOOT_MAGIC
+ ; Multiboot macros to make a few lines later more readable
+ MULTIBOOT_PAGE_ALIGN equ 1<<0
+ MULTIBOOT_MEMORY_INFO equ 1<<1
+ MULTIBOOT_AOUT_KLUDGE equ 1<<16
+ MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
+ MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO; | MULTIBOOT_AOUT_KLUDGE
+ MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+
+ ; This is the GRUB Multiboot header. A boot signature
+ dd MULTIBOOT_HEADER_MAGIC
+ dd MULTIBOOT_HEADER_FLAGS
+ dd MULTIBOOT_CHECKSUM
+ [extern __load_addr]
+ [extern __bss_start]
+ [extern gKernelEnd]
+ ; a.out kludge
+ dd mboot ; Location of Multiboot Header
+ dd __load_addr ; Load address
+ dd __bss_start - KERNEL_BASE ; End of .data
+ dd gKernelEnd - KERNEL_BASE ; End of .bss (and kernel)
+ dd start - KERNEL_BASE ; Entrypoint
[extern start64]
[section .text]
[global start]
start:
- ; Enable PAE
+ mov [gMultibootMagic - KERNEL_BASE], eax
+ mov [gMultibootPtr - KERNEL_BASE], ebx
+
+ ; Check for Long Mode support
+ mov eax, 0x80000000
+ cpuid
+ cmp eax, 0x80000001 ; Compare the A-register with 0x80000001.
+ mov eax, 0x80000001
+ cpuid
+ jb .not64bitCapable
+ test edx, 1<<29
+ jz .not64bitCapable
+
+ ; Enable PGE (Page Global Enable)
+ ; + PAE (Physical Address Extension)
+ ; + PSE (Page Size Extensions)
mov eax, cr4
- or eax, 0x80|0x20
+ or eax, 0x80|0x20|0x10
mov cr4, eax
; Load PDP4
- mov eax, gInitialPML4
+ mov eax, gInitialPML4 - KERNEL_BASE
mov cr3, eax
- ; Enable long/compatability mode
+ ; Enable IA-32e mode
+ ; (Also enables SYSCALL and NX)
mov ecx, 0xC0000080
rdmsr
- or ax, 0x100
+ or eax, (1 << 11)|(1 << 8)|(1 << 0) ; NXE, LME, SCE
wrmsr
; Enable paging
mov eax, cr0
- or eax, 0x80000000
+ or eax, 0x80010000 ; PG & WP
mov cr0, eax
; Load GDT
- lgdt [gGDTPtr]
- mov ax, 0x10
- mov ss, ax
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
-
- jmp 0x08:start64
+ lgdt [gGDTPtr - KERNEL_BASE]
+ jmp 0x08:start64 - KERNEL_BASE
+
+.not64bitCapable:
+ mov ah, 0x0F
+ mov edi, 0xB8000
+ mov esi, csNot64BitCapable - KERNEL_BASE
+
+.loop:
+ lodsb
+ test al, al
+ jz .hlt
+ stosw
+ jmp .loop
+
+.hlt:
+ cli
+ hlt
+ jmp .hlt
[section .data]
+[global gGDT]
+[global gGDTPtr]
gGDT:
dd 0,0
- dd 0x00000000, 0x00209800 ; 0x08: 64-bit Code
- dd 0x00000000, 0x00009000 ; 0x10: 64-bit Data
- dd 0x00000000, 0x00209800 ; 0x18: 64-bit User Code
- dd 0x00000000, 0x00209000 ; 0x20: 64-bit User Data
- dd 0x00000000, 0x00209800 ; 0x38: 32-bit User Code
- dd 0x00000000, 0x00209000 ; 0x30: 32-bit User Data
- times MAX_CPUS dd 0, 0, 0, 0 ; 0x38+16*n: TSS 0
+ dd 0x00000000, 0x00209A00 ; 0x08: 64-bit Code
+ dd 0x00000000, 0x00009200 ; 0x10: 64-bit Data
+ dd 0x00000000, 0x0040FA00 ; 0x18: 32-bit User Code
+ dd 0x00000000, 0x0040F200 ; 0x20: User Data
+ dd 0x00000000, 0x0020FA00 ; 0x28: 64-bit User Code
+ dd 0x00000000, 0x0000F200 ; 0x30: User Data (64 version)
+ times MAX_CPUS dd 0, 0x00008900, 0, 0 ; 0x38+16*n: TSS 0
gGDTPtr:
dw $-gGDT-1
- dd gGDT
+ dd gGDT-KERNEL_BASE
+ dd 0
+[global gMultibootPtr]
+[global gMultibootMagic]
+gMultibootMagic:
+ dd 0
+gMultibootPtr:
dd 0
[section .padata]
-gInitialPML4: ; Covers 256 TiB (Full 48-bit Virtual Address Space
- dd gInitialPDP + 3, 0 ; Identity Map Low 4Mb
- times 256-1 dq 0
- dd gInitialPDP + 3, 0 ; Map Low 4Mb to kernel base
- times 256-1 dq 0
+[global gInitialPML4]
+gInitialPML4: ; Covers 256 TiB (Full 48-bit Virtual Address Space)
+ dd gInitialPDP - KERNEL_BASE + 3, 0 ; Identity Map Low 4Mb
+ times 0xA0*2-1 dq 0
+ dd gStackPDP - KERNEL_BASE + 3, 0
+ times 512-4-($-gInitialPML4)/8 dq 0
+ dd gInitialPML4 - KERNEL_BASE + 3, 0 ; Fractal Mapping
+ dq 0
+ dq 0
+ dd gHighPDP - KERNEL_BASE + 3, 0 ; Map Low 4Mb to kernel base
gInitialPDP: ; Covers 512 GiB
- dd gInitialPD + 3, 0
- times 511 dq 0
+ dd gInitialPD - KERNEL_BASE + 3, 0
+ times 511 dq 0
-gInitialPD: ; Covers 1 GiB
- dd gInitialPT1 + 3, 0
- dd gInitialPT2 + 3, 0
+gStackPDP:
+ dd gStackPD - KERNEL_BASE + 3, 0
+ times 511 dq 0
-gInitialPT1: ; Covers 2 MiB
- %assign i 1
+gHighPDP: ; Covers 512 GiB
+ times 510 dq 0
+ ;dq 0 + 0x143 ; 1 GiB Page from zero
+ dd gInitialPD - KERNEL_BASE + 3, 0
+ dq 0
+
+gInitialPD: ; Covers 1 GiB
+; dq 0 + 0x143 ; 1 GiB Page from zero
+ dd gInitialPT1 - KERNEL_BASE + 3, 0
+ dd gInitialPT2 - KERNEL_BASE + 3, 0
+ times 510 dq 0
+
+gStackPD:
+ dd gKStackPT - KERNEL_BASE + 3, 0
+ times 511 dq 0
+
+gKStackPT: ; Covers 2 MiB
+ ; Initial stack - 64KiB
+ dq 0
+ %assign i 0
+ %rep INITIAL_KSTACK_SIZE-1
+ dd gInitialKernelStack - KERNEL_BASE + i*0x1000 + 0x103, 0
+ %assign i i+1
+ %endrep
+ times 512-INITIAL_KSTACK_SIZE dq 0
+gInitialPT1: ; 2 MiB
+ %assign i 0
%rep 512
- dq i*4096+3
+ dq i*4096+0x103
%assign i i+1
%endrep
gInitialPT2: ; 2 MiB
%assign i 512
%rep 512
- dq i*4096+3
+ dq i*4096+0x103
%assign i i+1
%endrep
+[section .padata]
+[global gInitialKernelStack]
+gInitialKernelStack:
+ times 0x1000*(INITIAL_KSTACK_SIZE-1) db 0 ; 8 Pages
+
+[section .rodata]
+csNot64BitCapable:
+ db "Not 64-bit Capable",0
+; vim: ft=nasm