Skip to content

Commit

Permalink
add linker scripts and head.S
Browse files Browse the repository at this point in the history
  • Loading branch information
lixinyu committed Dec 2, 2024
1 parent 33d8cca commit 6e5779a
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 6 deletions.
3 changes: 2 additions & 1 deletion kernel/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ unstable-options = true

[target.riscv64imac-unknown-none-elf]
rustflags = [
"-Ztls-model=local-exec"
"-Ztls-model=local-exec",
"-Clink-arg=-Tkernel/src/arch/riscv/linker.lds_pp"
]

[env]
Expand Down
5 changes: 0 additions & 5 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ name = "rel4_kernel"
version = "0.1.0"
edition = "2021"

[lib]
name = "rustlib"
path = "src/lib.rs"
crate-type = ["staticlib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down
20 changes: 20 additions & 0 deletions kernel/src/arch/riscv/head.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

.section .boot.text, "ax"
.global _start
.extern init_kernel
.extern kernel_stack_alloc
.extern __global_pointer$
.extern restore_user_context

_start:
fence.i
.option push
.option norelax
1:auipc gp, %pcrel_hi(__global_pointer$)
addi gp, gp, %pcrel_lo(1b)
.option pop
la sp, (kernel_stack_alloc + (1ul << (12)))
csrw sscratch, x0
jal init_kernel
la ra, restore_user_context
jr ra
318 changes: 318 additions & 0 deletions kernel/src/arch/riscv/linker.lds_pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
* Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com>
* Copyright 2021, HENSOLDT Cyber
* Copyright 2023, DornerWorks
*
* SPDX-License-Identifier: GPL-2.0-only
*/
OUTPUT_ARCH(riscv)
ENTRY(_start)
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/

/*
* Copyright 2014, General Dynamics C4 Systems
*
* SPDX-License-Identifier: BSD-2-Clause
*/

/* Compile-time configuration parameters. Might be set by the build system. */


/* disabled: CONFIG_ARCH_AARCH32 */
/* disabled: CONFIG_ARCH_AARCH64 */
/* disabled: CONFIG_ARCH_ARM_HYP */
/* disabled: CONFIG_ARCH_RISCV32 */
/* disabled: CONFIG_ARCH_X86_64 */
/* disabled: CONFIG_ARCH_IA32 */
/* disabled: CONFIG_ARM_CORTEX_A7 */
/* disabled: CONFIG_ARM_CORTEX_A8 */
/* disabled: CONFIG_ARM_CORTEX_A9 */
/* disabled: CONFIG_ARM_CORTEX_A15 */
/* disabled: CONFIG_ARM_CORTEX_A35 */
/* disabled: CONFIG_ARM_CORTEX_A53 */
/* disabled: CONFIG_ARM_CORTEX_A55 */
/* disabled: CONFIG_ARM_CORTEX_A57 */
/* disabled: CONFIG_ARM_CORTEX_A72 */
/* disabled: CONFIG_ARCH_ARM_V7A */
/* disabled: CONFIG_ARCH_ARM_V7VE */
/* disabled: CONFIG_ARCH_ARM_V8A */
/* disabled: CONFIG_AARCH64_SERROR_IGNORE */
/* disabled: CONFIG_KERNEL_MCS */
/* disabled: CONFIG_RISCV_EXT_F */
/* disabled: CONFIG_RISCV_EXT_D */
/* disabled: CONFIG_EXPORT_PCNT_USER */
/* disabled: CONFIG_EXPORT_VCNT_USER */
/* disabled: CONFIG_EXPORT_PTMR_USER */
/* disabled: CONFIG_EXPORT_VTMR_USER */
/* disabled: CONFIG_HAVE_FPU */
/* disabled: CONFIG_EXCEPTION_FASTPATH */
/* disabled: CONFIG_SIGNAL_FASTPATH */
/* disabled: CONFIG_ENABLE_SMP_SUPPORT */
/* disabled: CONFIG_VERIFICATION_BUILD */
/* disabled: CONFIG_BINARY_VERIFICATION_BUILD */
/* disabled: CONFIG_HARDWARE_DEBUG_API */
/* disabled: CONFIG_KERNEL_INVOCATION_REPORT_ERROR_IPC */
/* disabled: CONFIG_BENCHMARK_GENERIC */
/* disabled: CONFIG_BENCHMARK_TRACK_KERNEL_ENTRIES */
/* disabled: CONFIG_BENCHMARK_TRACEPOINTS */
/* disabled: CONFIG_BENCHMARK_TRACK_UTILISATION */
/* disabled: CONFIG_ENABLE_BENCHMARKS */
/* disabled: CONFIG_KERNEL_LOG_BUFFER */
/* disabled: CONFIG_KERNEL_OPT_LEVEL_OS */
/* disabled: CONFIG_KERNEL_OPT_LEVEL_O0 */
/* disabled: CONFIG_KERNEL_OPT_LEVEL_O1 */
/* disabled: CONFIG_KERNEL_OPT_LEVEL_O3 */
/* disabled: CONFIG_KERNEL_FWHOLE_PROGRAM */
/* disabled: CONFIG_DANGEROUS_CODE_INJECTION */
/* disabled: CONFIG_DEBUG_DISABLE_PREFETCHERS */
/* disabled: CONFIG_SET_TLS_BASE_SELF */
/* disabled: CONFIG_CLZ_32 */
/* disabled: CONFIG_CTZ_32 */
/* disabled: CONFIG_CLZ_NO_BUILTIN */
/* disabled: CONFIG_CTZ_NO_BUILTIN */
/* disabled: CONFIG_LINUX_APP_SUPPORT */
/* Set ENABLE_SMP_SUPPORT for kernel source files */
/*
* Copyright 2014, General Dynamics C4 Systems
*
* SPDX-License-Identifier: GPL-2.0-only
*/

/* Each architecture defines a set of constants in #defines. These
* constants describe the memory regions of the kernel's portion of the
* address space including the physical memory window, the kernel ELF
* region, and the device region.
*
* - USER_TOP: The first address after the end of user memory
*
* - PADDR_BASE: The first physical address mapped in the kernel's
* physical memory window.
* - PPTR_BASE: The first virtual address of the kernel's physical
* memory window.
* - PPTR_TOP: The first virtual address after the end of the kernel's
* physical memory window.
*
* - KERNEL_ELF_PADDR_BASE: The first physical address used to map the
* initial kernel image. The kernel ELF is mapped contiguously
* starting at this address.
* - KERNEL_ELF_BASE: The first virtual address used to map the initial
* kernel image.
*
* - KDEV_BASE: The first virtual address used to map devices.
*/
/* The offset from a physical address to a virtual address in the
* physical memory window. */
/* The last address in the physical memory region mapped into the
* physical memory window */
/* The kernel base offset is a way to translate the kernel image segment
* from virtual to physical. This translation must be a single offset
* for for the entire segment (i.e. the kernel image must be contiguous
* both virtually and physically) */
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/

/*
* Copyright 2014, General Dynamics C4 Systems
*
* SPDX-License-Identifier: GPL-2.0-only
*/

/* Provide a helper macro to define integer constants that are not of the
* default type 'int', but 'unsigned long [long]'. When such constants are
* shared between assembly and C code, some assemblers will fail because they
* don't support C-style integer suffixes like 'ul'. Using a macro works around
* this, as the suffix is only applied when the C compiler is used and dropped
* when the assembler runs.
*/
/* Time constants are defined to use the 'unsigned long long'. Rationale is,
* that the C rules define the calculation result is determined by largest type
* involved. Enforcing the largest possible type C provides avoids pitfalls with
* 32-bit overflows when values are getting quite large. Keep in mind that even
* 2^32 milli-seconds roll over within 50 days, which is an uptime that embedded
* systems will reach easily and it resembles not even two months in a calendar
* calculation. In addition, using the largest integer type C currently defines
* enforces that all calculations results need a cast back to a 32-bit type
* explicitly. This might feel annoying, but practically it makes code more
* robust and enforces thinking about potential overflows.
* Note that at this stage of the includes, we do not have defined the type
* uint64_t yet, so we can't use any definitions around it, but have to stick to
* plain C types. Neither moving the time constant definitions behind the
* uint64_t type definitions nor including the header with the uint64_t
* definitions here is currently a feasible option.
*/
/*
* The top half of the address space is reserved for the kernel. This means that 256 top level
* entries are for the user, and 256 are for the kernel. This will be further split into the
* 'regular' kernel window, which contains mappings to physical memory, a small (1GiB) higher
* kernel image window that we use for running the actual kernel from and a top 1GiB window for
* kernel device mappings. This means that between PPTR_BASE and
* KERNEL_ELF_BASE there are 254 entries remaining, which represents how much physical memory
* can be used.
*
* Almost all of the top 256 kernel entries will contain 1GiB page mappings. The only 2 entries
* that contain a 2nd level PageTable consisting of 2MiB page entries is the entry
* for the 1GiB Kernel ELF region and the 1GiB region corresponding to the physical memory
* of the kernel ELF in the kernel window. The same 2nd level PageTable is used and so both
* entries refer to the same 1GiB of physical memory.
* This means that the 1GiB kernel ELF mapping will correspond to physical memory with a 1GiB
* alignment.
*
* +-----------------------------+ 2^64
* | Kernel Devices |
* -> +-------------------KDEV_BASE-+ 2^64 - 1GiB
* | | Kernel ELF |
* ----| +-------------KERNEL_ELF_BASE-+ --+ 2^64 - 2GiB + (KERNEL_ELF_PADDR_BASE % 1GiB)
* | | | |
* | -> +-----------------------------+ --+ 2^64 - 2GiB = (KERNEL_ELF_BASE % 1GiB)
* Shared 1GiB| | | |
* table entry| | PSpace | |
* | | (direct kernel mappings) | +----+
* ------>| | | |
* | | | |
* +-------------------PPTR_BASE-+ --+ 2^64 - 2^b
* | | | +-------------------------+
* | | | | |
* | | | | |
* | Invalid | | | |
* | | | | not |
* | | | | kernel |
* | | | | addressable |
* +--------------------USER_TOP-+ 2^c | | |
* | | | | |
* | | | | |
* | | | +- --------------------------+ PADDR_TOP =
* | | | | | | PPTR_TOP - PPTR_BASE
* | | | | | |
* | | | | | |
* | User | | | | |
* | | | | | |
* | | +------+ +-------------------------+ KDEV_BASE - KERNEL_ELF_BASE + PADDR_LOAD
* | | kernel | | Kernel ELF |
* | | addressable | +-------------------------+ KERNEL_ELF_PADDR_BASE
* | | | | |
* | | | | |
* +-----------------------------+ 0 +- +-------------------------+ 0 PADDR_BASE
*
* virtual address space physical address space
*
*
* c = one less than number of bits the page tables can translate
* = sign extension bit for canonical addresses
* (= 47 on x64, 38 on RISCV64 sv39, 47 on RISCV64 sv48)
* b = The number of bits used by kernel mapping.
* = 38 (half of the 1 level page table) on RISCV64 sc39
* = 39 (entire second level page table) on aarch64 / X64 / sv48
*/
/* last accessible virtual address in user space */
/* The first physical address to map into the kernel's physical memory
* window */
/* The base address in virtual memory to use for the 1:1 physical memory
* mapping */
/* Top of the physical memory window */
/* The physical memory address to use for mapping the kernel ELF */
/* This represents the physical address that the kernel image will be linked to. This needs to
* be on a 1gb boundary as we currently require being able to creating a mapping to this address
* as the largest frame size */
/* For use by the linker (only integer constants allowed) */
/* The base address in virtual memory to use for the kernel ELF mapping */
/* For use by the linker (only integer constants allowed) */
/* The base address in virtual memory to use for the kernel device
* mapping region. These are mapped in the kernel page table. */
/* Place the kernel log buffer at the end of the kernel device page table */
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/

/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/
/*
* This file is autogenerated by <kernel>/tools/hardware/outputs/c_header.py.
*/

KERNEL_OFFSET = (0xFFFFFFFF80000000 + ((0x80000000 + 0x4000000) & ((1 << (30)) - 1))) - (0x80000000 + 0x4000000);
SECTIONS
{
. = (0xFFFFFFFF80000000 + ((0x80000000 + 0x4000000) & ((1 << (30)) - 1)));
.boot.text . : AT(ADDR(.boot.text) - KERNEL_OFFSET)
{
*(.boot.text)
}
.boot.rodata . : AT(ADDR(.boot.rodata) - KERNEL_OFFSET)
{
*(.boot.rodata)
}
.boot.data . : AT(ADDR(.boot.data) - KERNEL_OFFSET)
{
*(.boot.data)
}
.boot.bss . : AT(ADDR(.boot.bss) - KERNEL_OFFSET)
{
*(.boot.bss)
}
. = ALIGN(4K);
ki_boot_end = .;
.text . : AT(ADDR(.text) - KERNEL_OFFSET)
{
. = ALIGN(4K);
/* Standard kernel */
*(.text)
}
/* Start of data section */
_sdata = .;
.small : {
/* Small data that should be accessed relative to gp. ld has trouble
with the relaxation if they are not in a single section. */
__global_pointer$ = . + 0x800;
*(.srodata*)
*(.sdata*)
*(.sbss)
}
.rodata . : AT(ADDR(.rodata) - KERNEL_OFFSET)
{
*(.rodata)
*(.rodata.*)
}
.data . : AT(ADDR(.data) - KERNEL_OFFSET)
{
*(.data)
}
/* The kernel's idle thread section contains no code or data. */
._idle_thread . (NOLOAD): AT(ADDR(._idle_thread) - KERNEL_OFFSET)
{
*(._idle_thread)
}
.bss . (NOLOAD): AT(ADDR(.bss) - KERNEL_OFFSET)
{
*(.bss)
*(COMMON) /* fallback in case '-fno-common' is not used */
/* 4k breakpoint stack */
_breakpoint_stack_bottom = .;
. = . + 4K;
_breakpoint_stack_top = .;
/* large data such as the globals frame and global PD */
*(.bss.aligned)
}
. = ALIGN(4K);
. = . + 8K;
. = ALIGN(4K);
.page_table :
{
. = ALIGN(4K);
*(.page_table.aligned)
}
. = ALIGN(4K);
ki_end = .;
}
1 change: 1 addition & 0 deletions kernel/src/arch/riscv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub use platform::{init_cpu, init_freemem};
pub use exception::handleUnknownSyscall;

core::arch::global_asm!(include_str!("restore_fp.S"));
core::arch::global_asm!(include_str!("head.S"));

pub fn read_stval() -> usize {
let temp: usize;
Expand Down
13 changes: 13 additions & 0 deletions kernel/src/lib.rs → kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,16 @@ pub extern "C" fn strnlen(str: *const u8, _max_len: usize) -> usize {
ans
}
}

#[no_mangle]
#[link_section = ".boot.text"]
pub fn init_kernel(
ui_p_reg_start: usize,
ui_p_reg_end: usize,
pv_offset: usize,
v_entry: usize,
dtb_addr_p: usize,
dtb_size: usize
) -> ! {

}

0 comments on commit 6e5779a

Please sign in to comment.