mem: starting to get memory manager working
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
9a4d002832
commit
8521093f6d
40
Cargo.lock
generated
40
Cargo.lock
generated
@ -55,16 +55,6 @@ name = "rand_core"
|
|||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "riscv-rt-macros"
|
|
||||||
version = "0.1.6"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
@ -105,8 +95,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
name = "xous-kernel"
|
name = "xous-kernel"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"xous-kernel-riscv-rt 0.6.1",
|
||||||
"xous-riscv 0.5.4",
|
"xous-riscv 0.5.4",
|
||||||
"xous-riscv-rt 0.6.1",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xous-kernel-riscv-rt"
|
||||||
|
version = "0.6.1"
|
||||||
|
dependencies = [
|
||||||
|
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"xous-kernel-riscv-rt-macros 0.1.6",
|
||||||
|
"xous-riscv 0.5.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xous-kernel-riscv-rt-macros"
|
||||||
|
version = "0.1.6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -117,15 +126,6 @@ dependencies = [
|
|||||||
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xous-riscv-rt"
|
|
||||||
version = "0.6.1"
|
|
||||||
dependencies = [
|
|
||||||
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"riscv-rt-macros 0.1.6",
|
|
||||||
"xous-riscv 0.5.4",
|
|
||||||
]
|
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
"checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a"
|
"checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a"
|
||||||
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
|
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
|
||||||
|
6
memory.x
6
memory.x
@ -9,8 +9,10 @@ REGION_ALIAS("REGION_TEXT", FLASH);
|
|||||||
REGION_ALIAS("REGION_RODATA", FLASH);
|
REGION_ALIAS("REGION_RODATA", FLASH);
|
||||||
REGION_ALIAS("REGION_DATA", RAM);
|
REGION_ALIAS("REGION_DATA", RAM);
|
||||||
REGION_ALIAS("REGION_BSS", RAM);
|
REGION_ALIAS("REGION_BSS", RAM);
|
||||||
REGION_ALIAS("REGION_HEAP", RAM);
|
|
||||||
REGION_ALIAS("REGION_STACK", RAM);
|
REGION_ALIAS("REGION_STACK", RAM);
|
||||||
|
REGION_ALIAS("REGION_HEAP", RAM);
|
||||||
|
|
||||||
_lcdfb = ORIGIN(MEMLCD);
|
_lcdfb = ORIGIN(MEMLCD);
|
||||||
_heap_size = LENGTH(RAM) - 1M;
|
/* Size of the main kernel stack */
|
||||||
|
_stack_size = 16K;
|
||||||
|
_eheap = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
35
src/irq.rs
35
src/irq.rs
@ -1,40 +1,7 @@
|
|||||||
use crate::syscalls;
|
use crate::syscalls;
|
||||||
|
use crate::filled_array;
|
||||||
use xous_riscv::register::{mstatus, vmim};
|
use xous_riscv::register::{mstatus, vmim};
|
||||||
|
|
||||||
// Shamelessly taken from
|
|
||||||
// https://stackoverflow.com/questions/36258417/using-a-macro-to-initialize-a-big-array-of-non-copy-elements
|
|
||||||
// Allows us to fill an array with a predefined value.
|
|
||||||
macro_rules! filled_array {
|
|
||||||
(@accum (0, $($_es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@as_expr [$($body)*])};
|
|
||||||
(@accum (1, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (0, $($es),*) -> ($($body)* $($es,)*))};
|
|
||||||
(@accum (2, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (0, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
|
|
||||||
(@accum (3, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (2, $($es),*) -> ($($body)* $($es,)*))};
|
|
||||||
(@accum (4, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (2, $($es,)* $($es),*) -> ($($body)*))};
|
|
||||||
(@accum (5, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)*))};
|
|
||||||
(@accum (6, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
|
|
||||||
(@accum (7, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)* $($es,)*))};
|
|
||||||
(@accum (8, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (4, $($es,)* $($es),*) -> ($($body)*))};
|
|
||||||
(@accum (16, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (8, $($es,)* $($es),*) -> ($($body)*))};
|
|
||||||
(@accum (32, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (16, $($es,)* $($es),*) -> ($($body)*))};
|
|
||||||
(@accum (64, $($es:expr),*) -> ($($body:tt)*))
|
|
||||||
=> {filled_array!(@accum (32, $($es,)* $($es),*) -> ($($body)*))};
|
|
||||||
|
|
||||||
(@as_expr $e:expr) => {$e};
|
|
||||||
|
|
||||||
[$e:expr; $n:tt] => { filled_array!(@accum ($n, $e) -> ()) };
|
|
||||||
}
|
|
||||||
|
|
||||||
static mut IRQ_HANDLERS: [Option<fn(usize)>; 32] = filled_array![None; 32];
|
static mut IRQ_HANDLERS: [Option<fn(usize)>; 32] = filled_array![None; 32];
|
||||||
|
|
||||||
pub fn handle(irqs_pending: usize) {
|
pub fn handle(irqs_pending: usize) {
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
extern crate xous_riscv;
|
extern crate xous_riscv;
|
||||||
|
|
||||||
use core::panic::PanicInfo;
|
// use core::panic::PanicInfo;
|
||||||
#[panic_handler]
|
// #[panic_handler]
|
||||||
fn handle_panic(_arg: &PanicInfo) -> ! {
|
// fn handle_panic(_arg: &PanicInfo) -> ! {
|
||||||
loop {}
|
// loop {}
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Allow consumers of this library to make syscalls
|
// Allow consumers of this library to make syscalls
|
||||||
pub mod syscalls;
|
pub mod syscalls;
|
||||||
|
46
src/macros.rs
Normal file
46
src/macros.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Shamelessly taken from
|
||||||
|
// https://stackoverflow.com/questions/36258417/using-a-macro-to-initialize-a-big-array-of-non-copy-elements
|
||||||
|
// Allows us to fill an array with a predefined value.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! filled_array {
|
||||||
|
(@accum (0, $($_es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@as_expr [$($body)*])};
|
||||||
|
(@accum (1, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (0, $($es),*) -> ($($body)* $($es,)*))};
|
||||||
|
(@accum (2, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (0, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
|
||||||
|
(@accum (3, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (2, $($es),*) -> ($($body)* $($es,)*))};
|
||||||
|
(@accum (4, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (2, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (5, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)*))};
|
||||||
|
(@accum (6, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)*))};
|
||||||
|
(@accum (7, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)* $($es,)*))};
|
||||||
|
(@accum (8, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (4, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (16, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (8, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (32, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (16, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (64, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (32, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (128, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (64, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (256, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (128, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (512, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (256, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (1024, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (512, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (2048, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (1024, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
(@accum (4096, $($es:expr),*) -> ($($body:tt)*))
|
||||||
|
=> {filled_array!(@accum (2048, $($es,)* $($es),*) -> ($($body)*))};
|
||||||
|
|
||||||
|
(@as_expr $e:expr) => {$e};
|
||||||
|
|
||||||
|
[$e:expr; $n:tt] => { filled_array!(@accum ($n, $e) -> ()) };
|
||||||
|
}
|
@ -4,12 +4,15 @@
|
|||||||
extern crate xous_riscv;
|
extern crate xous_riscv;
|
||||||
mod syscalls;
|
mod syscalls;
|
||||||
mod irq;
|
mod irq;
|
||||||
|
mod macros;
|
||||||
|
mod mem;
|
||||||
|
|
||||||
pub use irq::sys_interrupt_claim;
|
pub use irq::sys_interrupt_claim;
|
||||||
|
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use xous_kernel_riscv_rt::xous_kernel_entry;
|
use xous_kernel_riscv_rt::xous_kernel_entry;
|
||||||
use xous_riscv::register::{mcause, mstatus, mie, vmim, vmip};
|
use xous_riscv::register::{mcause, mstatus, mie, vmim, vmip};
|
||||||
|
use mem::MemoryManager;
|
||||||
|
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
@ -32,6 +35,7 @@ fn xous_main() -> ! {
|
|||||||
mie::set_mext();
|
mie::set_mext();
|
||||||
mstatus::set_mie(); // Enable CPU interrupts
|
mstatus::set_mie(); // Enable CPU interrupts
|
||||||
}
|
}
|
||||||
|
let mm = MemoryManager::new();
|
||||||
sys_interrupt_claim(2, |_| {
|
sys_interrupt_claim(2, |_| {
|
||||||
let uart_ptr = 0xE000_1800 as *mut usize;
|
let uart_ptr = 0xE000_1800 as *mut usize;
|
||||||
print_str(uart_ptr, "hello, world!\r\n");
|
print_str(uart_ptr, "hello, world!\r\n");
|
||||||
|
127
src/mem.rs
Normal file
127
src/mem.rs
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
use crate::syscalls::{XousError, XousPid};
|
||||||
|
use xous_riscv::register::mstatus;
|
||||||
|
|
||||||
|
const FLASH_START: usize = 0x20000000;
|
||||||
|
const FLASH_SIZE: usize = 16_777_216;
|
||||||
|
const FLASH_END: usize = FLASH_START + FLASH_SIZE;
|
||||||
|
const RAM_START: usize = 0x40000000;
|
||||||
|
const RAM_SIZE: usize = 16_777_216;
|
||||||
|
const RAM_END: usize = RAM_START + RAM_SIZE;
|
||||||
|
const IO_START: usize = 0xe0000000;
|
||||||
|
const IO_SIZE: usize = 65_536;
|
||||||
|
const IO_END: usize = IO_START + IO_SIZE;
|
||||||
|
const LCD_START: usize = 0xB0000000;
|
||||||
|
const LCD_SIZE: usize = 32_768;
|
||||||
|
const LCD_END: usize = LCD_START + LCD_SIZE;
|
||||||
|
|
||||||
|
const PAGE_SIZE: usize = 4096;
|
||||||
|
|
||||||
|
const FLASH_PAGE_COUNT: usize = FLASH_SIZE / PAGE_SIZE;
|
||||||
|
const RAM_PAGE_COUNT: usize = RAM_SIZE / PAGE_SIZE;
|
||||||
|
const IO_PAGE_COUNT: usize = IO_SIZE;
|
||||||
|
const LCD_PAGE_COUNT: usize = LCD_SIZE / PAGE_SIZE;
|
||||||
|
pub struct MemoryManager {
|
||||||
|
flash: [u8; FLASH_PAGE_COUNT],
|
||||||
|
ram: [u8; RAM_PAGE_COUNT],
|
||||||
|
io: [u8; IO_PAGE_COUNT],
|
||||||
|
lcd: [u8; LCD_PAGE_COUNT],
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// Boundaries of the .bss section
|
||||||
|
static mut _ebss: usize;
|
||||||
|
static mut _sbss: usize;
|
||||||
|
|
||||||
|
// Boundaries of the .data section
|
||||||
|
static mut _edata: usize;
|
||||||
|
static mut _sdata: usize;
|
||||||
|
|
||||||
|
// Boundaries of the stack
|
||||||
|
static mut _estack: usize;
|
||||||
|
static mut _sstack: usize;
|
||||||
|
|
||||||
|
// Boundaries of the heap
|
||||||
|
static _sheap: usize;
|
||||||
|
static _eheap: usize;
|
||||||
|
|
||||||
|
// Initial values of the .data section (stored in Flash)
|
||||||
|
static _sidata: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
use core::mem::transmute;
|
||||||
|
|
||||||
|
/// Initialzie the memory map.
|
||||||
|
/// This will go through memory and map anything that the kernel is
|
||||||
|
/// using to process 0xff, then allocate a pagetable for this process
|
||||||
|
/// and place it at the usual offset.
|
||||||
|
/// Finally, it will enable the MMU.
|
||||||
|
impl MemoryManager {
|
||||||
|
pub fn new() -> MemoryManager {
|
||||||
|
let mut mm = MemoryManager {
|
||||||
|
flash: [0; FLASH_PAGE_COUNT],
|
||||||
|
ram: [0; RAM_PAGE_COUNT],
|
||||||
|
io: [0; IO_PAGE_COUNT],
|
||||||
|
lcd: [0; LCD_PAGE_COUNT],
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe { mstatus::clear_mie() };
|
||||||
|
|
||||||
|
// Map the bss section
|
||||||
|
let start_bss = unsafe { transmute::<&usize, usize>(&_sbss) };
|
||||||
|
let end_bss = unsafe { transmute::<&usize, usize>(&_ebss) };
|
||||||
|
let bss_range = (start_bss..end_bss).step_by(PAGE_SIZE);
|
||||||
|
|
||||||
|
let start_data = unsafe { transmute::<&usize, usize>(&_sdata) };
|
||||||
|
let end_data = unsafe { transmute::<&usize, usize>(&_edata) };
|
||||||
|
let data_range = (start_data..end_data).step_by(PAGE_SIZE);
|
||||||
|
|
||||||
|
// Note: stack grows downwards so these are swapped.
|
||||||
|
let start_stack = unsafe { transmute::<&usize, usize>(&_estack) };
|
||||||
|
let end_stack = unsafe { transmute::<&usize, usize>(&_sstack) };
|
||||||
|
let stack_range = (start_stack..end_stack).step_by(PAGE_SIZE);
|
||||||
|
|
||||||
|
for region in bss_range {
|
||||||
|
mm.claim_page(region & !0xfff, 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for region in data_range {
|
||||||
|
mm.claim_page(region & !0xfff, 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for region in stack_range {
|
||||||
|
mm.claim_page(region & !0xfff, 1).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { mstatus::set_mie() };
|
||||||
|
mm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn claim_page(&mut self, addr: usize, pid: XousPid) -> Result<(), XousError> {
|
||||||
|
// Ensure the address lies on a page boundary
|
||||||
|
if addr & 0xfff != 0 {
|
||||||
|
return Err(XousError::BadAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
FLASH_START..=FLASH_END => {
|
||||||
|
Self::claim_page_inner(&mut self.flash, addr - FLASH_START, pid)
|
||||||
|
}
|
||||||
|
RAM_START..=RAM_END => Self::claim_page_inner(&mut self.ram, addr - RAM_START, pid),
|
||||||
|
IO_START..=IO_END => Self::claim_page_inner(&mut self.io, addr - IO_START, pid),
|
||||||
|
LCD_START..=LCD_END => Self::claim_page_inner(&mut self.lcd, addr - LCD_START, pid),
|
||||||
|
_ => Err(XousError::BadAddress),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn claim_page_inner(tbl: &mut [u8], addr: usize, pid: XousPid) -> Result<(), XousError> {
|
||||||
|
let page = addr / PAGE_SIZE;
|
||||||
|
if page > tbl.len() {
|
||||||
|
return Err(XousError::BadAddress);
|
||||||
|
}
|
||||||
|
if tbl[page] != 0 {
|
||||||
|
return Err(XousError::OutOfMemory);
|
||||||
|
}
|
||||||
|
tbl[page] = pid;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -74,23 +74,23 @@ SECTIONS
|
|||||||
_ebss = .;
|
_ebss = .;
|
||||||
} > REGION_BSS
|
} > REGION_BSS
|
||||||
|
|
||||||
/* fictitious region that represents the memory available for the heap */
|
|
||||||
.heap (NOLOAD) :
|
|
||||||
{
|
|
||||||
_sheap = .;
|
|
||||||
. += _heap_size;
|
|
||||||
. = ALIGN(4);
|
|
||||||
_eheap = .;
|
|
||||||
} > REGION_HEAP
|
|
||||||
|
|
||||||
/* fictitious region that represents the memory available for the stack */
|
/* fictitious region that represents the memory available for the stack */
|
||||||
.stack (NOLOAD) :
|
.stack (NOLOAD) :
|
||||||
{
|
{
|
||||||
_estack = .;
|
_estack = .;
|
||||||
. = _stack_start;
|
PROVIDE(_stack_start = .);
|
||||||
|
. += _stack_size;
|
||||||
_sstack = .;
|
_sstack = .;
|
||||||
} > REGION_STACK
|
} > REGION_STACK
|
||||||
|
|
||||||
|
/* fictitious region that represents the memory available for the heap */
|
||||||
|
.heap (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sheap = .;
|
||||||
|
/* _eheap is defined elsewhere and is the remainder of RAM */
|
||||||
|
} > REGION_HEAP
|
||||||
|
|
||||||
/* fake output .got section */
|
/* fake output .got section */
|
||||||
/* Dynamic relocations are unsupported. This section is only used to detect
|
/* Dynamic relocations are unsupported. This section is only used to detect
|
||||||
relocatable code in the input files and raise an error if relocatable code
|
relocatable code in the input files and raise an error if relocatable code
|
||||||
|
Loading…
Reference in New Issue
Block a user