feat(loader, kernel): impl part of loader and initialize kernel structure

This commit is contained in:
2026-04-11 09:42:09 +08:00
parent 1233ae9e9b
commit 34ccf69569
53 changed files with 1743 additions and 777 deletions

181
arch/x86_64/boot/head.S Normal file
View File

@@ -0,0 +1,181 @@
#include "boot.h"
#include "processor_flags.h"
#define rva(x) ((x)-startup_32)
#define __BOOT_DS (3*8)
#define __KERNEL32_CS (1*8)
#define __KERNEL_CS (2*8)
.section .head.text, "ax"
.global _start
_start: // just make linker happy
.code32
.global startup_32
.type startup_32, %function
startup_32:
movl $0x50000, %edx
movl $0xdeadbeef, (%edx)
cld
cli
// Actually multiboot doesn't give us a scartch area to use as stack,
// so we temporaily save the 2nd 32bit of boot information and use it as the stack.
movl 4(%ebx), %ecx
leal 8(%ebx), %esp
call 1f
1: popl %ebp
movl %ecx, 4(%ebx)
subl $rva(1b), %ebp
leal rva(gdt)(%ebp), %eax
mov %eax, 2(%eax)
lgdt (%eax)
mov $__BOOT_DS, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
leal rva(boot_stack_end)(%ebp), %esp
pushl $__KERNEL32_CS
leal rva(1f)(%ebp), %eax
pushl %eax
lret
1:
movl %cr4, %eax
orl $X86_CR4_PAE, %eax
movl %eax, %cr4
leal rva(pgtable)(%ebp), %edi
xorl %eax, %eax
movl $(BOOT_INIT_PGTABLE_SIZE/4), %ecx
rep stosl
leal rva(pgtable)(%ebp), %edi
leal 0x1007(%edi), %eax
movl %eax, 0(%edi)
leal rva(pgtable + 0x1000)(%ebp), %edi
leal 0x1007(%edi), %eax
movl $4, %ecx
1: movl %eax, 0(%edi)
addl $0x1000, %eax
addl $8, %edi
decl %ecx
jnz 1b
leal rva(pgtable + 0x2000)(%ebp), %edi
movl $0x183, %eax
movl $2048, %ecx
1: movl %eax, 0(%edi)
addl $0x200000, %eax
addl $8, %edi
decl %ecx
jnz 1b
leal rva(pgtable)(%ebp), %eax
movl %eax, %cr3
movl $MSR_EFER, %ecx
rdmsr
btsl $_EFER_LME, %eax
wrmsr
leal rva(startup_64)(%ebp), %eax
pushl $__KERNEL_CS
pushl %eax
movl $CR0_STATE, %eax
movl %eax, %cr0
lret
#define rva64(x) ((x)-startup_64)
#define STARTUP64_OFFSET 0x200
.code64
.global startup_64
.type startup_64, %function
.org STARTUP64_OFFSET
startup_64:
cld
cli
xorl %eax, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %ss
movl %eax, %fs
movl %eax, %gs
movq %rbx, %rsi
movq $LOAD_PHYSICAL_ADDR, %rbp
// movl has the side effect of zero-extending the upper 32 bits of rbx
movl $uncompressed_kernel_size, %ebx
// there's no need to copy the code before startup_64
addq %rbp, %rbx
leaq rva64(boot_stack_end)(%rbx), %rsp
movq %rsi, %r15
leaq (_bss - 8)(%rip), %rsi
leaq rva64(_bss - 8)(%rbx), %rdi
movl $rva64(_bss), %ecx
shrl $3, %ecx
std
rep movsq
cld
leaq rva64(gdt64)(%rbx), %rax
leaq rva64(gdt)(%rbx), %rdx
movq %rdx, 2(%rax)
lgdt (%rax)
leaq rva64(relocated)(%rbx), %rax
jmp *%rax
.text
relocated:
// clear bss
xorl %eax, %eax
leaq _bss(%rip), %rdi
leaq _ebss(%rip), %rcx
subq %rdi, %rcx
shrq $3, %rcx
rep stosq
mov %rbx, %rdi
subq $STARTUP64_OFFSET, %rdi
call relocateSelf
movq %r15, %rdi // boot params pointer
movq %rbp, %rsi // load physical address
call extractKernel
hlt
.data
gdt64:
.word gdt_end - gdt - 1
.quad gdt - gdt64
gdt64_end:
.balign 8
gdt:
.word gdt_end - gdt - 1
.long 0
.word 0
.quad 0x00cf9a000000ffff // __KERNEL32_CS
.quad 0x00af9a000000ffff // __KERNEL_CS
.quad 0x00cf92000000ffff // __KERNEL_DS
gdt_end:
.bss
.balign 4
boot_heap:
.space BOOT_HEAP_SIZE
boot_stack:
.space BOOT_STACK_SIZE
boot_stack_end:
.section ".pgtable","aw",@nobits
.balign 4096
pgtable:
.space BOOT_PGTABLE_SIZE
pgtable_end: