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"; /// 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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -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);