parent
9bdac887f0
commit
52758e6620
@ -0,0 +1,20 @@
|
|||||||
|
.section .text.boot
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
_start:
|
||||||
|
# read cpu affinity, start core 0, halt the rest
|
||||||
|
mfc0 $8, $15, 1
|
||||||
|
beqz $8, setup
|
||||||
|
andi $8, $8, 0x3ff # use bits 11 ~ 0
|
||||||
|
|
||||||
|
halt:
|
||||||
|
# core affinity != 0, halt it
|
||||||
|
b halt
|
||||||
|
nop
|
||||||
|
|
||||||
|
setup:
|
||||||
|
# put the bootstack at 8MB offset of physical mem
|
||||||
|
la $29, 0x80800000 # $sp
|
||||||
|
la $28, _gp # $gp
|
||||||
|
b boot_main
|
||||||
|
nop
|
@ -0,0 +1,41 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
|
||||||
|
/* MIPS entry point after cold reset */
|
||||||
|
. = 0xBFC00000;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
KEEP(*(.text.boot)) /* from boot.S */
|
||||||
|
*(.text .text.* .gnu.linkonce.t*)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata .rodata.* .gnu.linkonce.r*)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
*(.data .data.* .gnu.linkonce.d*)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
_sbss = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
_ebss = .;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payload : {
|
||||||
|
*(.payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
.dtb : {
|
||||||
|
*(.dtb)
|
||||||
|
}
|
||||||
|
|
||||||
|
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
use core::ptr;
|
||||||
|
use fixedvec::FixedVec;
|
||||||
|
use xmas_elf::program::{ProgramHeader32, Type};
|
||||||
|
|
||||||
|
const KERNEL_OFFSET: u32 = 0x80000000;
|
||||||
|
|
||||||
|
global_asm!(include_str!("boot.S"));
|
||||||
|
|
||||||
|
pub fn copy_kernel(kernel_start: usize, segments: &FixedVec<ProgramHeader32>) {
|
||||||
|
// reverse program headers to avoid overlapping in memory copying
|
||||||
|
let mut space = alloc_stack!([ProgramHeader32; 32]);
|
||||||
|
let mut rev_segments = FixedVec::new(&mut space);
|
||||||
|
for i in (0..segments.len()).rev() {
|
||||||
|
rev_segments.push(segments[i]).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for segment in &rev_segments {
|
||||||
|
if segment.get_type() != Ok(Type::Load) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let virt_addr = segment.virtual_addr;
|
||||||
|
let offset = segment.offset;
|
||||||
|
let file_size = segment.file_size;
|
||||||
|
let mem_size = segment.mem_size;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let src = (kernel_start as u32 + offset) as *const u8;
|
||||||
|
let dst = virt_addr.wrapping_sub(KERNEL_OFFSET) as *mut u8;
|
||||||
|
ptr::copy(src, dst, file_size as usize);
|
||||||
|
ptr::write_bytes(dst.offset(file_size as isize), 0, (mem_size - file_size) as usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"arch": "mips",
|
||||||
|
"cpu": "mips32r2",
|
||||||
|
"llvm-target": "mipsel-unknown-none",
|
||||||
|
"data-layout": "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64",
|
||||||
|
"target-endian": "little",
|
||||||
|
"target-pointer-width": "32",
|
||||||
|
"target-c-int-width": "32",
|
||||||
|
"os": "none",
|
||||||
|
"features": "+mips32r2",
|
||||||
|
"max-atomic-width": "32",
|
||||||
|
"linker": "rust-lld",
|
||||||
|
"linker-flavor": "ld.lld",
|
||||||
|
"pre-link-args": {
|
||||||
|
"ld.lld": [
|
||||||
|
"-Tsrc/arch/mipsel/boot.ld"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"executables": true,
|
||||||
|
"panic-strategy": "abort",
|
||||||
|
"relocation-model": "static",
|
||||||
|
"abi-blacklist": [
|
||||||
|
"cdecl",
|
||||||
|
"stdcall",
|
||||||
|
"fastcall",
|
||||||
|
"vectorcall",
|
||||||
|
"thiscall",
|
||||||
|
"aapcs",
|
||||||
|
"win64",
|
||||||
|
"sysv64",
|
||||||
|
"ptx-kernel",
|
||||||
|
"msp430-interrupt",
|
||||||
|
"x86-interrupt"
|
||||||
|
],
|
||||||
|
"eliminate-frame-pointer": false
|
||||||
|
}
|
Loading…
Reference in new issue