IOPB: .short 0
TSS_END:
.set TSS_SIZE, TSS_END - TSS
+.align 0x1000
+PDPT_high: .skip 0x1000 - 16
+ .quad 0x83
+ .quad 0x83 + 1024 * 1024 * 1024
.section .bss
.align 0x1000
PML4T: .skip 0x1000
PDPT_low: .skip 0x1000
-PDPT_high: .skip 0x1000
PDT: .skip 0x1000
PT: .skip 0x1000
+phys_mem_map: .skip 0x1000 * 128 - 8
.align 16
stack_bottom:
.skip 1024 * 16 # 16KiB
_start:
mov $stack_top - KERNEL_VMA, %esp
+ # Save multiboot info:
+ push $0 # /
+ push %eax # \ magic
+ push $0 # /
+ push %ebx # \ info structure
+
# Check if cpuid is supported:
pushfl
pop %eax
popfl
xor %ecx, %eax
jnz .has_cpuid
- movw $0x024E, 0xB8000
- movw $0x026F, 0xB8002
- movw $0x0220, 0xB8004
- movw $0x0243, 0xB8006
- movw $0x0250, 0xB8008
- movw $0x0255, 0xB800A
- movw $0x0249, 0xB800C
- movw $0x0244, 0xB800E
- movw $0x022E, 0xB8010
cli
1: hlt
jmp 1b
jb .no_long_mode
mov $0x80000001, %eax
cpuid
+ # Long mode:
test $1 << 29, %edx
- jnz .has_long_mode
+ jz .no_long_mode
+ # 1GiB pages:
+ test $1 << 26, %edx
+ jz .no_long_mode
+ jmp .has_long_mode
.no_long_mode:
- movw $0x024E, 0xB8000
- movw $0x026F, 0xB8002
- movw $0x0220, 0xB8004
- movw $0x026C, 0xB8006
- movw $0x026F, 0xB8008
- movw $0x026E, 0xB800A
- movw $0x0267, 0xB800C
- movw $0x0220, 0xB800E
- movw $0x026D, 0xB8010
- movw $0x026F, 0xB8012
- movw $0x0264, 0xB8014
- movw $0x0265, 0xB8016
- movw $0x022E, 0xB8018
cli
1: hlt
jmp 1b
mov %eax, PML4T - KERNEL_VMA + 511 * 8
mov $PDT - KERNEL_VMA + 3, %eax
mov %eax, PDPT_low - KERNEL_VMA + 0 * 8
- mov %eax, PDPT_high - KERNEL_VMA + 510 * 8
mov $PT - KERNEL_VMA + 3, %eax
mov %eax, PDT - KERNEL_VMA + 0 * 8
.code64
.trampoline:
- mov %esp, %esp
mov $GDT.KERNEL_DATA, %ax # Set the A-register to the data descriptor.
mov %ax, %ds # Set the data segment to the A-register.
mov %ax, %es # Set the extra segment to the A-register.
mov %ax, %fs # Set the F-segment to the A-register.
mov %ax, %gs # Set the G-segment to the A-register.
mov %ax, %ss # Set the stack segment to the A-register.
+
mov $.higher_half, %rax
jmp *%rax
.section .text
.higher_half:
- call kmain
+ mov %esp, %esp
+ pop %r14 # Multiboot info address.
+ pop %r15 # Multiboot magic.
+ mov $stack_top, %rsp
+
+ # map physical memory in kernel:
+ mov $phys_mem_map - KERNEL_VMA + 3, %rbx
+ mov $PML4T + 256 * 8, %rdi
+ mov $128, %rcx
+1: mov %rbx, (%rdi)
+ add $0x1000, %rbx
+ add $8, %rdi
+ loop 1b
+
+ mov $0x83, %rbx
+ mov $phys_mem_map, %rdi
+ mov $128 * 512, %rcx
+1: mov %rbx, (%rdi)
+ add $1024 * 1024 * 1024, %rbx
+ add $8, %rdi
+ loop 1b
+
+ mov $PML4T - KERNEL_VMA, %rax
+ mov %rax, %cr3
+
+ mov %r14, %rsi
+ mov %r15, %rdi
+ call kmain # With the two arguments popped earlier.