Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Linux header for aarch64 #221

Merged
merged 4 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions configs/platforms/aarch64-qemu-virt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ phys-memory-base = 0x4000_0000 # uint
# Size of the whole physical memory. (128M)
phys-memory-size = 0x800_0000 # uint
# Base physical address of the kernel image.
kernel-base-paddr = 0x4008_0000 # uint
kernel-base-paddr = 0x4020_0000 # uint
# Base virtual address of the kernel image.
kernel-base-vaddr = "0xffff_0000_4008_0000" # uint
kernel-base-vaddr = "0xffff_0000_4020_0000" # uint
# Linear mapping offset, for quick conversions between physical and virtual
# addresses.
phys-virt-offset = "0xffff_0000_0000_0000" # uint
Expand Down
16 changes: 14 additions & 2 deletions doc/platform_phytium_pi.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,23 @@ ostool run uboot

![select](./figures/phytium_select_dtb.png)

We can ignore select dtb step by pressing `enter` directly. ArceOS dose not support dtb yet.
`dtb` path is `tools/phytium_pi/phytiumpi_firefly.dtb`

Then the cmdline will wait for you to put board power on or reset.

You can modify config in `.project.toml` to change the default behavior.
`Ctrl+C` to exit.

Modify config in `.project.toml` to change platform for phytium pi.

Find `shell=[[ ... "make A=examples/helloworld ARCH=aarch64" ]]`, add `PLATFORM` like:

`"make A=examples/helloworld PLATFORM=aarch64-phytium-pi"`.

Find `elf = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"` and change to:

`elf = "examples/helloworld/helloworld_aarch64-phytium-pi.elf"`.

Then run `ostool run uboot` again. When see `等待 U-Boot 启动...` , put board power on or reset.

If everything goes well, you will see the following output:

Expand Down
161 changes: 100 additions & 61 deletions modules/axhal/src/platform/aarch64_common/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ static mut BOOT_PT_L0: [A64PTE; 512] = [A64PTE::empty(); 512];
#[unsafe(link_section = ".data.boot_page_table")]
static mut BOOT_PT_L1: [A64PTE; 512] = [A64PTE::empty(); 512];

const FLAG_LE: usize = 0b0;
const FLAG_PAGE_SIZE_4K: usize = 0b10;
const FLAG_ANY_MEM: usize = 0b1000;

unsafe fn switch_to_el1() {
SPSel.write(SPSel::SP::ELx);
SP_EL0.set(0);
Expand Down Expand Up @@ -47,11 +51,13 @@ unsafe fn switch_to_el1() {
+ SPSR_EL2::I::Masked
+ SPSR_EL2::F::Masked,
);
core::arch::asm!(
"
mov x8, sp
msr sp_el1, x8"
);
unsafe {
core::arch::asm!(
"
ZR233 marked this conversation as resolved.
Show resolved Hide resolved
mov x8, sp
msr sp_el1, x8"
)
};
ELR_EL2.set(LR.get());
asm::eret();
}
Expand Down Expand Up @@ -100,44 +106,75 @@ unsafe fn init_boot_page_table() {
crate::platform::mem::init_boot_page_table(addr_of_mut!(BOOT_PT_L0), addr_of_mut!(BOOT_PT_L1));
}

