blob: 260289bf273bd86d84f4db02808094e5b9975de8 [file] [log] [blame] [edit]
/* Copyright (c) 2009-13 The Regents of the University of California
* Barret Rhoden <brho@cs.berkeley.edu>
* See LICENSE for details. */
#include <arch/mmu.h>
#include <arch/trap.h>
#include <kstack.h>
.set CODE_SEL,0x8 # index of code seg within mygdt
.set DATA_SEL,0x10 # index of data seg within mygdt
#define MULTIBOOT_PAGE_ALIGN (1<<0)
#define MULTIBOOT_MEMORY_INFO (1<<1)
#define MULTIBOOT_HEADER_MAGIC (0x1BADB002)
#define MULTIBOOT_HEADER_FLAGS (MULTIBOOT_MEMORY_INFO | MULTIBOOT_PAGE_ALIGN)
#define CHECKSUM (-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS))
# The kernel bootstrap (this code) is linked and loaded at physical address
# 0x00100000 (1MB), which is the start of extended memory. (See kernel.ld)
# Flagging boottext to be text. Check out:
# http://sourceware.org/binutils/docs/as/Section.html
.section .boottext, "awx"
.code32
.align 4
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long CHECKSUM
.globl _start
_start:
movw $0x1234,0x472 # warm boot
# Reload all segment registers (including CS!) with flag segment selectors
# from our boot GDT.
lgdt mygdtdesc
movl $DATA_SEL, %eax
movw %ax,%ds
movw %ax,%es
movw %ax,%ss
ljmp $CODE_SEL,$newcs # reload CS by jumping
newcs:
# build page table. need a mapping for current code at 0x00100000 and a
# basic kernbase mapping. we're using the 32 bit second PT (aka, pg_dir),
# which covers 4MB per entry
movl $boot_pdt, %edx
# identity map the first jumbo PTE from 0x0 -> 0x0
movl $(PTE_P | PTE_W | PTE_PS), (%edx)
# map KERNBASE -> 0 for 1GB (1/4 of the 1024 entries)
movl $256, %ecx
# init loop, eax at paddr 0, and edx is advanced by KERNBASE mapping slots
# (with 4 bytes per PTE).
addl $((KERNBASE >> PTSHIFT) << 2), %edx
movl $(PTE_P | PTE_W | PTE_PS), %eax
loop:
movl %eax, (%edx)
addl $PTSIZE, %eax
addl $4, %edx
decl %ecx
jnz loop
# load cr3 and turn on paging. note we assume PSE support. if we didn't
# have it, then our jumbo page mappings are going to fail.
movl $boot_pdt, %eax
movl %eax, %cr3
movl %cr4, %eax
orl $(CR4_PSE | CR4_PGE), %eax
movl %eax, %cr4
movl %cr0, %eax
orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_MP), %eax
andl $(~(CR0_TS | CR0_EM | CR0_CD | CR0_NW)), %eax
movl %eax, %cr0
# paging is on, and our code is still running at 0x00100000 do some
# miscellaneous OS setup. the coreid stuff is so we can call core_id()
# before smp_boot. this is the only arch-dependent code called before then.
movl $0x0, os_coreid_lookup
movl $0x0, hw_coreid_lookup
# Clear the frame pointer register (EBP)
# so that once we get into debugging C code,
# stack backtraces will be terminated properly.
movl $0x0,%ebp
movl $(bootstacktop),%esp
# Save multiboot info
push %ebx
movl $0x1,num_cpus # init global var, for now
call kernel_init
# Should never get here, but in case we do, just spin.
spin: jmp spin
.section .bootdata, "aw"
.p2align 2 # force 4 byte alignment
mygdt:
SEG_NULL # null seg
SEG(STA_X|STA_R, 0, 0xffffffff) # code seg
SEG(STA_W, 0, 0xffffffff) # data seg
mygdtdesc:
.word 0x17 # sizeof(mygdt) - 1
.long mygdt # address mygdt
# boot page directory. going to use jumbo page entries
.align PGSIZE
boot_pdt:
.space PGSIZE
# From here down is linked for KERNBASE
.data
.p2align PGSHIFT # force page alignment
.globl bootstack
bootstack:
.space KSTKSIZE
.globl bootstacktop
bootstacktop: