feat(loader, kernel): impl part of loader and initialize kernel structure
This commit is contained in:
181
arch/x86_64/boot/head.S
Normal file
181
arch/x86_64/boot/head.S
Normal 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:
|
||||
Reference in New Issue
Block a user