/// The earliest entry point for the primary CPU.
/// Kernel entry point with Linux image header.
///
/// Some bootloaders require this header to be present at the beginning of the
/// kernel image.
///
/// Documentation: <https://docs.kernel.org/arch/arm64/booting.html>
#[naked]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".text.boot")]
unsafe extern "C" fn _start() -> ! {
// PC = 0x8_0000
// X0 = dtb
core::arch::naked_asm!("
mrs x19, mpidr_el1
and x19, x19, #0xffffff // get current CPU id
mov x20, x0 // save DTB pointer

adrp x8, {boot_stack} // setup boot stack
add x8, x8, {boot_stack_size}
mov sp, x8

bl {switch_to_el1} // switch to EL1
bl {enable_fp} // enable fp/neon
bl {init_boot_page_table}
bl {init_mmu} // setup MMU

mov x8, {phys_virt_offset} // set SP to the high address
add sp, sp, x8

mov x0, x19 // call rust_entry(cpu_id, dtb)
mov x1, x20
ldr x8, ={entry}
blr x8
b .",
switch_to_el1 = sym switch_to_el1,
init_boot_page_table = sym init_boot_page_table,
init_mmu = sym init_mmu,
enable_fp = sym enable_fp,
boot_stack = sym BOOT_STACK,
boot_stack_size = const TASK_STACK_SIZE,
phys_virt_offset = const PHYS_VIRT_OFFSET,
entry = sym crate::platform::rust_entry,
)
unsafe {
// PC = bootloader load address
// X0 = dtb
core::arch::naked_asm!("
add x13, x18, #0x16 // 'MZ' magic
b {entry} // Branch to kernel start, magic

.quad 0 // Image load offset from start of RAM, little-endian
.quad _ekernel - _start // Effective size of kernel image, little-endian
.quad {flags} // Kernel flags, little-endian
.quad 0 // reserved
.quad 0 // reserved
.quad 0 // reserved
.ascii \"ARM\\x64\" // Magic number
.long 0 // reserved (used for PE COFF offset)",
flags = const FLAG_LE | FLAG_PAGE_SIZE_4K | FLAG_ANY_MEM,
entry = sym _start_primary,
)
}
}

/// The earliest entry point for the primary CPU.
#[naked]
#[unsafe(link_section = ".text.boot")]
unsafe extern "C" fn _start_primary() -> ! {
ZR233 marked this conversation as resolved.
Show resolved Hide resolved
unsafe {
// X0 = dtb
core::arch::naked_asm!("
ZR233 marked this conversation as resolved.
Show resolved Hide resolved
mrs x19, mpidr_el1
and x19, x19, #0xffffff // get current CPU id
mov x20, x0 // save DTB pointer

adrp x8, {boot_stack} // setup boot stack
add x8, x8, {boot_stack_size}
mov sp, x8

bl {switch_to_el1} // switch to EL1
bl {enable_fp} // enable fp/neon
bl {init_boot_page_table}
bl {init_mmu} // setup MMU

mov x8, {phys_virt_offset} // set SP to the high address
add sp, sp, x8

mov x0, x19 // call rust_entry(cpu_id, dtb)
mov x1, x20
ldr x8, ={entry}
blr x8
b .",
switch_to_el1 = sym switch_to_el1,
init_boot_page_table = sym init_boot_page_table,
init_mmu = sym init_mmu,
enable_fp = sym enable_fp,
boot_stack = sym BOOT_STACK,
boot_stack_size = const TASK_STACK_SIZE,
phys_virt_offset = const PHYS_VIRT_OFFSET,
entry = sym crate::platform::rust_entry,
)
}
}

/// The earliest entry point for the secondary CPUs.
Expand All @@ -146,26 +183,28 @@ unsafe extern "C" fn _start() -> ! {
#[unsafe(no_mangle)]
#[unsafe(link_section = ".text.boot")]
unsafe extern "C" fn _start_secondary() -> ! {
core::arch::naked_asm!("
mrs x19, mpidr_el1
and x19, x19, #0xffffff // get current CPU id

mov sp, x0
bl {switch_to_el1}
bl {init_mmu}
bl {enable_fp}

mov x8, {phys_virt_offset} // set SP to the high address
add sp, sp, x8

mov x0, x19 // call rust_entry_secondary(cpu_id)
ldr x8, ={entry}
blr x8
b .",
switch_to_el1 = sym switch_to_el1,
init_mmu = sym init_mmu,
enable_fp = sym enable_fp,
phys_virt_offset = const PHYS_VIRT_OFFSET,
entry = sym crate::platform::rust_entry_secondary,
)
unsafe {
core::arch::naked_asm!("
mrs x19, mpidr_el1
and x19, x19, #0xffffff // get current CPU id

mov sp, x0
bl {switch_to_el1}
bl {init_mmu}
bl {enable_fp}

mov x8, {phys_virt_offset} // set SP to the high address
add sp, sp, x8

mov x0, x19 // call rust_entry_secondary(cpu_id)
ldr x8, ={entry}
blr x8
b .",
switch_to_el1 = sym switch_to_el1,
init_mmu = sym init_mmu,
enable_fp = sym enable_fp,
phys_virt_offset = const PHYS_VIRT_OFFSET,
entry = sym crate::platform::rust_entry_secondary,
)
}
}
Loading