add basic alloc

master
koumingyang 6 years ago
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
}

6
kernel/Cargo.lock generated

@ -1,3 +1,7 @@
[[package]]
name = "atags"
version = "0.1.0"
[[package]] [[package]]
name = "bare-metal" name = "bare-metal"
version = "0.2.3" version = "0.2.3"
@ -239,6 +243,7 @@ dependencies = [
name = "ucore" name = "ucore"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"atags 0.1.0",
"bbl 0.1.0", "bbl 0.1.0",
"bcm2837 0.1.0", "bcm2837 0.1.0",
"bit-allocator 0.1.0", "bit-allocator 0.1.0",
@ -246,6 +251,7 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bootloader 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "bootloader 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"cortex-a 2.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "linked_list_allocator 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",

@ -44,6 +44,8 @@ riscv = { path = "../crate/riscv" }
bbl = { path = "../crate/bbl" } bbl = { path = "../crate/bbl" }
[target.'cfg(target_arch = "aarch64")'.dependencies] [target.'cfg(target_arch = "aarch64")'.dependencies]
cortex-a = "2.2.1"
atags = { path = "../crate/atags" }
bcm2837 = { path = "../crate/bcm2837", features = ["use_generic_timer"] } bcm2837 = { path = "../crate/bcm2837", features = ["use_generic_timer"] }
[package.metadata.bootimage] [package.metadata.bootimage]

@ -1,8 +1,34 @@
//! Memory initialization for aarch64. //! Memory initialization for aarch64.
use ucore_memory::PAGE_SIZE; use ucore_memory::PAGE_SIZE;
use super::atags::atags::Atags;
use super::super::HEAP_ALLOCATOR;
/// Memory initialization. /// Memory initialization.
pub fn init() { 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
} }

@ -1,5 +1,7 @@
//! Entrance and initialization for aarch64. //! Entrance and initialization for aarch64.
extern crate atags;
pub mod io; pub mod io;
pub mod paging; pub mod paging;
pub mod memory; pub mod memory;
@ -18,6 +20,18 @@ pub extern "C" fn rust_main() -> ! {
// Init board to enable serial port. // Init board to enable serial port.
board::init(); board::init();
let (start, end) = memory::memory_map().expect("failed to find memory map");
println!("The value of start is: {}, end is {}", start, end);
memory::init();
println!("memory init over");
let mut v = vec![];
for i in 0..1000 {
v.push(i);
println!("{:?}", v);
}
// First init log mod, so that we can print log info. // First init log mod, so that we can print log info.
// FIXME // FIXME
// ::logging::init(); // ::logging::init();

Loading…
Cancel
Save