You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.8 KiB
99 lines
2.8 KiB
#![no_std]
|
|
#![no_main]
|
|
#![feature(lang_items)]
|
|
#![feature(global_asm)]
|
|
|
|
#[macro_use]
|
|
extern crate fixedvec;
|
|
extern crate xmas_elf;
|
|
|
|
use core::mem::transmute;
|
|
use core::slice;
|
|
use fixedvec::FixedVec;
|
|
use xmas_elf::{
|
|
header,
|
|
program::{ProgramHeader, ProgramHeader32, ProgramHeader64},
|
|
ElfFile,
|
|
};
|
|
|
|
#[cfg(target_arch = "aarch64")]
|
|
#[path = "arch/aarch64/mod.rs"]
|
|
pub mod arch;
|
|
|
|
#[cfg(target_arch = "mips")]
|
|
#[path = "arch/mipsel/mod.rs"]
|
|
pub mod arch;
|
|
|
|
pub mod lang_items;
|
|
|
|
extern "C" {
|
|
fn _kernel_payload_start();
|
|
fn _kernel_payload_end();
|
|
}
|
|
|
|
#[cfg(target_arch = "mips")]
|
|
extern "C" {
|
|
fn _dtb_start();
|
|
fn _dtb_end();
|
|
}
|
|
|
|
/// The entry point of bootloader
|
|
#[cfg(target_arch = "aarch64")]
|
|
#[no_mangle]
|
|
pub extern "C" fn boot_main() -> ! {
|
|
let kernel_size = _kernel_payload_end as usize - _kernel_payload_start as usize;
|
|
let kernel = unsafe { slice::from_raw_parts(_kernel_payload_start as *const u8, kernel_size) };
|
|
let kernel_elf = ElfFile::new(kernel).unwrap();
|
|
header::sanity_check(&kernel_elf).unwrap();
|
|
|
|
let mut preallocated_space = alloc_stack!([ProgramHeader64; 32]);
|
|
let mut segments = FixedVec::new(&mut preallocated_space);
|
|
|
|
for program_header in kernel_elf.program_iter() {
|
|
match program_header {
|
|
ProgramHeader::Ph64(header) => segments
|
|
.push(*header)
|
|
.expect("does not support more than 32 program segments"),
|
|
ProgramHeader::Ph32(_) => panic!("does not support 32 bit elf files"),
|
|
}
|
|
}
|
|
|
|
let entry = kernel_elf.header.pt2.entry_point();
|
|
let kernel_main: extern "C" fn() = unsafe { transmute(entry) };
|
|
|
|
arch::map_kernel(_kernel_payload_start as usize, &segments);
|
|
kernel_main();
|
|
|
|
loop {}
|
|
}
|
|
|
|
|
|
#[cfg(target_arch = "mips")]
|
|
#[no_mangle]
|
|
pub extern "C" fn boot_main() -> ! {
|
|
let kernel_size = _kernel_payload_end as usize - _kernel_payload_start as usize;
|
|
let kernel = unsafe { slice::from_raw_parts(_kernel_payload_start as *const u8, kernel_size) };
|
|
let kernel_elf = ElfFile::new(kernel).unwrap();
|
|
header::sanity_check(&kernel_elf).unwrap();
|
|
|
|
let mut preallocated_space = alloc_stack!([ProgramHeader32; 32]);
|
|
let mut segments = FixedVec::new(&mut preallocated_space);
|
|
|
|
for program_header in kernel_elf.program_iter() {
|
|
match program_header {
|
|
ProgramHeader::Ph32(header) => segments
|
|
.push(*header)
|
|
.expect("does not support more than 32 program segments"),
|
|
ProgramHeader::Ph64(_) => panic!("does not support 64 bit elf files"),
|
|
}
|
|
}
|
|
|
|
let entry = kernel_elf.header.pt2.entry_point() as u32;
|
|
let kernel_main: extern "C" fn(dtb: usize) = unsafe { transmute(entry) };
|
|
|
|
arch::copy_kernel(_kernel_payload_start as usize, &segments);
|
|
kernel_main(_dtb_start as usize);
|
|
|
|
loop {}
|
|
}
|