feat: ✨ Update linker script
* Add MMIO remap region * Move script to appropriate place
This commit is contained in:
parent
e8a587ea7b
commit
134d7c530f
|
@ -1,5 +1,7 @@
|
||||||
const LINKER_SCRIPT: &str = "linker/aarch64.ld";
|
/// This build script is used to create lib tests.
|
||||||
const LINKER_SCRIPT_AUX: &str = "linker/aarch64-exceptions.ld";
|
|
||||||
|
const LINKER_SCRIPT: &str = "machine/src/platform/raspberrypi/linker/kernel.ld";
|
||||||
|
const LINKER_SCRIPT_AUX: &str = "machine/src/arch/aarch64/linker/aarch64-exceptions.ld";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed={}", LINKER_SCRIPT);
|
println!("cargo:rerun-if-changed={}", LINKER_SCRIPT);
|
||||||
|
|
|
@ -65,10 +65,10 @@ pub unsafe extern "C" fn _boot_cores() -> ! {
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
// Stack top
|
// Stack top
|
||||||
// Stack placed before first executable instruction
|
// Stack placed before first executable instruction
|
||||||
static __STACK_START: UnsafeCell<()>;
|
static __STACK_TOP: UnsafeCell<()>;
|
||||||
}
|
}
|
||||||
// Set stack pointer. Used in case we started in EL1.
|
// Set stack pointer. Used in case we started in EL1.
|
||||||
SP.set(__STACK_START.get() as u64);
|
SP.set(__STACK_TOP.get() as u64);
|
||||||
|
|
||||||
shared_setup_and_enter_pre();
|
shared_setup_and_enter_pre();
|
||||||
|
|
||||||
|
@ -122,12 +122,12 @@ fn shared_setup_and_enter_pre() {
|
||||||
fn shared_setup_and_enter_post() -> ! {
|
fn shared_setup_and_enter_post() -> ! {
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
// Stack top
|
// Stack top
|
||||||
static __STACK_START: UnsafeCell<()>;
|
static __STACK_TOP: UnsafeCell<()>;
|
||||||
}
|
}
|
||||||
// Set up SP_EL1 (stack pointer), which will be used by EL1 once
|
// Set up SP_EL1 (stack pointer), which will be used by EL1 once
|
||||||
// we "return" to it.
|
// we "return" to it.
|
||||||
unsafe {
|
unsafe {
|
||||||
SP_EL1.set(__STACK_START.get() as u64);
|
SP_EL1.set(__STACK_TOP.get() as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use `eret` to "return" to EL1. This will result in execution of
|
// Use `eret` to "return" to EL1. This will result in execution of
|
||||||
|
|
|
@ -5,11 +5,14 @@
|
||||||
* Original code distributed under MIT, additional changes are under BlueOak-1.0.0
|
* Original code distributed under MIT, additional changes are under BlueOak-1.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
PAGE_SIZE = 64K;
|
||||||
|
PAGE_MASK = PAGE_SIZE - 1;
|
||||||
|
|
||||||
|
__phys_mem_start = 0x0;
|
||||||
|
|
||||||
__phys_load_addr = 0x80000;
|
__phys_load_addr = 0x80000;
|
||||||
ENTRY(__phys_load_addr);
|
ENTRY(__phys_load_addr);
|
||||||
|
|
||||||
PAGE_SIZE = 65536;
|
|
||||||
|
|
||||||
/* Flags:
|
/* Flags:
|
||||||
* 4 == R
|
* 4 == R
|
||||||
* 5 == RX
|
* 5 == RX
|
||||||
|
@ -26,13 +29,26 @@ PHDRS
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Symbols between __BOOT_START and __BOOT_END should be dropped after init is complete.
|
/* Symbols between __BOOT_START and __BOOT_END should be dropped after init is complete.
|
||||||
Symbols between __RO_START and __RO_END are the kernel code.
|
Symbols between __CODE_START and __CODE_END are the kernel code.
|
||||||
Symbols between __BSS_START and __BSS_END must be initialized to zero by startup code in the kernel.
|
Symbols between __BSS_START and __BSS_END must be initialized to zero by startup code in the kernel.
|
||||||
*/
|
*/
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
__STACK_START = __phys_load_addr; /* Stack grows from here towards 0x0. */
|
. = __phys_mem_start;
|
||||||
. = __phys_load_addr; /* AArch64 boot address is 0x80000, 4K-aligned */
|
|
||||||
|
/***********************************************************************************************
|
||||||
|
* Boot Core Stack
|
||||||
|
***********************************************************************************************/
|
||||||
|
.boot_core_stack (NOLOAD) :
|
||||||
|
{
|
||||||
|
__STACK_BOTTOM = .; /* ^ */
|
||||||
|
/* | stack */
|
||||||
|
. = __phys_load_addr; /* | growth AArch64 boot address is 0x80000, 4K-aligned */
|
||||||
|
/* | direction */
|
||||||
|
__STACK_TOP = .; /* | Stack grows from here towards 0x0. */
|
||||||
|
} :segment_boot_core_stack
|
||||||
|
|
||||||
|
ASSERT((. & PAGE_MASK) == 0, "End of boot core stack is not page aligned")
|
||||||
|
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
* Code + RO Data
|
* Code + RO Data
|
||||||
|
@ -43,19 +59,19 @@ SECTIONS
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
* Boot Code + Boot Data
|
* Boot Code + Boot Data
|
||||||
*******************************************************************************************/
|
*******************************************************************************************/
|
||||||
|
|
||||||
__BOOT_START = .;
|
__BOOT_START = .;
|
||||||
KEEP(*(.text.main.entry))
|
KEEP(*(.text.main.entry))
|
||||||
*(.text.boot)
|
*(.text.boot)
|
||||||
*(.data.boot)
|
*(.data.boot)
|
||||||
. = ALIGN(PAGE_SIZE); /* Here the boot code ends */
|
. = ALIGN(PAGE_SIZE);
|
||||||
__BOOT_END = .; // __BOOT_END must be PAGE_SIZE aligned
|
__BOOT_END = .; /* Here the boot code ends */
|
||||||
|
ASSERT((__BOOT_END & PAGE_MASK) == 0, "End of boot code is not page aligned")
|
||||||
|
|
||||||
/*******************************************************************************************
|
/*******************************************************************************************
|
||||||
* Regular Kernel Code
|
* Regular Kernel Code
|
||||||
*******************************************************************************************/
|
*******************************************************************************************/
|
||||||
|
|
||||||
__RO_START = .;
|
__CODE_START = .;
|
||||||
*(.text*)
|
*(.text*)
|
||||||
} :segment_code
|
} :segment_code
|
||||||
|
|
||||||
|
@ -72,7 +88,8 @@ SECTIONS
|
||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
FILL(0x00)
|
FILL(0x00)
|
||||||
. = ALIGN(PAGE_SIZE); /* Fill up to page size */
|
. = ALIGN(PAGE_SIZE); /* Fill up to page size */
|
||||||
__RO_END = .; /* __RO_END must be PAGE_SIZE aligned */
|
__CODE_END = .;
|
||||||
|
ASSERT((__CODE_END & PAGE_MASK) == 0, "End of kernel code is not page aligned")
|
||||||
} :segment_code
|
} :segment_code
|
||||||
|
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
|
@ -81,7 +98,8 @@ SECTIONS
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
{
|
{
|
||||||
__DATA_START = .; /* __DATA_START must be PAGE_SIZE aligned */
|
__DATA_START = .;
|
||||||
|
ASSERT((__DATA_START & PAGE_MASK) == 0, "Start of kernel data is not page aligned")
|
||||||
*(.data*)
|
*(.data*)
|
||||||
FILL(0x00)
|
FILL(0x00)
|
||||||
} :segment_data
|
} :segment_data
|
||||||
|
@ -96,6 +114,17 @@ SECTIONS
|
||||||
__BSS_SIZE_U64S = (__BSS_END - __BSS_START) / 8;
|
__BSS_SIZE_U64S = (__BSS_END - __BSS_START) / 8;
|
||||||
} :segment_data
|
} :segment_data
|
||||||
|
|
||||||
|
__DATA_END = .;
|
||||||
|
|
||||||
|
/***********************************************************************************************
|
||||||
|
* MMIO Remap Reserved
|
||||||
|
***********************************************************************************************/
|
||||||
|
__MMIO_REMAP_START = .;
|
||||||
|
. += 8 * 1024 * 1024;
|
||||||
|
__MMIO_REMAP_END = .;
|
||||||
|
|
||||||
|
ASSERT((. & PAGE_MASK) == 0, "MMIO remap reservation is not page aligned")
|
||||||
|
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
* Misc
|
* Misc
|
||||||
***********************************************************************************************/
|
***********************************************************************************************/
|
||||||
|
@ -106,4 +135,4 @@ SECTIONS
|
||||||
/DISCARD/ : { *(.comment*) *(.gnu*) *(.note*) *(.eh_frame*) *(.text.chainboot*) }
|
/DISCARD/ : { *(.comment*) *(.gnu*) *(.note*) *(.eh_frame*) *(.text.chainboot*) }
|
||||||
}
|
}
|
||||||
|
|
||||||
INCLUDE linker/aarch64-exceptions.ld
|
INCLUDE machine/src/arch/aarch64/linker/aarch64-exceptions.ld
|
|
@ -288,14 +288,14 @@ mod tests {
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn kernel_tables_in_bss() {
|
fn kernel_tables_in_bss() {
|
||||||
extern "Rust" {
|
extern "Rust" {
|
||||||
static __bss_start: UnsafeCell<u64>;
|
static __BSS_START: UnsafeCell<u64>;
|
||||||
static __bss_end_exclusive: UnsafeCell<u64>;
|
static __BSS_END: UnsafeCell<u64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bss_range = unsafe {
|
let bss_range = unsafe {
|
||||||
Range {
|
Range {
|
||||||
start: __bss_start.get(),
|
start: __BSS_START.get(),
|
||||||
end: __bss_end_exclusive.get(),
|
end: __BSS_END.get(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let kernel_tables_addr = &KERNEL_TABLES as *const _ as usize as *mut u64;
|
let kernel_tables_addr = &KERNEL_TABLES as *const _ as usize as *mut u64;
|
||||||
|
|
|
@ -93,26 +93,32 @@ extern "Rust" {
|
||||||
//
|
//
|
||||||
// The inclusive start of the read-only area, aka the address of the
|
// The inclusive start of the read-only area, aka the address of the
|
||||||
// first byte of the area.
|
// first byte of the area.
|
||||||
static __RO_START: UnsafeCell<()>;
|
static __CODE_START: UnsafeCell<()>;
|
||||||
// The exclusive end of the read-only area, aka the address of
|
// The exclusive end of the read-only area, aka the address of
|
||||||
// the first byte _after_ the RO area.
|
// the first byte _after_ the RO area.
|
||||||
static __RO_END: UnsafeCell<()>;
|
static __CODE_END: UnsafeCell<()>;
|
||||||
}
|
|
||||||
|
|
||||||
// Symbols from the linker script.
|
// The inclusive start of the kernel data/BSS area, aka the address of the
|
||||||
// extern "Rust" {
|
// first byte of the area.
|
||||||
// static __code_start: UnsafeCell<()>; // __RO_START
|
static __DATA_START: UnsafeCell<()>;
|
||||||
// static __code_end_exclusive: UnsafeCell<()>; // __RO_END
|
// The exclusive end of the kernel data/BSS area, aka the address of
|
||||||
//
|
// the first byte _after_ the data/BSS area.
|
||||||
// static __data_start: UnsafeCell<()>;
|
static __DATA_END: UnsafeCell<()>;
|
||||||
// static __data_end_exclusive: UnsafeCell<()>;
|
|
||||||
//
|
// The inclusive start of the kernel data/BSS area, aka the address of the
|
||||||
// static __mmio_remap_start: UnsafeCell<()>;
|
// first byte of the area.
|
||||||
// static __mmio_remap_end_exclusive: UnsafeCell<()>;
|
static __STACK_BOTTOM: UnsafeCell<()>;
|
||||||
//
|
// The exclusive end of the kernel data/BSS area, aka the address of
|
||||||
// static __boot_core_stack_start: UnsafeCell<()>;
|
// the first byte _after_ the data/BSS area.
|
||||||
// static __boot_core_stack_end_exclusive: UnsafeCell<()>;
|
static __STACK_TOP: UnsafeCell<()>;
|
||||||
// }
|
|
||||||
|
// The inclusive start of the kernel MMIO remap area, aka the address of the
|
||||||
|
// first byte of the area.
|
||||||
|
static __MMIO_REMAP_START: UnsafeCell<()>;
|
||||||
|
// The exclusive end of the kernel MMIO remap area, aka the address of
|
||||||
|
// the first byte _after_ the MMIO remap area.
|
||||||
|
static __MMIO_REMAP_END: UnsafeCell<()>;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
// Public Definitions
|
// Public Definitions
|
||||||
|
@ -254,7 +260,7 @@ fn boot_end_exclusive() -> usize {
|
||||||
/// - Value is provided by the linker script and must be trusted as-is.
|
/// - Value is provided by the linker script and must be trusted as-is.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn code_start() -> usize {
|
fn code_start() -> usize {
|
||||||
unsafe { __RO_START.get() as usize }
|
unsafe { __CODE_START.get() as usize }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start page address of the code segment.
|
/// Start page address of the code segment.
|
||||||
|
@ -264,7 +270,7 @@ fn code_start() -> usize {
|
||||||
/// - Value is provided by the linker script and must be trusted as-is.
|
/// - Value is provided by the linker script and must be trusted as-is.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn virt_code_start() -> PageAddress<Virtual> {
|
fn virt_code_start() -> PageAddress<Virtual> {
|
||||||
PageAddress::from(unsafe { __RO_START.get() as usize })
|
PageAddress::from(unsafe { __CODE_START.get() as usize })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size of the code segment.
|
/// Size of the code segment.
|
||||||
|
@ -274,7 +280,7 @@ fn virt_code_start() -> PageAddress<Virtual> {
|
||||||
/// - Value is provided by the linker script and must be trusted as-is.
|
/// - Value is provided by the linker script and must be trusted as-is.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn code_size() -> usize {
|
fn code_size() -> usize {
|
||||||
unsafe { (__RO_END.get() as usize) - (__RO_START.get() as usize) }
|
unsafe { (__CODE_END.get() as usize) - (__CODE_START.get() as usize) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exclusive end page address of the code segment.
|
/// Exclusive end page address of the code segment.
|
||||||
|
@ -289,7 +295,7 @@ fn code_size() -> usize {
|
||||||
/// Start page address of the data segment.
|
/// Start page address of the data segment.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn virt_data_start() -> PageAddress<Virtual> {
|
fn virt_data_start() -> PageAddress<Virtual> {
|
||||||
PageAddress::from(unsafe { __data_start.get() as usize })
|
PageAddress::from(unsafe { __DATA_START.get() as usize })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size of the data segment.
|
/// Size of the data segment.
|
||||||
|
@ -299,7 +305,7 @@ fn virt_data_start() -> PageAddress<Virtual> {
|
||||||
/// - Value is provided by the linker script and must be trusted as-is.
|
/// - Value is provided by the linker script and must be trusted as-is.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn data_size() -> usize {
|
fn data_size() -> usize {
|
||||||
unsafe { (__data_end_exclusive.get() as usize) - (__data_start.get() as usize) }
|
unsafe { (__DATA_END.get() as usize) - (__DATA_START.get() as usize) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start page address of the MMIO remap reservation.
|
/// Start page address of the MMIO remap reservation.
|
||||||
|
@ -309,7 +315,7 @@ fn data_size() -> usize {
|
||||||
/// - Value is provided by the linker script and must be trusted as-is.
|
/// - Value is provided by the linker script and must be trusted as-is.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn virt_mmio_remap_start() -> PageAddress<Virtual> {
|
fn virt_mmio_remap_start() -> PageAddress<Virtual> {
|
||||||
PageAddress::from(unsafe { __mmio_remap_start.get() as usize })
|
PageAddress::from(unsafe { __MMIO_REMAP_START.get() as usize })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size of the MMIO remap reservation.
|
/// Size of the MMIO remap reservation.
|
||||||
|
@ -319,21 +325,19 @@ fn virt_mmio_remap_start() -> PageAddress<Virtual> {
|
||||||
/// - Value is provided by the linker script and must be trusted as-is.
|
/// - Value is provided by the linker script and must be trusted as-is.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mmio_remap_size() -> usize {
|
fn mmio_remap_size() -> usize {
|
||||||
unsafe { (__mmio_remap_end_exclusive.get() as usize) - (__mmio_remap_start.get() as usize) }
|
unsafe { (__MMIO_REMAP_END.get() as usize) - (__MMIO_REMAP_START.get() as usize) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Start page address of the boot core's stack.
|
/// Start page address of the boot core's stack.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn virt_boot_core_stack_start() -> PageAddress<Virtual> {
|
fn virt_boot_core_stack_start() -> PageAddress<Virtual> {
|
||||||
PageAddress::from(unsafe { __boot_core_stack_start.get() as usize })
|
PageAddress::from(unsafe { __STACK_BOTTOM.get() as usize })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size of the boot core's stack.
|
/// Size of the boot core's stack.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn boot_core_stack_size() -> usize {
|
fn boot_core_stack_size() -> usize {
|
||||||
unsafe {
|
unsafe { (__STACK_TOP.get() as usize) - (__STACK_BOTTOM.get() as usize) }
|
||||||
(__boot_core_stack_end_exclusive.get() as usize) - (__boot_core_stack_start.get() as usize)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
const LINKER_SCRIPT: &str = "linker/aarch64.ld";
|
/// This build script is used to link main kernel binary.
|
||||||
const LINKER_SCRIPT_AUX: &str = "linker/aarch64-exceptions.ld";
|
|
||||||
|
const LINKER_SCRIPT: &str = "machine/src/platform/raspberrypi/linker/kernel.ld";
|
||||||
|
const LINKER_SCRIPT_AUX: &str = "machine/src/arch/aarch64/linker/aarch64-exceptions.ld";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed={}", LINKER_SCRIPT);
|
println!("cargo:rerun-if-changed={}", LINKER_SCRIPT);
|
||||||
|
|
Loading…
Reference in New Issue