/*
Copyright © 2013 DolphinCommode
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
test is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
.text
.code16
start:
.p2align 2 /* 4-byte aligment */
IDT:
.word 0
.long 0
/* Zero out the 16KiB buffer.
Since we are doing a rep stosd, count should be bytes/4. */
pushw %di /* REP STOSD alters DI. */
movl $0x1000, %ecx
xorl %eax, %eax
cld
rep stosl
popw %di /* Get DI back. */
/* Build the Page Map Level 4.
es:di points to the Page Map Level 4 table. */
leal %es:0x1000(%di), %eax /* Put the address of the Page Directory Pointer Table in to EAX. */
#orl $0b11, %eax /* Or EAX with the flags - present flag, writable flag. */
orb $0b11, %al
movl %eax, %es:(%di) /* Store the value of EAX as the first PML4E. */
/* Build the Page Directory Pointer Table. */
leal %es:0x2000(%di), %eax /* Put the address of the Page Directory in to EAX. */
#orl $0b11, %eax /* Or EAX with the flags - present flag, writeable flag. */
orb $0b11, %al
movl %eax, %es:0x1000(%di) /* Store to value of EAX as the first PDE. */
leal %es:0x3000(%di), %eax /* Put the address of the Page Table in to EAX. */
#orl $0b11, %eax /* Or EAX with the flags - present flag, writeable flag. */
orb $0b11, %al
movl %eax, %es:0x2000(%di) /* Store to value of EAX as the first PDE. */
pushw %di /* Save DI for the time being. */
leaw 0x3000(%di), %di /* Point 1DI to the page table. */
movl $0b11, %eax /* Move the flags into EAX - and point it to 0x0000. */
/* Build the Page Table. */
LoopPageTable:
movl %eax, %es:(%di)
addl $0x1000, %eax
addw $8, %di
cmpl $0x200000, %eax /* If we did all 2MiB, end. */
jb LoopPageTable
popw %di /* Restore DI. */
/* Disable IRQs */
movb $0xFF, %al /* Out 0xFF to 0xA1 and 0x21 to disable all IRQs. */
outb %al, $0xA1
outb %al, $0x21
nop
nop
lidtw (IDT) /* Load a zero length IDT so that any NMI causes a triple fault. */
/* Enter long mode. */
movl $0b10100000, %eax /* Set the PAE and PGE bit. */
movl %eax, %cr4
movl %edi, %edx /* Point CR3 at the PML4. */
movl %edx, %cr3
movl $0xC0000080, %ecx /* Read from the EFER MSR. */
rdmsr
orl $0x00000100, %eax /* Set the LME bit. */
wrmsr
movl %cr0, %ebx /* Activate long mode - */
or $0x80000001, %ebx /* - by enabling paging and protection simultaneously. */
movl %ebx, %cr0
lgdt (GDT_Pointer) /* Load GDT_Pointer defined below. */
ljmp $0x8, $FAR /* Load CS with 64 bit segment and flush the instruction cache */
GDT:
.quad 0x0000000000000000 /* Null Descriptor - should be present. */
.quad 0x0020980000000000 /* 64-bit code descriptor. */
.quad 0x0000900000000000 /* 64-bit data descriptor. */
.p2align 2 /* 4-byte aligment */
.word 0 /* Padding to make the "address of the GDT" field aligned on a 4-byte boundary */
GDT_Pointer:
.word . - GDT - 1
.long GDT
.code64
FAR:
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
/* Blank out the screen to a blue color. */
movl $0xB8000, %edi /* Since we are clearing QWORDs over here, we put the count as Count/4. */
movl $500, %ecx /* Set the value to set the screen to: Blue background, white foreground, blank spaces. */
movq $0x1F201F201F201F20, %rax /* Clear the entire screen. */
rep stosq
movl $msg, %esi
movl $0xB8000, %edi
cld
prnt:
lodsb
stosb
incl %edi
test %al, %al
jnz prnt
jmp .
msg:
.ascii "Fuck You!"
len = . - msg
finish:
.fill (510-(. - start)),1,0
.word 0xAA55