# Multiboot2 header and x86_64 long-mode bootstrap .section .multiboot2, "a" .align 8 multiboot_header: .long 0xe85250d6 .long 0 .long multiboot_header_end - multiboot_header .long -(0xe85250d6 + 0 + (multiboot_header_end - multiboot_header)) /* Framebuffer tag: type=5, prefer RGB 32 bpp */ .align 8 .word 5 .word 0 .long 32 .quad 0 .long 0 .long 0 .long 32 .byte 1 .byte 0 .word 0 .align 8 .word 0 .word 0 .long 8 multiboot_header_end: .section .bss, "aw", @nobits .align 4096 pml4: .space 4096 pdpt: .space 4096 pd: .space 4096 .align 16 stack_bottom: .space 16384 stack_top: .align 8 mboot_info_ptr: .space 8 .section .text .code32 .global _start .type _start, @function _start: movl $stack_top, %esp movl %ebx, mboot_info_ptr cld movl $__bss_start, %edi movl $__bss_end, %ecx subl %edi, %ecx xorl %eax, %eax rep stosb movl $pdpt, %eax orl $0x03, %eax movl %eax, pml4 movl $pd, %eax orl $0x03, %eax movl %eax, pdpt movl $0x00000083, %eax movl $pd, %edi movl $512, %ecx 1: movl %eax, (%edi) addl $0x200000, %eax addl $8, %edi loop 1b movl $pml4, %eax movl %eax, %cr3 movl %cr4, %eax orl $0x20, %eax movl %eax, %cr4 movl $0xC0000080, %ecx rdmsr orl $0x100, %eax wrmsr movl %cr0, %eax orl $0x80000000, %eax movl %eax, %cr0 lgdt gdt64_pointer ljmp $0x08, $long_mode_start .code64 long_mode_start: /* Load data segment registers with the data descriptor (0x10). * In long mode most of these are ignored for access checks, but * %ss must be a valid (or null) selector so that iretq from an * interrupt can safely reload it. */ movw $0x10, %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movw %ax, %ss movabsq $stack_top, %rax movq %rax, %rsp /* Ensure 16-byte alignment for the System V AMD64 ABI. */ andq $-16, %rsp movq mboot_info_ptr, %rdi call kernel_main cli 1: hlt jmp 1b .code64 .global isr_keyboard .align 16 isr_keyboard: /* Save all caller-saved registers used by the SysV AMD64 ABI. */ pushq %rax pushq %rcx pushq %rdx pushq %rsi pushq %rdi pushq %r8 pushq %r9 pushq %r10 pushq %r11 /* On interrupt entry the CPU pushed 5 qwords (40 bytes), and we * pushed 9 more (72 bytes) = 112 bytes total. That leaves %rsp * misaligned by 8 relative to a 16-byte boundary after the * upcoming `call`. Push one dummy qword to realign. */ subq $8, %rsp cld call keyboard_handler addq $8, %rsp popq %r11 popq %r10 popq %r9 popq %r8 popq %rdi popq %rsi popq %rdx popq %rcx popq %rax iretq .section .note.Xen, "a", @note .align 4 .long 4 .long 4 .long 18 .asciz "Xen" .align 4 .long _start .section .rodata .align 8 gdt64: .quad 0x0000000000000000 /* 0x00: null descriptor */ .quad 0x00209A0000000000 /* 0x08: 64-bit code, DPL=0 */ .quad 0x0000920000000000 /* 0x10: data, writable, present */ gdt64_end: gdt64_pointer: .word gdt64_end - gdt64 - 1 .quad gdt64