mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-24 17:06:18 +04:00
aarch64: bootable in qemu
This commit is contained in:
parent
174e0da3b6
commit
cc936ded35
@ -87,6 +87,7 @@ objdump := $(prefix)-objdump
|
|||||||
objcopy := $(prefix)-objcopy
|
objcopy := $(prefix)-objcopy
|
||||||
cc := $(prefix)-gcc
|
cc := $(prefix)-gcc
|
||||||
as := $(prefix)-as
|
as := $(prefix)-as
|
||||||
|
gdb := $(prefix)-gdb
|
||||||
|
|
||||||
.PHONY: all clean run build asm doc justrun kernel
|
.PHONY: all clean run build asm doc justrun kernel
|
||||||
|
|
||||||
@ -103,8 +104,10 @@ run: build justrun
|
|||||||
justrun:
|
justrun:
|
||||||
@qemu-system-$(arch) $(qemu_opts) || [ $$? -eq 11 ] # run qemu and assert it exit 11
|
@qemu-system-$(arch) $(qemu_opts) || [ $$? -eq 11 ] # run qemu and assert it exit 11
|
||||||
|
|
||||||
debug: $(bin)
|
debug: $(kernel) $(bin)
|
||||||
@qemu-system-$(arch) $(qemu_opts) -s -S &
|
@qemu-system-$(arch) $(qemu_opts) -s -S &
|
||||||
|
@sleep 1
|
||||||
|
@$(gdb) $(kernel) -x ../tools/gdbinit
|
||||||
|
|
||||||
ifeq ($(arch), x86_64)
|
ifeq ($(arch), x86_64)
|
||||||
build: kernel
|
build: kernel
|
||||||
@ -136,7 +139,7 @@ else
|
|||||||
cp bbl ../../kernel/$@
|
cp bbl ../../kernel/$@
|
||||||
endif
|
endif
|
||||||
else ifeq ($(arch), aarch64)
|
else ifeq ($(arch), aarch64)
|
||||||
$(objcopy) $(kernel) -O binary $@
|
$(objcopy) $(kernel) --strip-all -O binary $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
kernel:
|
kernel:
|
||||||
|
@ -13,6 +13,11 @@
|
|||||||
"linker": "aarch64-none-elf-ld",
|
"linker": "aarch64-none-elf-ld",
|
||||||
"linker-flavor": "ld",
|
"linker-flavor": "ld",
|
||||||
"linker-is-gnu": true,
|
"linker-is-gnu": true,
|
||||||
|
"pre-link-args": {
|
||||||
|
"ld": [
|
||||||
|
"-Tsrc/arch/aarch64/boot/linker.ld"
|
||||||
|
]
|
||||||
|
},
|
||||||
"llvm-target": "aarch64-unknown-none",
|
"llvm-target": "aarch64-unknown-none",
|
||||||
"no-compiler-rt": true,
|
"no-compiler-rt": true,
|
||||||
"features": "+a53,+strict-align",
|
"features": "+a53,+strict-align",
|
||||||
@ -20,6 +25,7 @@
|
|||||||
"os": "none",
|
"os": "none",
|
||||||
"panic": "abort",
|
"panic": "abort",
|
||||||
"panic-strategy": "abort",
|
"panic-strategy": "abort",
|
||||||
|
"relocation-model": "static",
|
||||||
"position-independent-executables": true,
|
"position-independent-executables": true,
|
||||||
"target-c-int-width": "32",
|
"target-c-int-width": "32",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
|
99
kernel/src/arch/aarch64/boot/boot.S
Normal file
99
kernel/src/arch/aarch64/boot/boot.S
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# TODO rewrite in Rust, use crate cortex-a
|
||||||
|
|
||||||
|
.section .text.boot
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
# read cpu affinity, start core 0, halt rest
|
||||||
|
mrs x1, mpidr_el1
|
||||||
|
and x1, x1, #3
|
||||||
|
cbz x1, setup
|
||||||
|
|
||||||
|
halt:
|
||||||
|
# core affinity != 0, halt it
|
||||||
|
wfe
|
||||||
|
b halt
|
||||||
|
|
||||||
|
setup:
|
||||||
|
# store the desired EL1 stack pointer in x1
|
||||||
|
adr x1, _start
|
||||||
|
|
||||||
|
# read the current exception level into x0 (ref: C5.2.1)
|
||||||
|
mrs x0, CurrentEL
|
||||||
|
and x0, x0, #0b1100
|
||||||
|
lsr x0, x0, #2
|
||||||
|
|
||||||
|
switch_to_el2:
|
||||||
|
# switch to EL2 if we're in EL3. otherwise switch to EL1
|
||||||
|
cmp x0, #2
|
||||||
|
beq switch_to_el1
|
||||||
|
|
||||||
|
# set-up SCR_EL3 (bits 0, 4, 5, 7, 8, 10) (A53: 4.3.42)
|
||||||
|
mov x0, #0x5b1
|
||||||
|
msr scr_el3, x0
|
||||||
|
|
||||||
|
# set-up SPSR_EL3 (bits 0, 3, 6, 7, 8, 9) (ref: C5.2.20)
|
||||||
|
mov x0, #0x3c9
|
||||||
|
msr spsr_el3, x0
|
||||||
|
|
||||||
|
# switch
|
||||||
|
adr x0, switch_to_el1
|
||||||
|
msr elr_el3, x0
|
||||||
|
|
||||||
|
eret
|
||||||
|
|
||||||
|
switch_to_el1:
|
||||||
|
# switch to EL1 if we're not already in EL1. otherwise continue with start
|
||||||
|
cmp x0, #1
|
||||||
|
beq set_stack
|
||||||
|
|
||||||
|
# set the stack-pointer for EL1
|
||||||
|
msr sp_el1, x1
|
||||||
|
|
||||||
|
# set-up HCR_EL2, enable AArch64 in EL1 (bits 1, 31) (ref: D10.2.45)
|
||||||
|
mov x0, #0x0002
|
||||||
|
movk x0, #0x8000, lsl #16
|
||||||
|
msr hcr_el2, x0
|
||||||
|
|
||||||
|
# Set SCTLR to known state (RES1: 11, 20, 22, 23, 28, 29) (ref: D10.2.100)
|
||||||
|
mov x0, #0x0800
|
||||||
|
movk x0, #0x30d0, lsl #16
|
||||||
|
msr sctlr_el1, x0
|
||||||
|
|
||||||
|
# set-up SPSR_EL2 (bits 0, 2, 6, 7, 8, 9) (ref: C5.2.19)
|
||||||
|
mov x0, #0x3c5
|
||||||
|
msr spsr_el2, x0
|
||||||
|
|
||||||
|
# enable CNTP for EL1/EL0 (ref: D7.5.2, D7.5.13)
|
||||||
|
# NOTE: This doesn't actually enable the counter stream.
|
||||||
|
mrs x0, cnthctl_el2
|
||||||
|
orr x0, x0, #3
|
||||||
|
msr cnthctl_el2, x0
|
||||||
|
msr cntvoff_el2, xzr
|
||||||
|
|
||||||
|
# switch
|
||||||
|
adr x0, set_stack
|
||||||
|
msr elr_el2, x0
|
||||||
|
|
||||||
|
eret
|
||||||
|
|
||||||
|
set_stack:
|
||||||
|
# set the current stack pointer
|
||||||
|
mov sp, x1
|
||||||
|
|
||||||
|
zero_bss:
|
||||||
|
# load the start address and number of bytes in BSS section
|
||||||
|
ldr x1, =__bss_start
|
||||||
|
ldr x2, =__bss_length
|
||||||
|
|
||||||
|
zero_bss_loop:
|
||||||
|
# zero out the BSS section, 64-bits at a time
|
||||||
|
cbz x2, go_kmain
|
||||||
|
str xzr, [x1], #8
|
||||||
|
sub x2, x2, #8
|
||||||
|
cbnz x2, zero_bss_loop
|
||||||
|
|
||||||
|
go_kmain:
|
||||||
|
# jump to rust_main, which shouldn't return. halt if it does
|
||||||
|
bl rust_main
|
||||||
|
b halt
|
39
kernel/src/arch/aarch64/boot/linker.ld
Normal file
39
kernel/src/arch/aarch64/boot/linker.ld
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0x80000; /* Raspbery Pi 3 Aarch64 (kernel8.img) load address */
|
||||||
|
|
||||||
|
/* start of the binary */
|
||||||
|
_start = .;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
KEEP(*(.text.boot)) /* from boot.S */
|
||||||
|
*(.text .text.* .gnu.linkonce.t*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.* .gnu.linkonce.r*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.* .gnu.linkonce.d*)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(32);
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(8);
|
||||||
|
__bss_end = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end of the binary */
|
||||||
|
_end = ALIGN(8);
|
||||||
|
|
||||||
|
/* number of bytes in BSS section and complete binary */
|
||||||
|
__bss_length = (__bss_end - __bss_start);
|
||||||
|
__binary_length = (_end - _start);
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
@ -29,6 +29,4 @@ pub extern fn rust_main() -> ! {
|
|||||||
::kmain();
|
::kmain();
|
||||||
}
|
}
|
||||||
|
|
||||||
// global_asm!(include_str!("boot/boot.asm"));
|
global_asm!(include_str!("boot/boot.S"));
|
||||||
// global_asm!(include_str!("boot/entry.asm"));
|
|
||||||
// global_asm!(include_str!("boot/trap.asm"));
|
|
||||||
|
3
tools/gdbinit
Normal file
3
tools/gdbinit
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target remote :1234
|
||||||
|
break rust_main
|
||||||
|
continue
|
Loading…
Reference in New Issue
Block a user