diff --git a/boot/startup32.S b/boot/startup32.S index c40d24e..428276b 100644 --- a/boot/startup32.S +++ b/boot/startup32.S @@ -104,6 +104,7 @@ startup: movl %esi, boot_params_addr@GOTOFF(%ebx) # ...and check if the processor supports long mode. + # TODO and NX movl $0x80000000, %eax # check if function 0x80000001 is available pushl %ebx # ebx is overwritten by cpuid @@ -206,7 +207,7 @@ init_idt_descr: jz 1f # bail if not supported movl %cr4, %eax # enable PAE - orl $0x00000020, %eax + orb $0x20, %al movl %eax, %cr4 leal pdp@GOTOFF(%ebx), %eax # set the page directory base address @@ -219,7 +220,7 @@ init_idt_descr: movl $0xc0000080, %ecx # enable long mode rdmsr - orl $0x00000100, %eax + orb $0x01, %ah wrmsr leal pml4@GOTOFF(%ebx), %eax # set the page directory base address @@ -648,17 +649,17 @@ gdt_end: .data - .macro ptes64 start, count=64 - .quad \start + 0x0000000 + 0x83 - .quad \start + 0x0200000 + 0x83 - .quad \start + 0x0400000 + 0x83 - .quad \start + 0x0600000 + 0x83 - .quad \start + 0x0800000 + 0x83 - .quad \start + 0x0A00000 + 0x83 - .quad \start + 0x0C00000 + 0x83 - .quad \start + 0x0E00000 + 0x83 + .macro ptes64 start, flags, count=64 + .quad \start + 0x0000000 + \flags + .quad \start + 0x0200000 + \flags + .quad \start + 0x0400000 + \flags + .quad \start + 0x0600000 + \flags + .quad \start + 0x0800000 + \flags + .quad \start + 0x0A00000 + \flags + .quad \start + 0x0C00000 + \flags + .quad \start + 0x0E00000 + \flags .if \count-1 - ptes64 "(\start+0x01000000)",\count-1 + ptes64 "(\start+0x01000000)", \flags, \count-1 .endif .endm @@ -702,22 +703,22 @@ pdp: .align 4096 .globl pd0 pd0: - ptes64 0x0000000000000000 + ptes64 0x0000000000000000,0x0000000000000083 .align 4096 .globl pd1 pd1: - ptes64 0x0000000040000000 + ptes64 0x0000000040000000,0x0000000000000083 .align 4096 .globl pd2 pd2: - ptes64 0x0000000080000000 + ptes64 0x0000000080000000,0x0000000000000083 .align 4096 .globl pd3 pd3: - ptes64 0x00000000C0000000 + ptes64 0x00000000C0000000,0x0000000000000083 .previous diff --git a/boot/startup64.S b/boot/startup64.S index a6f86d1..ec3a7a1 100644 --- a/boot/startup64.S +++ b/boot/startup64.S @@ -71,14 +71,14 @@ startup32: # Enable PAE. movl %cr4, %eax - orl $0x20, %eax + orb $0x20, %al movl %eax, %cr4 # Enable long mode. movl $0xc0000080, %ecx rdmsr - orl $0x00000100, %eax + orb $0x01, %ah wrmsr # Enable paging and protection. @@ -162,6 +162,13 @@ startup: leaq _stacks(%rip), %rsp addq %rax, %rsp + # Enable NX. + + movl $0xc0000080, %ecx + rdmsr + orb $0x08, %ah + wrmsr + # Initialise the pml4 and pdp tables. leaq pml4(%rip), %rcx @@ -255,8 +262,8 @@ flush: movw $KERNEL_DS, %ax # Enable SSE. movq %cr0, %rax - andw $0xfffb, %ax # clear coprocessor emulation bit - orw $0x0002, %ax # set coprocessor monitoring bit + andb $0xfb, %al # clear coprocessor emulation bit + orb $0x02, %al # set coprocessor monitoring bit mov %rax, %cr0 movq %cr4, %rax orw $0x0600, %ax # set OSFXSR and OSXMMEXCPT @@ -465,17 +472,17 @@ gdt_end: .data - .macro ptes64 start, count=64 - .quad \start + 0x0000000 + 0x83 - .quad \start + 0x0200000 + 0x83 - .quad \start + 0x0400000 + 0x83 - .quad \start + 0x0600000 + 0x83 - .quad \start + 0x0800000 + 0x83 - .quad \start + 0x0A00000 + 0x83 - .quad \start + 0x0C00000 + 0x83 - .quad \start + 0x0E00000 + 0x83 + .macro ptes64 start, flags, count=64 + .quad \start + 0x0000000 + \flags + .quad \start + 0x0200000 + \flags + .quad \start + 0x0400000 + \flags + .quad \start + 0x0600000 + \flags + .quad \start + 0x0800000 + \flags + .quad \start + 0x0A00000 + \flags + .quad \start + 0x0C00000 + \flags + .quad \start + 0x0E00000 + \flags .if \count-1 - ptes64 "(\start+0x01000000)",\count-1 + ptes64 "(\start+0x01000000)", \flags, \count-1 .endif .endm @@ -514,22 +521,22 @@ pdp: .align 4096 .globl pd0 pd0: - ptes64 0x0000000000000000 + ptes64 0x0000000000000000,0x0000000000000083 .align 4096 .globl pd1 pd1: - ptes64 0x0000000040000000 + ptes64 0x0000000040000000,0x0000000000000083 .align 4096 .globl pd2 pd2: - ptes64 0x0000000080000000 + ptes64 0x0000000080000000,0x8000000000000083 .align 4096 .globl pd3 pd3: - ptes64 0x00000000C0000000 + ptes64 0x00000000C0000000,0x0000000000000083 .previous @@ -567,14 +574,14 @@ data32 lgdt ap_gdt_descr - ap_trampoline # Enable PAE. movl %cr4, %eax - orl $0x20, %eax + orb $0x20, %al movl %eax, %cr4 # Enable long mode. movl $0xc0000080, %ecx rdmsr - orl $0x00000100, %eax + orb $0x01, %ah wrmsr # Enable paging and protection. @@ -583,6 +590,13 @@ data32 lgdt ap_gdt_descr - ap_trampoline orl $0x80000001, %eax movl %eax, %cr0 + # Enable NX. + + movl $0xc0000080, %ecx + rdmsr + orb $0x08, %ah + wrmsr + # Jump to the 64-bit entry point. ap_jump: data32 ljmp $KERNEL_CS, $0 diff --git a/system/cpuid.h b/system/cpuid.h index c84fd27..a97ba17 100644 --- a/system/cpuid.h +++ b/system/cpuid.h @@ -100,7 +100,9 @@ typedef union { uint32_t : 12; // ECX feature flags, bit 20 uint32_t x2apic : 1; uint32_t : 10; // ECX feature flags, bit 31 - uint32_t : 29; // EDX extended feature flags, bit 0 + uint32_t : 19; // EDX extended feature flags, bit 0 + uint32_t nx : 1; + uint32_t : 9; uint32_t lm : 1; uint32_t : 2; // EDX extended feature flags, bit 31 }; diff --git a/system/vmem.c b/system/vmem.c index 58d6694..0df4d1e 100644 --- a/system/vmem.c +++ b/system/vmem.c @@ -125,13 +125,14 @@ bool map_window(uintptr_t start_page) return false; } if (cpuid_info.flags.lm == 0 && (start_page >= PAGE_C(64,GB))) { - // Fail, we want an address that is out of bounds - // for PAE and no long mode (ie. 32 bit CPU). + // Fail, we want an address that is out of bounds + // for PAE and no long mode (ie. 32 bit CPU). return false; } // Compute the page table entries. + uint64_t flags = cpuid_info.flags.nx ? UINT64_C(0x8000000000000083) : 0x83; for (uintptr_t i = 0; i < 512; i++) { - pd2[i] = ((uint64_t)window << 30) + (i << VM_PAGE_SHIFT) + 0x83; + pd2[i] = ((uint64_t)window << 30) + (i << VM_PAGE_SHIFT) + flags; } // Reload the PDBR to flush any remnants of the old mapping. load_pdbr();