DragonOS/kernel/head.S
2022-04-04 22:30:06 +08:00

603 lines
15 KiB
ArmAsm
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by longjin.
// 2022/01/20
#include "common/asm.h"
// multiboot2
// How many bytes from the start of the file we search for the header.
#define MULTIBOOT_SEARCH 32768
#define MULTIBOOT_HEADER_ALIGN 8
// The magic field should contain this.
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
// This should be in %eax.
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
// Alignment of multiboot modules.
#define MULTIBOOT_MOD_ALIGN 0x00001000
// Alignment of the multiboot info structure.
#define MULTIBOOT_INFO_ALIGN 0x00000008
// Flags set in the 'flags' member of the multiboot header.
#define MULTIBOOT_TAG_ALIGN 8
#define MULTIBOOT_TAG_TYPE_END 0
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
#define MULTIBOOT_TAG_TYPE_MODULE 3
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
#define MULTIBOOT_TAG_TYPE_MMAP 6
#define MULTIBOOT_TAG_TYPE_VBE 7
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
#define MULTIBOOT_TAG_TYPE_APM 10
#define MULTIBOOT_TAG_TYPE_EFI32 11
#define MULTIBOOT_TAG_TYPE_EFI64 12
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
#define MULTIBOOT_TAG_TYPE_NETWORK 16
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
#define MULTIBOOT_HEADER_TAG_END 0
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
#define MULTIBOOT_HEADER_TAG_ADDRESS 2
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
#define MULTIBOOT_ARCHITECTURE_I386 0
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
// multiboot2
// How many bytes from the start of the file we search for the header.
#define MULTIBOOT_SEARCH 32768
#define MULTIBOOT_HEADER_ALIGN 8
// The magic field should contain this.
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
// This should be in %eax.
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
// Alignment of multiboot modules.
#define MULTIBOOT_MOD_ALIGN 0x00001000
// Alignment of the multiboot info structure.
#define MULTIBOOT_INFO_ALIGN 0x00000008
// Flags set in the 'flags' member of the multiboot header.
#define MULTIBOOT_TAG_ALIGN 8
#define MULTIBOOT_TAG_TYPE_END 0
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
#define MULTIBOOT_TAG_TYPE_MODULE 3
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
#define MULTIBOOT_TAG_TYPE_MMAP 6
#define MULTIBOOT_TAG_TYPE_VBE 7
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
#define MULTIBOOT_TAG_TYPE_APM 10
#define MULTIBOOT_TAG_TYPE_EFI32 11
#define MULTIBOOT_TAG_TYPE_EFI64 12
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
#define MULTIBOOT_TAG_TYPE_NETWORK 16
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
#define MULTIBOOT_HEADER_TAG_END 0
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
#define MULTIBOOT_HEADER_TAG_ADDRESS 2
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
#define MULTIBOOT_ARCHITECTURE_I386 0
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
// -m64 64
// 32 32 64
// 64 -m32 long -m64
// x86_64(IA32E)
// See https://wiki.osdev.org/Creating_a_64-bit_kernel:
// With a 32-bit bootstrap in your kernel
// long
// 32bit
// 32
.code32
// multiboot2
//
.SET HEADER_LENGTH, multiboot_header_end - multiboot_header
//
.SET CHECKSUM, -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + HEADER_LENGTH)
// 8
.align MULTIBOOT_HEADER_ALIGN
//
.section .multiboot_header
multiboot_header:
//
.long MULTIBOOT2_HEADER_MAGIC
//
.long MULTIBOOT_ARCHITECTURE_I386
//
.long HEADER_LENGTH
//
.long CHECKSUM
// Multiboot2 Specification version 2.0.pdf
//
.align 8
framebuffer_tag_start:
.short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
.short MULTIBOOT_HEADER_TAG_OPTIONAL
.long framebuffer_tag_end - framebuffer_tag_start
.long 1440
.long 900
.long 32
framebuffer_tag_end:
.align 8
.short MULTIBOOT_HEADER_TAG_END
//
.short 0
.long 8
multiboot_header_end:
// 4KB/
.section .data
.align 0x1000
.global pml4
pml4:
.skip 0x1000
pdpt:
.skip 0x1000
pd:
.skip 0x1000
pt:
.skip 0x1000
// GDT
.align 16
gdt64:
null_desc:
.short 0xFFFF
.short 0
.byte 0
.byte 0
.byte 0
.byte 0
code_desc:
.short 0
.short 0
.byte 0
.byte 0x9A
.byte 0x20
.byte 0
data_desc:
.short 0
.short 0
.byte 0
.byte 0x92
.byte 0
.byte 0
user_code_desc:
.short 0
.short 0
.byte 0
.byte 0xFA
.byte 0x20
.byte 0
user_data_desc:
.short 0
.short 0
.byte 0
.byte 0xF2
.byte 0
.byte 0
gdt64_pointer:
.short gdt64_pointer-gdt64-1
.quad gdt64
gdt64_pointer64:
.short gdt64_pointer-gdt64-1
.quad gdt64
.section .text
.global _start
.type _start, @function
# multiboot2.cpp
.extern boot_info_addr
.extern multiboot2_magic
.extern _start64
_start:
//
cli
// multiboot2_info
mov %ebx, boot_info_addr
//
mov %eax, multiboot2_magic
/
// 1. PAE
mov %cr4, %eax
or $(1<<5), %eax
mov %eax, %cr4
// 2.
//
mov $pml4, %eax
mov $pdpt, %ebx
or $0x3, %ebx
mov %ebx, 0(%eax)
//
mov $pdpt, %eax
mov $pd, %ebx
or $0x3, %ebx
mov %ebx, 0(%eax)
//
mov $pd, %eax
mov $pt, %ebx
or $0x3, %ebx
mov %ebx, 0(%eax)
//
// 512
mov $512, %ecx
mov $pt, %eax
mov $0x3, %ebx
.fill_pt:
mov %ebx, 0(%eax)
add $0x1000, %ebx
add $8, %eax
loop .fill_pt
// CR3
mov $pml4, %eax
mov %eax, %cr3
// 3. long
mov $0xC0000080, %ecx
rdmsr
or $(1<<8), %eax
wrmsr
// 4.
mov %cr0, %eax
or $(1<<31), %eax
mov %eax, %cr0
// 5. GDT
mov $gdt64_pointer, %eax
lgdt 0(%eax)
// 6. 64
jmp $0x8, $_start64
hlt
ret
.section .text
.code64
.global _start64
.type _start64, @function
.extern Start_Kernel
ENTRY(_start64)
//
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %ss
mov $0x7e00, %esp
// === GDTR ====
lgdt GDT_POINTER(%rip) //rip, PICposition independent code
// === IDTR ====
lidt IDT_POINTER(%rip)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %ss
mov %ax, %gs
movq $0x7e00, %rsp
// 2.
//
mov $__PML4E, %eax
mov $__PDPTE, %ebx
or $0x3, %ebx
mov %ebx, 0(%eax)
//
mov $__PDPTE, %eax
mov $__PDE, %ebx
or $0x3, %ebx
mov %ebx, 0(%eax)
// ==== CR3
movq $__PML4E, %rax //
movq %rax, %cr3
movq switch_seg(%rip), %rax
// ljmplcallGASlretcs
// Amazing
pushq $0x08 //
pushq %rax
lretq
// 64
switch_seg:
.quad entry64
entry64:
movq $0x10, %rax
movq %rax, %ds
movq %rax, %es
movq %rax, %gs
movq %rax, %ss
movq _stack_start(%rip), %rsp //rsp
setup_IDT:
leaq m_ignore_int(%rip), %rdx // ignore_int8B
movq $(0x08 << 16), %rax // IDT0x100000TI=0,RPL=0
movw %dx, %ax
movq $ (0x8e00 << 32), %rcx // Type=1110 P=1 DPL=00 0=0
addq %rcx, %rax
// ignore_int, rax8B rdx8B
movl %edx, %ecx
shrl $16, %ecx // 16
shlq $48, %rcx
addq %rcx, %rax // 31:16
shrq $32, %rdx // 3232
leaq IDT_Table(%rip), %rdi // rdi
mov $256, %rcx //
repeat_set_idt:
// ====== 256 ===
movq %rax, (%rdi) // 8B
movq %rdx, 8(%rdi) // 8B
addq $0x10, %rdi // IDT
dec %rcx
jne repeat_set_idt
SetUp_TSS64:
// == 64 ===
//rdx8B rax8B
leaq TSS64_Table(%rip), %rdx
xorq %rax, %rax
xorq %rcx, %rcx
// TSS47401000 1001
movq $0x89, %rax
shlq $40, %rax
// 设置段基地址31:24
movl %edx, %ecx
shrl $24, %ecx
shlq $56, %rcx
addq %rcx, %rax
xorq %rcx, %rcx
// 设置段基地址23:00
movl %edx, %ecx
andl $0xffffff, %ecx // ecx8
shlq $16, %rcx
addq %rcx, %rax
addq $103, %rax //
leaq GDT_Table(%rip), %rdi
movq %rax, 80(%rdi) // BGDT10
shrq $32, %rdx
movq %rdx, 88(%rdi) // 8BGDT11
// (main.c使load_TR)
// mov $0x50, %ax // 80
// ltr %ax
//now enable SSE and the like
movq %cr0, %rax
and $0xFFFB, %ax //clear coprocessor emulation CR0.EM
or $0x2, %ax //set coprocessor monitoring CR0.MP
movq %rax, %cr0
movq %cr4, %rax
or $(3 << 9), %ax //set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
movq %rax, %cr4
call Start_Kernel
go_to_kernel:
.quad Start_Kernel
// ==== / ignore int
m_ignore_int:
// cignore_int
movq go_to_ignore_int(%rip), %rax
pushq $0x08
pushq %rax
lretq
lretq
go_to_ignore_int:
.quad ignore_int
ENTRY(_stack_start)
.quad initial_proc_union + 32768
//
.align 0x1000 //4k
.org 0x1000 //0x1000
__PML4E:
.quad 0x103003 // 访 31~12
.fill 255,8,0
.quad 0x103003
.fill 255,8,0
.org 0x2000
__PDPTE:
.quad 0x104003 // 访
.fill 511,8,0
.org 0x3000
__PDE:
.quad 0x000083 // 访
.quad 0x200083
.quad 0x400083
.quad 0x600083
.quad 0x800083
.quad 0xa00083
.quad 0xc00083
.quad 0xe00083
.quad 0x1000083
.quad 0x1200083
.quad 0x1400083
.quad 0x1600083
.quad 0x1800083
.quad 0x1a00083
.quad 0x1c00083
.quad 0x1e00083
.quad 0x2000083
.quad 0x2200083
.quad 0x2400083
.quad 0x2600083
.quad 0x2800083
.quad 0x2a00083
.quad 0x2c00083
.quad 0x2e00083
.quad 0x3000083
.quad 0x3200083
.quad 0x3400083
.quad 0x3600083
.quad 0xe0000083 /*虚拟地址0x 3000000 初始情况下,帧缓冲区映射到这里*/
.quad 0xe0200083
.quad 0xe0400083
.quad 0xe0600083 /*0x1000000*/
.quad 0xe0800083
.quad 0xe0a00083
.quad 0xe0c00083
.quad 0xe0e00083
.quad 0xe1000083
.quad 0xe1200083
.quad 0xe1400083
.quad 0xe1600083
.quad 0xe1800083
.quad 0xe1a00083
.quad 0xe1c00083
.quad 0xe1e00083
.fill 468,8,0
// GDT
.section .data
.align 16
.global GDT_Table // 使GDT访
GDT_Table:
.quad 0x0000000000000000 // 0 0x00
.quad 0x0020980000000000 // 1 64 0x08
.quad 0x0000920000000000 // 2 64 0x10
.quad 0x0000000000000000 // 3 32 0x18
.quad 0x0000000000000000 // 4 32 0x20
.quad 0x0020f80000000000 // 5 64 0x28
.quad 0x0000f20000000000 // 6 64 0x30
.quad 0x00cf9a000000ffff // 7 32 0x38
.quad 0x00cf92000000ffff // 8 32 0x40
.fill 10, 8, 0 // 10-11 TSS(9) 80
GDT_END:
GDT_POINTER:
GDT_LIMIT: .word GDT_END - GDT_Table - 1 // GDT
GDT_BASE: .quad GDT_Table
// IDT
.global IDT_Table
IDT_Table:
.fill 512, 8, 0 // 512*8IDT
IDT_END:
IDT_POINTER:
IDT_LIMIT: .word IDT_END - IDT_Table - 1
IDT_BASE: .quad IDT_Table
// 64TSS
.global TSS64_Table
TSS64_Table:
.fill 13, 8, 0
TSS64_END:
TSS64_POINTER:
TSS64_LIMIT: .word TSS64_END - TSS64_Table - 1
TSS64_BASE: .quad TSS64_Table