parent
9fc13c8ebb
commit
a13f39149b
@ -0,0 +1,14 @@
|
||||
[[package]]
|
||||
name = "atags"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"volatile 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "volatile"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum volatile 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ca391c55768e479d5c2f8beb40c136df09257292a809ea514e82cfdfc15d00"
|
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "atags"
|
||||
version = "0.1.0"
|
||||
authors = ["koumingyang <1761674434@qq.com>"]
|
||||
|
||||
[dependencies]
|
@ -0,0 +1,67 @@
|
||||
use raw;
|
||||
use core::slice;
|
||||
use core::str;
|
||||
|
||||
pub use raw::{Core, Mem};
|
||||
|
||||
/// An ATAG.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Atag {
|
||||
Core(raw::Core),
|
||||
Mem(raw::Mem),
|
||||
Cmd(&'static str),
|
||||
Unknown(u32),
|
||||
None
|
||||
}
|
||||
|
||||
impl Atag {
|
||||
/// Returns `Some` if this is a `Core` ATAG. Otherwise returns `None`.
|
||||
pub fn core(self) -> Option<Core> {
|
||||
match self {
|
||||
Atag::Core(x) => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Some` if this is a `Mem` ATAG. Otherwise returns `None`.
|
||||
pub fn mem(self) -> Option<Mem> {
|
||||
match self {
|
||||
Atag::Mem(x) => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `Some` with the command line string if this is a `Cmd` ATAG.
|
||||
/// Otherwise returns `None`.
|
||||
pub fn cmd(self) -> Option<&'static str> {
|
||||
match self {
|
||||
Atag::Cmd(x) => Some(x),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert between raw::* types and Atag wrapper.
|
||||
impl<'a> From<&'a raw::Atag> for Atag {
|
||||
fn from(atag: &raw::Atag) -> Atag {
|
||||
unsafe {
|
||||
match (atag.tag, &atag.kind) {
|
||||
(raw::Atag::CORE, &raw::Kind { core }) => Atag::Core(core),
|
||||
(raw::Atag::MEM, &raw::Kind { mem }) => Atag::Mem(mem),
|
||||
(raw::Atag::CMDLINE, &raw::Kind { ref cmd }) => {
|
||||
let mut cmd_ptr: *const u8 = &cmd.cmd as *const u8;
|
||||
let mut len: usize = 0;
|
||||
|
||||
while *cmd_ptr.add(len) != 0 {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
let cmd_slice = slice::from_raw_parts(cmd_ptr, len);
|
||||
Atag::Cmd(str::from_utf8_unchecked(cmd_slice))
|
||||
},
|
||||
(raw::Atag::NONE, _) => Atag::None,
|
||||
(id, _) => Atag::Unknown(id),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
pub use atag::*;
|
||||
use raw;
|
||||
|
||||
/// The address at which the firmware loads the ATAGS.
|
||||
const ATAG_BASE: usize = 0x100;
|
||||
|
||||
/// An iterator over the ATAGS on this system.
|
||||
pub struct Atags {
|
||||
ptr: &'static raw::Atag,
|
||||
}
|
||||
|
||||
impl Atags {
|
||||
/// Returns an instance of `Atags`, an iterator over ATAGS on this system.
|
||||
pub fn get() -> Atags {
|
||||
Atags {
|
||||
ptr: unsafe { &*(ATAG_BASE as *const raw::Atag) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for Atags {
|
||||
type Item = Atag;
|
||||
|
||||
/// Iterate over Atags. Returns a valid Atag until the iterator hits the
|
||||
/// Atag::None.
|
||||
fn next(&mut self) -> Option<Atag> {
|
||||
let cur = self.ptr;
|
||||
match cur.next() {
|
||||
Some(next) => {
|
||||
let result = Some(Atag::from(cur));
|
||||
self.ptr = next;
|
||||
result
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#![no_std]
|
||||
|
||||
mod raw;
|
||||
mod atag;
|
||||
|
||||
pub mod atags;
|
@ -0,0 +1,67 @@
|
||||
/// A raw `ATAG` as laid out in memory.
|
||||
#[repr(C)]
|
||||
pub struct Atag {
|
||||
pub dwords: u32,
|
||||
pub tag: u32,
|
||||
pub kind: Kind
|
||||
}
|
||||
|
||||
impl Atag {
|
||||
pub const NONE: u32 = 0x00000000;
|
||||
pub const CORE: u32 = 0x54410001;
|
||||
pub const MEM: u32 = 0x54410002;
|
||||
pub const VIDEOTEXT: u32 = 0x54410003;
|
||||
pub const RAMDISK: u32 = 0x54410004;
|
||||
pub const INITRD2: u32 = 0x54420005;
|
||||
pub const SERIAL: u32 = 0x54410006;
|
||||
pub const REVISION: u32 = 0x54410007;
|
||||
pub const VIDEOLFB: u32 = 0x54410008;
|
||||
pub const CMDLINE: u32 = 0x54410009;
|
||||
|
||||
/// Returns the ATAG following `self`, if there is one.
|
||||
pub fn next(&self) -> Option<&Atag> {
|
||||
if self.tag == Atag::NONE {
|
||||
None
|
||||
} else {
|
||||
let current = self as *const Atag as *const u32;
|
||||
let next: &Atag = unsafe {
|
||||
&*(current.add(self.dwords as usize) as *const Atag)
|
||||
};
|
||||
|
||||
Some(next)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The possible variant of an ATAG.
|
||||
#[repr(C)]
|
||||
pub union Kind {
|
||||
pub core: Core,
|
||||
pub mem: Mem,
|
||||
pub cmd: Cmd
|
||||
}
|
||||
|
||||
/// A `CORE` ATAG.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Core {
|
||||
pub flags: u32,
|
||||
pub page_size: u32,
|
||||
pub root_dev: u32
|
||||
}
|
||||
|
||||
/// A `MEM` ATAG.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Mem {
|
||||
pub size: u32,
|
||||
pub start: u32
|
||||
}
|
||||
|
||||
/// A `CMDLINE` ATAG.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Cmd {
|
||||
/// The first byte of the command line string.
|
||||
pub cmd: u8
|
||||
}
|
@ -1,8 +1,34 @@
|
||||
//! Memory initialization for aarch64.
|
||||
|
||||
use ucore_memory::PAGE_SIZE;
|
||||
use super::atags::atags::Atags;
|
||||
use super::super::HEAP_ALLOCATOR;
|
||||
|
||||
/// Memory initialization.
|
||||
pub fn init() {
|
||||
// TODO
|
||||
let (start, end) = memory_map().expect("failed to find memory map");
|
||||
unsafe {
|
||||
HEAP_ALLOCATOR.lock().init(start, end - start);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
static _end: u8;
|
||||
}
|
||||
|
||||
/// Returns the (start address, end address) of the available memory on this
|
||||
/// system if it can be determined. If it cannot, `None` is returned.
|
||||
///
|
||||
/// This function is expected to return `Some` under all normal cirumstances.
|
||||
pub fn memory_map() -> Option<(usize, usize)> {
|
||||
let binary_end = unsafe { (&_end as *const u8) as u32 };
|
||||
|
||||
let mut atags: Atags = Atags::get();
|
||||
while let Some(atag) = atags.next() {
|
||||
if let Some(mem) = atag.mem() {
|
||||
return Some((binary_end as usize, (mem.start + mem.size) as usize));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
Loading…
Reference in new issue