.section .boot,"ax" .code16 .global boot boot: cli xor %ax, %ax mov %ax, %ds mov %ax, %es mov %ax, %ss mov $0x7c00, %sp mov $packet, %si mov $0x42, %ah int $0x13 jc stopped in $0x92, %al or $2, %al out %al, $0x92 lgdt descriptor mov %cr0, %eax or $1, %eax mov %eax, %cr0 ljmpl $8, $protected stopped: hlt jmp stopped .balign 8 packet: .byte 16, 0 .word 120 .word 0, 0x1000 .quad 1 .global gdt gdt: .quad 0 .quad 0x00cf9a000000ffff .quad 0x00cf92000000ffff .quad 0x00af9a000000ffff .quad 0x00affa000000ffff .quad 0x00cff2000000ffff .quad 0, 0 descriptor: .word 63 .long gdt .org 510 .word 0xaa55 .section .text .code32 protected: mov $0x10, %ax mov %ax, %ds mov %ax, %es mov %ax, %ss mov $0x90000, %esp cld mov $0x70000, %edi xor %eax, %eax mov $3072, %ecx rep stosl movl $0x71003, 0x70000 movl $0x72003, 0x71000 mov $0x72000, %edi mov $0x83, %eax mov $512, %ecx 1: mov %eax, (%edi) add $0x200000, %eax add $8, %edi loop 1b mov $0x20, %eax mov %eax, %cr4 mov $0x70000, %eax mov %eax, %cr3 mov $0xc0000080, %ecx rdmsr or $0x900, %eax wrmsr mov %cr0, %eax or $0x80010000, %eax mov %eax, %cr0 ljmp $0x18, $longmode .code64 longmode: mov $0x10, %ax mov %ax, %ds mov %ax, %es mov %ax, %ss mov $0x90000, %rsp lea __bss_start(%rip), %rdi lea __bss_end(%rip), %rcx sub %rdi, %rcx xor %eax, %eax rep stosb call guest 2: hlt jmp 2b .global probe probe: mov %rsp, recovery_stack(%rip) lea 5f(%rip), %rax mov %rax, recovery_address(%rip) test %edi, %edi jz 3f cmp $1, %edi je 4f call *%rsi jmp 5f 3: mov (%rsi), %rax jmp 5f 4: movq $0xc3, (%rsi) 5: ret .global probe_user probe_user: mov %rsp, recovery_stack(%rip) lea 9f(%rip), %rax mov %rax, recovery_address(%rip) pushq $0x2b pushq $0x86000 pushq $2 pushq $0x23 lea 6f(%rip), %rax push %rax iretq 6: test %edi, %edi jz 7f cmp $1, %edi je 8f call *%rsi int $0x80 7: mov (%rsi), %rax int $0x80 8: movq $0xc3, (%rsi) int $0x80 9: ret .global completed completed: pushq $0 jmp recover .global pagefault pagefault: movq $14, observed_vector(%rip) jmp recover .global protection protection: movq $13, observed_vector(%rip) recover: push %rax mov 8(%rsp), %rax mov %rax, observed_error(%rip) mov recovery_address(%rip), %rax mov %rax, 16(%rsp) mov recovery_stack(%rip), %rax mov %rax, 40(%rsp) movq $0x18, 24(%rsp) movq $0x10, 48(%rsp) pop %rax add $8, %rsp iretq .section .note.GNU-stack,"",@progbits