diff --git a/bootloader/Cargo.lock b/bootloader/Cargo.lock index 1b96241..e2fe90a 100644 --- a/bootloader/Cargo.lock +++ b/bootloader/Cargo.lock @@ -12,6 +12,13 @@ dependencies = [ "ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bcm2837" +version = "0.1.0" +dependencies = [ + "volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bit_field" version = "0.9.0" @@ -91,6 +98,7 @@ name = "rcore-bootloader" version = "0.1.0" dependencies = [ "aarch64 2.2.2 (git+https://github.com/equation314/aarch64)", + "bcm2837 0.1.0", "cc 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", "fixedvec 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "xmas-elf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -158,6 +166,11 @@ name = "ux" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "volatile" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "winapi" version = "0.3.6" @@ -212,6 +225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum usize_conversions 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f70329e2cbe45d6c97a5112daad40c34cd9a4e18edb5a2a18fefeb584d8d25e5" "checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f" +"checksum volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af0edf5b4faacc31fc51159244d78d65ec580f021afcef7bd53c04aeabc7f29" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/bootloader/Cargo.toml b/bootloader/Cargo.toml index 5a77dff..70f7550 100644 --- a/bootloader/Cargo.toml +++ b/bootloader/Cargo.toml @@ -10,6 +10,7 @@ fixedvec = "0.2.3" [target.'cfg(target_arch = "aarch64")'.dependencies] aarch64 = { git = "https://github.com/equation314/aarch64" } +bcm2837 = { path = "../crate/bcm2837" } [build-dependencies] cc = "1.0" diff --git a/bootloader/src/arch/aarch64/mod.rs b/bootloader/src/arch/aarch64/mod.rs index 61f9152..2ba1473 100644 --- a/bootloader/src/arch/aarch64/mod.rs +++ b/bootloader/src/arch/aarch64/mod.rs @@ -2,6 +2,7 @@ use aarch64::addr::{VirtAddr, PhysAddr}; use aarch64::paging::{memory_attribute::*, Page, PageTable, PageTableFlags as EF, PhysFrame}; use aarch64::paging::{Size4KiB, Size2MiB, Size1GiB}; use aarch64::{asm::*, barrier, regs::*}; +use bcm2837::consts::RAW_IO_BASE; use core::ptr; use fixedvec::FixedVec; use xmas_elf::program::{ProgramHeader64, Type}; @@ -9,9 +10,6 @@ use xmas_elf::program::{ProgramHeader64, Type}; const PAGE_SIZE: usize = 4096; const ALIGN_2MB: u64 = 0x200000; -const IO_REMAP_BASE: u64 = 0x3F00_0000; -const MEMORY_END: u64 = 0x4000_0000; - const RECURSIVE_INDEX: usize = 0o777; const KERNEL_OFFSET: u64 = 0xFFFF_0000_0000_0000; @@ -41,13 +39,13 @@ fn setup_temp_page_table(start_vaddr: VirtAddr, end_vaddr: VirtAddr, offset: u64 p2[page.p2_index()].set_block::(paddr, block_flags, MairNormal::attr_value()); } // device memory - for page in Page::::range_of(IO_REMAP_BASE, MEMORY_END) { + for page in Page::::range_of(RAW_IO_BASE as u64, 0x4000_0000) { let paddr = PhysAddr::new(page.start_address().as_u64()); p2[page.p2_index()].set_block::(paddr, block_flags | EF::PXN, MairDevice::attr_value()); } p3[0].set_frame(frame_lvl2, EF::default(), MairNormal::attr_value()); - p3[1].set_block::(PhysAddr::new(MEMORY_END), block_flags | EF::PXN, MairDevice::attr_value()); + p3[1].set_block::(PhysAddr::new(0x4000_0000), block_flags | EF::PXN, MairDevice::attr_value()); p4[0].set_frame(frame_lvl3, EF::default(), MairNormal::attr_value()); p4[RECURSIVE_INDEX].set_frame(frame_lvl4, EF::default(), MairNormal::attr_value()); diff --git a/crate/atags/Cargo.toml b/crate/atags/Cargo.toml deleted file mode 100644 index 3c095bf..0000000 --- a/crate/atags/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "atags" -version = "0.1.0" -authors = ["koumingyang <1761674434@qq.com>"] - -[dependencies] \ No newline at end of file diff --git a/crate/atags/src/lib.rs b/crate/atags/src/lib.rs deleted file mode 100644 index 33c76c2..0000000 --- a/crate/atags/src/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![no_std] - -mod raw; -mod atag; - -pub mod atags; diff --git a/crate/bcm2837/Cargo.toml b/crate/bcm2837/Cargo.toml index 456ee0e..18cb598 100644 --- a/crate/bcm2837/Cargo.toml +++ b/crate/bcm2837/Cargo.toml @@ -5,6 +5,7 @@ authors = ["equation314 "] edition = "2018" [features] +zero_kernel_offset = [] use_generic_timer = ["aarch64"] [dependencies] diff --git a/crate/atags/src/atag.rs b/crate/bcm2837/src/atags/atag.rs similarity index 88% rename from crate/atags/src/atag.rs rename to crate/bcm2837/src/atags/atag.rs index 77f729a..30315ea 100644 --- a/crate/atags/src/atag.rs +++ b/crate/bcm2837/src/atags/atag.rs @@ -1,9 +1,7 @@ -use raw; +use super::raw; use core::slice; use core::str; -pub use raw::{Core, Mem}; - /// An ATAG. #[derive(Debug, Copy, Clone)] pub enum Atag { @@ -11,12 +9,12 @@ pub enum Atag { Mem(raw::Mem), Cmd(&'static str), Unknown(u32), - None + None, } impl Atag { /// Returns `Some` if this is a `Core` ATAG. Otherwise returns `None`. - pub fn core(self) -> Option { + pub fn core(self) -> Option { match self { Atag::Core(x) => Some(x), _ => None, @@ -24,7 +22,7 @@ impl Atag { } /// Returns `Some` if this is a `Mem` ATAG. Otherwise returns `None`. - pub fn mem(self) -> Option { + pub fn mem(self) -> Option { match self { Atag::Mem(x) => Some(x), _ => None, @@ -49,7 +47,7 @@ impl<'a> From<&'a raw::Atag> for Atag { (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 cmd_ptr: *const u8 = &cmd.cmd as *const u8; let mut len: usize = 0; while *cmd_ptr.add(len) != 0 { @@ -58,7 +56,7 @@ impl<'a> From<&'a raw::Atag> for Atag { 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), } diff --git a/crate/atags/src/atags.rs b/crate/bcm2837/src/atags/mod.rs similarity index 75% rename from crate/atags/src/atags.rs rename to crate/bcm2837/src/atags/mod.rs index 98b7522..8787fcc 100644 --- a/crate/atags/src/atags.rs +++ b/crate/bcm2837/src/atags/mod.rs @@ -1,8 +1,12 @@ -pub use atag::*; -use raw; +mod atag; +mod raw; + +use super::consts::KERNEL_OFFSET; +pub use self::atag::*; +pub use self::raw::{Cmd, Core, Mem}; /// The address at which the firmware loads the ATAGS. -const ATAG_BASE: usize = 0x100; +const ATAG_BASE: usize = KERNEL_OFFSET + 0x100; /// An iterator over the ATAGS on this system. pub struct Atags { @@ -13,7 +17,7 @@ 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) } + ptr: unsafe { &*(ATAG_BASE as *const raw::Atag) }, } } } @@ -30,7 +34,7 @@ impl Iterator for Atags { let result = Some(Atag::from(cur)); self.ptr = next; result - }, + } None => None, } } diff --git a/crate/atags/src/raw.rs b/crate/bcm2837/src/atags/raw.rs similarity index 85% rename from crate/atags/src/raw.rs rename to crate/bcm2837/src/atags/raw.rs index abfd166..22bed83 100644 --- a/crate/atags/src/raw.rs +++ b/crate/bcm2837/src/atags/raw.rs @@ -3,7 +3,7 @@ pub struct Atag { pub dwords: u32, pub tag: u32, - pub kind: Kind + pub kind: Kind, } impl Atag { @@ -24,9 +24,7 @@ impl Atag { None } else { let current = self as *const Atag as *const u32; - let next: &Atag = unsafe { - &*(current.add(self.dwords as usize) as *const Atag) - }; + let next: &Atag = unsafe { &*(current.add(self.dwords as usize) as *const Atag) }; Some(next) } @@ -38,7 +36,7 @@ impl Atag { pub union Kind { pub core: Core, pub mem: Mem, - pub cmd: Cmd + pub cmd: Cmd, } /// A `CORE` ATAG. @@ -47,7 +45,7 @@ pub union Kind { pub struct Core { pub flags: u32, pub page_size: u32, - pub root_dev: u32 + pub root_dev: u32, } /// A `MEM` ATAG. @@ -55,7 +53,7 @@ pub struct Core { #[derive(Debug, Copy, Clone)] pub struct Mem { pub size: u32, - pub start: u32 + pub start: u32, } /// A `CMDLINE` ATAG. @@ -63,5 +61,5 @@ pub struct Mem { #[derive(Debug, Copy, Clone)] pub struct Cmd { /// The first byte of the command line string. - pub cmd: u8 + pub cmd: u8, } diff --git a/crate/bcm2837/src/consts.rs b/crate/bcm2837/src/consts.rs new file mode 100644 index 0000000..92ec433 --- /dev/null +++ b/crate/bcm2837/src/consts.rs @@ -0,0 +1,7 @@ +#[cfg(feature = "zero_kernel_offset")] +pub const KERNEL_OFFSET: usize = 0; +#[cfg(not(feature = "zero_kernel_offset"))] +pub const KERNEL_OFFSET: usize = 0xFFFF_0000_0000_0000; + +pub const RAW_IO_BASE: usize = 0x3F00_0000; +pub const IO_BASE: usize = KERNEL_OFFSET + RAW_IO_BASE; diff --git a/crate/bcm2837/src/gpio.rs b/crate/bcm2837/src/gpio.rs index ef258d6..2bcf901 100644 --- a/crate/bcm2837/src/gpio.rs +++ b/crate/bcm2837/src/gpio.rs @@ -1,4 +1,4 @@ -use crate::IO_BASE; +use crate::consts::IO_BASE; use crate::timer::delay; use core::marker::PhantomData; use volatile::{ReadOnly, Volatile, WriteOnly}; diff --git a/crate/bcm2837/src/interrupt.rs b/crate/bcm2837/src/interrupt.rs index 03657c9..d3caba6 100644 --- a/crate/bcm2837/src/interrupt.rs +++ b/crate/bcm2837/src/interrupt.rs @@ -1,4 +1,4 @@ -use crate::IO_BASE; +use crate::consts::IO_BASE; use volatile::{ReadOnly, Volatile}; const INT_BASE: usize = IO_BASE + 0xB000 + 0x200; diff --git a/crate/bcm2837/src/lib.rs b/crate/bcm2837/src/lib.rs index 2755e55..ba9cc2a 100644 --- a/crate/bcm2837/src/lib.rs +++ b/crate/bcm2837/src/lib.rs @@ -3,10 +3,10 @@ extern crate volatile; +pub mod atags; +pub mod consts; pub mod gpio; -pub mod timer; +pub mod interrupt; pub mod mailbox; pub mod mini_uart; -pub mod interrupt; - -pub const IO_BASE: usize = 0xFFFF_0000_3F00_0000; +pub mod timer; diff --git a/crate/bcm2837/src/mailbox.rs b/crate/bcm2837/src/mailbox.rs index 0e7d32f..e20c0ff 100644 --- a/crate/bcm2837/src/mailbox.rs +++ b/crate/bcm2837/src/mailbox.rs @@ -1,4 +1,4 @@ -use crate::IO_BASE; +use crate::consts::IO_BASE; use volatile::{ReadOnly, Volatile, WriteOnly}; /// The base address for the `MU` registers. diff --git a/crate/bcm2837/src/mini_uart.rs b/crate/bcm2837/src/mini_uart.rs index a3a5503..9606cf8 100644 --- a/crate/bcm2837/src/mini_uart.rs +++ b/crate/bcm2837/src/mini_uart.rs @@ -1,4 +1,4 @@ -use crate::IO_BASE; +use crate::consts::IO_BASE; use crate::gpio::{Function, Gpio}; use volatile::{ReadOnly, Volatile}; diff --git a/crate/bcm2837/src/timer/generic_timer.rs b/crate/bcm2837/src/timer/generic_timer.rs index bc54053..9128dce 100644 --- a/crate/bcm2837/src/timer/generic_timer.rs +++ b/crate/bcm2837/src/timer/generic_timer.rs @@ -1,11 +1,12 @@ extern crate aarch64; use super::BasicTimer; +use crate::consts::KERNEL_OFFSET; use aarch64::regs::*; use volatile::*; /// The base address for the ARM generic timer, IRQs, mailboxes -const GEN_TIMER_REG_BASE: usize = 0xFFFF_0000_4000_0000; +const GEN_TIMER_REG_BASE: usize = KERNEL_OFFSET + 0x4000_0000; /// Core interrupt sources (ref: QA7 4.10, page 16) #[repr(u8)] diff --git a/crate/bcm2837/src/timer/system_timer.rs b/crate/bcm2837/src/timer/system_timer.rs index 9261c4a..6ad1d85 100644 --- a/crate/bcm2837/src/timer/system_timer.rs +++ b/crate/bcm2837/src/timer/system_timer.rs @@ -1,6 +1,6 @@ use super::BasicTimer; +use crate::consts::IO_BASE; use crate::interrupt::{Controller, Interrupt}; -use crate::IO_BASE; use volatile::{ReadOnly, Volatile}; /// The base address for the ARM system timer registers. diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index c14e2d1..fe415ce 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -30,10 +30,6 @@ dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "atags" -version = "0.1.0" - [[package]] name = "bare-metal" version = "0.2.4" @@ -251,7 +247,6 @@ version = "0.1.0" dependencies = [ "aarch64 2.2.2 (git+https://github.com/equation314/aarch64)", "apic 0.1.0 (git+https://github.com/wangrunji0408/APIC-Rust)", - "atags 0.1.0", "bbl 0.1.0", "bcm2837 0.1.0", "bit-allocator 0.1.0", diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 2619130..6b26913 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -72,7 +72,6 @@ bbl = { path = "../crate/bbl" } [target.'cfg(target_arch = "aarch64")'.dependencies] aarch64 = { git = "https://github.com/equation314/aarch64" } -atags = { path = "../crate/atags" } bcm2837 = { path = "../crate/bcm2837", optional = true } [package.metadata.bootimage] diff --git a/kernel/src/arch/aarch64/board/raspi3/mod.rs b/kernel/src/arch/aarch64/board/raspi3/mod.rs index c001b34..ff959e4 100644 --- a/kernel/src/arch/aarch64/board/raspi3/mod.rs +++ b/kernel/src/arch/aarch64/board/raspi3/mod.rs @@ -1,6 +1,7 @@ //! Raspberry PI 3 Model B/B+ use once::*; +use bcm2837::atags::Atags; pub mod fb; pub mod irq; @@ -8,8 +9,8 @@ pub mod timer; pub mod serial; pub mod mailbox; -pub const IO_REMAP_BASE: usize = bcm2837::IO_BASE; -pub const IO_REMAP_END: usize = 0xFFFF_0000_4000_1000; +pub const IO_REMAP_BASE: usize = bcm2837::consts::IO_BASE; +pub const IO_REMAP_END: usize = bcm2837::consts::KERNEL_OFFSET + 0x4000_1000; /// Initialize serial port before other initializations. pub fn init_serial_early() { @@ -26,3 +27,17 @@ pub fn init_driver() { fb::init(); timer::init(); } + +/// Returns the (start address, end address) of the physical 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 probe_memory() -> Option<(usize, usize)> { + let mut atags: Atags = Atags::get(); + while let Some(atag) = atags.next() { + if let Some(mem) = atag.mem() { + return Some((mem.start as usize, (mem.start + mem.size) as usize)); + } + } + None +} diff --git a/kernel/src/arch/aarch64/memory.rs b/kernel/src/arch/aarch64/memory.rs index 1fd2162..c40a055 100644 --- a/kernel/src/arch/aarch64/memory.rs +++ b/kernel/src/arch/aarch64/memory.rs @@ -4,7 +4,6 @@ use crate::memory::{init_heap, Linear, MemoryAttr, MemorySet, FRAME_ALLOCATOR}; use crate::consts::{MEMORY_OFFSET, KERNEL_OFFSET}; use super::paging::MMIOType; use aarch64::regs::*; -use atags::atags::Atags; use log::*; use rcore_memory::PAGE_SIZE; @@ -20,7 +19,8 @@ fn init_frame_allocator() { use bit_allocator::BitAlloc; use core::ops::Range; - let (start, end) = memory_map().expect("failed to find memory map"); + let end = super::board::probe_memory().expect("failed to find memory map").1; + let start = (_end as u64 + PAGE_SIZE as u64).wrapping_sub(KERNEL_OFFSET as u64) as usize; let mut ba = FRAME_ALLOCATOR.lock(); ba.insert(to_range(start, end)); info!("FrameAllocator init end"); @@ -72,23 +72,6 @@ pub fn ioremap(paddr: usize, len: usize, name: &'static str) -> usize { 0 } -/// 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. -fn memory_map() -> Option<(usize, usize)> { - let binary_end = (_end as u64).wrapping_sub(KERNEL_OFFSET as u64); - - 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 -} - extern "C" { fn bootstacktop(); fn stext(); diff --git a/kernel/src/arch/aarch64/paging.rs b/kernel/src/arch/aarch64/paging.rs index 51735c4..e5da2bb 100644 --- a/kernel/src/arch/aarch64/paging.rs +++ b/kernel/src/arch/aarch64/paging.rs @@ -30,8 +30,7 @@ impl PageTable for ActivePageTable { fn get_entry(&mut self, vaddr: usize) -> Option<&mut Entry> { // get p1 entry - let entry_addr = ((vaddr >> 9) & 0o777_777_777_7770) | (RECURSIVE_INDEX << 39) - | (vaddr & 0xffff_0000_0000_0000); + let entry_addr = ((vaddr >> 9) & 0o777_777_777_7770) | (RECURSIVE_INDEX << 39) | (vaddr & KERNEL_OFFSET); Some(unsafe { &mut *(entry_addr as *mut PageEntry) }) } }