1d16c23fc5
Co-authored-by: aider (openrouter/anthropic/claude-opus-4.7) <aider@aider.chat>
185 lines
3.7 KiB
ArmAsm
185 lines
3.7 KiB
ArmAsm
# 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, size=20, width=height=0 (any), depth=32.
|
|
* Layout per multiboot2 spec:
|
|
* u16 type, u16 flags, u32 size, u32 width, u32 height, u32 depth
|
|
* Padded to 8-byte alignment. */
|
|
.align 8
|
|
.word 5
|
|
.word 0
|
|
.long 20
|
|
.long 0
|
|
.long 0
|
|
.long 32
|
|
.long 0 /* padding to 8-byte alignment */
|
|
|
|
.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 * 4
|
|
|
|
.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
|
|
|
|
/* Populate 4 PDPT entries, each pointing to one of 4 PDs.
|
|
* This identity-maps the first 4 GiB using 2 MiB pages,
|
|
* which covers typical framebuffer/MMIO regions. */
|
|
movl $pd, %eax
|
|
orl $0x03, %eax
|
|
movl %eax, pdpt + 0
|
|
addl $4096, %eax
|
|
movl %eax, pdpt + 8
|
|
addl $4096, %eax
|
|
movl %eax, pdpt + 16
|
|
addl $4096, %eax
|
|
movl %eax, pdpt + 24
|
|
|
|
movl $0x00000083, %eax
|
|
movl $pd, %edi
|
|
movl $2048, %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
|