feat: Update linker script

* Add MMIO remap region
* Move script to appropriate place
This commit is contained in:
Berkus Decker 2023-08-10 13:22:44 +03:00 committed by Berkus Decker
parent e8a587ea7b
commit 134d7c530f
7 changed files with 89 additions and 52 deletions

View File

@ -1,5 +1,7 @@
const LINKER_SCRIPT: &str = "linker/aarch64.ld";
const LINKER_SCRIPT_AUX: &str = "linker/aarch64-exceptions.ld";
/// This build script is used to create lib tests.
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() {
println!("cargo:rerun-if-changed={}", LINKER_SCRIPT);

View File

@ -65,10 +65,10 @@ pub unsafe extern "C" fn _boot_cores() -> ! {
extern "Rust" {
// Stack top
// Stack placed before first executable instruction
static __STACK_START: UnsafeCell<()>;
static __STACK_TOP: UnsafeCell<()>;
}
// 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();
@ -122,12 +122,12 @@ fn shared_setup_and_enter_pre() {
fn shared_setup_and_enter_post() -> ! {
extern "Rust" {
// Stack top
static __STACK_START: UnsafeCell<()>;
static __STACK_TOP: UnsafeCell<()>;
}
// Set up SP_EL1 (stack pointer), which will be used by EL1 once
// we "return" to it.
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

View File

@ -5,11 +5,14 @@
* 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;
ENTRY(__phys_load_addr);
PAGE_SIZE = 65536;
/* Flags:
* 4 == R
* 5 == RX
@ -26,13 +29,26 @@ PHDRS
}
/* 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.
*/
SECTIONS
{
__STACK_START = __phys_load_addr; /* Stack grows from here towards 0x0. */
. = __phys_load_addr; /* AArch64 boot address is 0x80000, 4K-aligned */
. = __phys_mem_start;
/***********************************************************************************************
* 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
@ -43,19 +59,19 @@ SECTIONS
/*******************************************************************************************
* Boot Code + Boot Data
*******************************************************************************************/
__BOOT_START = .;
KEEP(*(.text.main.entry))
*(.text.boot)
*(.data.boot)
. = ALIGN(PAGE_SIZE); /* Here the boot code ends */
__BOOT_END = .; // __BOOT_END must be PAGE_SIZE aligned
. = ALIGN(PAGE_SIZE);
__BOOT_END = .; /* Here the boot code ends */
ASSERT((__BOOT_END & PAGE_MASK) == 0, "End of boot code is not page aligned")
/*******************************************************************************************
* Regular Kernel Code
*******************************************************************************************/
__RO_START = .;
__CODE_START = .;
*(.text*)
} :segment_code
@ -72,7 +88,8 @@ SECTIONS
*(.rodata*)
FILL(0x00)
. = 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
/***********************************************************************************************
@ -81,7 +98,8 @@ SECTIONS
.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*)
FILL(0x00)
} :segment_data
@ -96,6 +114,17 @@ SECTIONS
__BSS_SIZE_U64S = (__BSS_END - __BSS_START) / 8;
} :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
***********************************************************************************************/
@ -106,4 +135,4 @@ SECTIONS
/DISCARD/ : { *(.comment*) *(.gnu*) *(.note*) *(.eh_frame*) *(.text.chainboot*) }
}
INCLUDE linker/aarch64-exceptions.ld
INCLUDE machine/src/arch/aarch64/linker/aarch64-exceptions.ld

View File

@ -288,14 +288,14 @@ mod tests {
#[test_case]
fn kernel_tables_in_bss() {
extern "Rust" {
static __bss_start: UnsafeCell<u64>;
static __bss_end_exclusive: UnsafeCell<u64>;
static __BSS_START: UnsafeCell<u64>;
static __BSS_END: UnsafeCell<u64>;
}
let bss_range = unsafe {
Range {
start: __bss_start.get(),
end: __bss_end_exclusive.get(),
start: __BSS_START.get(),
end: __BSS_END.get(),
}
};
let kernel_tables_addr = &KERNEL_TABLES as *const _ as usize as *mut u64;

View File

@ -93,26 +93,32 @@ extern "Rust" {
//
// The inclusive start of the read-only area, aka the address of the
// 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 first byte _after_ the RO area.
static __RO_END: UnsafeCell<()>;
}
static __CODE_END: UnsafeCell<()>;
// Symbols from the linker script.
// extern "Rust" {
// static __code_start: UnsafeCell<()>; // __RO_START
// static __code_end_exclusive: UnsafeCell<()>; // __RO_END
//
// static __data_start: UnsafeCell<()>;
// static __data_end_exclusive: UnsafeCell<()>;
//
// static __mmio_remap_start: UnsafeCell<()>;
// static __mmio_remap_end_exclusive: UnsafeCell<()>;
//
// static __boot_core_stack_start: UnsafeCell<()>;
// static __boot_core_stack_end_exclusive: UnsafeCell<()>;
// }
// The inclusive start of the kernel data/BSS area, aka the address of the
// first byte of the area.
static __DATA_START: UnsafeCell<()>;
// The exclusive end of the kernel data/BSS area, aka the address of
// the first byte _after_ the data/BSS area.
static __DATA_END: UnsafeCell<()>;
// The inclusive start of the kernel data/BSS area, aka the address of the
// first byte of the area.
static __STACK_BOTTOM: UnsafeCell<()>;
// The exclusive end of the kernel data/BSS area, aka the address of
// the first byte _after_ the data/BSS area.
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
@ -254,7 +260,7 @@ fn boot_end_exclusive() -> usize {
/// - Value is provided by the linker script and must be trusted as-is.
#[inline(always)]
fn code_start() -> usize {
unsafe { __RO_START.get() as usize }
unsafe { __CODE_START.get() as usize }
}
/// 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.
#[inline(always)]
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.
@ -274,7 +280,7 @@ fn virt_code_start() -> PageAddress<Virtual> {
/// - Value is provided by the linker script and must be trusted as-is.
#[inline(always)]
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.
@ -289,7 +295,7 @@ fn code_size() -> usize {
/// Start page address of the data segment.
#[inline(always)]
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.
@ -299,7 +305,7 @@ fn virt_data_start() -> PageAddress<Virtual> {
/// - Value is provided by the linker script and must be trusted as-is.
#[inline(always)]
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.
@ -309,7 +315,7 @@ fn data_size() -> usize {
/// - Value is provided by the linker script and must be trusted as-is.
#[inline(always)]
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.
@ -319,21 +325,19 @@ fn virt_mmio_remap_start() -> PageAddress<Virtual> {
/// - Value is provided by the linker script and must be trusted as-is.
#[inline(always)]
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.
#[inline(always)]
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.
#[inline(always)]
fn boot_core_stack_size() -> usize {
unsafe {
(__boot_core_stack_end_exclusive.get() as usize) - (__boot_core_stack_start.get() as usize)
}
unsafe { (__STACK_TOP.get() as usize) - (__STACK_BOTTOM.get() as usize) }
}
//--------------------------------------------------------------------------------------------------

View File

@ -1,5 +1,7 @@
const LINKER_SCRIPT: &str = "linker/aarch64.ld";
const LINKER_SCRIPT_AUX: &str = "linker/aarch64-exceptions.ld";
/// This build script is used to link main kernel binary.
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() {
println!("cargo:rerun-if-changed={}", LINKER_SCRIPT);