An x86-64 operating system built from xv6, now largely rewritten: SMP, a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF rasteriser, and a Linux-numbered syscall ABI. No history before this point -- the tree was never under version control. This commit exists so the rename that follows has something to undo to.
174 lines
No EOL
4.5 KiB
ArmAsm
174 lines
No EOL
4.5 KiB
ArmAsm
/* entry.S
|
|
*
|
|
* Copyright (c) 2013 Brian Swetland
|
|
* Modified by Nexoniarz
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
* the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
*/
|
|
|
|
#define mboot_magic 0x1badb002
|
|
#define mboot_flags 0x00010000
|
|
#include "mmu.h"
|
|
|
|
.code64
|
|
.global mboot_header
|
|
.global mboot_entry
|
|
|
|
mboot_header:
|
|
.long mboot_magic
|
|
.long mboot_flags
|
|
.long (-mboot_magic -mboot_flags)
|
|
.long mboot_load_addr
|
|
.long mboot_load_addr
|
|
.long mboot_load_end
|
|
.long mboot_bss_end
|
|
.long mboot_entry_addr
|
|
|
|
.code32
|
|
mboot_entry:
|
|
mov %eax, %ebp
|
|
|
|
# bootstrap page tables (0x1000 - 0x3000)
|
|
xor %eax, %eax
|
|
mov $0x1000, %edi
|
|
mov $0x2000, %ecx
|
|
rep stosb
|
|
|
|
# Bootstrap page tables (Identity mapping 4GB)
|
|
# PML4T[0] i PML4T[256] -> PDPT pod 0x2000
|
|
mov $(0x2000 | PTE_P | PTE_W), %edx
|
|
mov %edx, 0x1000
|
|
mov %edx, 0x1800
|
|
|
|
# PDPT mapping 4GB using 1GB huge pages
|
|
mov $(0x00000000 | PTE_P | PTE_PS | PTE_W), %edx
|
|
mov %edx, 0x2000
|
|
mov $(0x40000000 | PTE_P | PTE_PS | PTE_W), %edx
|
|
mov %edx, 0x2008
|
|
mov $(0x80000000 | PTE_P | PTE_PS | PTE_W), %edx
|
|
mov %edx, 0x2010
|
|
mov $(0xC0000000 | PTE_P | PTE_PS | PTE_W), %edx
|
|
mov %edx, 0x2018
|
|
|
|
mov %ebp, %ebx
|
|
|
|
.global entry32mp
|
|
entry32mp:
|
|
mov $0x1000, %eax
|
|
mov %eax, %cr3
|
|
|
|
lgdt (gdtr64 - mboot_header + mboot_load_addr)
|
|
|
|
mov %cr4, %eax
|
|
bts $5, %eax
|
|
mov %eax, %cr4
|
|
|
|
mov $MSR_EFER, %ecx
|
|
rdmsr
|
|
bts $0, %eax
|
|
bts $8, %eax
|
|
wrmsr
|
|
|
|
mov %cr0, %eax
|
|
orl $(CR0_PG | CR0_WP | CR0_MP), %eax
|
|
mov %eax, %cr0
|
|
|
|
ljmp $8, $(entry64low - mboot_header + mboot_load_addr)
|
|
|
|
.align 16
|
|
gdtr64:
|
|
.word gdt64_end - gdt64_begin - 1;
|
|
.quad gdt64_begin - mboot_header + mboot_load_addr
|
|
|
|
.align 16
|
|
gdt64_begin:
|
|
.long 0x00000000
|
|
.long 0x00000000
|
|
.long 0x00000000 # 64-bit code
|
|
.long 0x00209800
|
|
.long 0x00000000 # 64-bit data
|
|
.long 0x00009000
|
|
gdt64_end:
|
|
|
|
.align 16
|
|
.code64
|
|
entry64low:
|
|
movabs $entry64high, %rax
|
|
jmp *%rax
|
|
|
|
.global _start
|
|
_start:
|
|
entry64high:
|
|
xor %rax, %rax
|
|
mov %ax, %ss
|
|
mov %ax, %ds
|
|
mov %ax, %es
|
|
mov %ax, %fs
|
|
mov %ax, %gs
|
|
|
|
# Is this an application processor, or the boot processor?
|
|
#
|
|
# This check used to be a comment saying it had not been written yet, and
|
|
# every AP fell straight through into the BSP path below: it set RSP to the
|
|
# *boot processor's* stack, passed its own flag to kmain() as a framebuffer
|
|
# address, and re-ran the entire bootstrap -- e820_init, kinit1, kvmalloc --
|
|
# on a second core sharing one stack with the first. That is the SMP triple
|
|
# fault. QEMU hid it for years by never reporting more than one CPU (see
|
|
# kernel/arch/x86_64/acpi.c); VMware did not.
|
|
#
|
|
# EBX is the discriminator, and entryother.S sets it to 1 immediately before
|
|
# entering long mode for exactly this purpose. It is safe: on the boot
|
|
# processor EBX carries the VESA framebuffer address from the loader, which is
|
|
# either zero or a physical MMIO address, and can never be 1.
|
|
cmp $1, %ebx
|
|
je entry64mp
|
|
|
|
# Setup initial stack
|
|
movabs $0xFFFF800000010000, %rax
|
|
mov %rax, %rsp
|
|
|
|
# Pass VESA address to main (1st argument in RDI)
|
|
mov %rbx, %rdi
|
|
|
|
call kmain
|
|
|
|
.global __deadloop
|
|
__deadloop:
|
|
jmp .
|
|
|
|
entry64mp:
|
|
mov $0x7000, %rax
|
|
mov -16(%rax), %rsp
|
|
jmp mpenter
|
|
|
|
.global wrmsr
|
|
wrmsr:
|
|
mov %rdi, %rcx
|
|
mov %rsi, %rax
|
|
shr $32, %rsi
|
|
mov %rsi, %rdx
|
|
wrmsr
|
|
retq
|
|
|
|
.global ignore_sysret
|
|
ignore_sysret:
|
|
mov $-38, %rax
|
|
sysretq |