Skip to content

Commit d9bbf6c

Browse files
authored
Add Linux header for aarch64 (arceos-org#221)
* add linux header * add phytium dtb info in doc.
1 parent 0778fe3 commit d9bbf6c

File tree

3 files changed

+116
-65
lines changed

3 files changed

+116
-65
lines changed

configs/platforms/aarch64-qemu-virt.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ phys-memory-base = 0x4000_0000 # uint
1515
# Size of the whole physical memory. (128M)
1616
phys-memory-size = 0x800_0000 # uint
1717
# Base physical address of the kernel image.
18-
kernel-base-paddr = 0x4008_0000 # uint
18+
kernel-base-paddr = 0x4020_0000 # uint
1919
# Base virtual address of the kernel image.
20-
kernel-base-vaddr = "0xffff_0000_4008_0000" # uint
20+
kernel-base-vaddr = "0xffff_0000_4020_0000" # uint
2121
# Linear mapping offset, for quick conversions between physical and virtual
2222
# addresses.
2323
phys-virt-offset = "0xffff_0000_0000_0000" # uint

doc/platform_phytium_pi.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,23 @@ ostool run uboot
2929

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

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

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

36-
You can modify config in `.project.toml` to change the default behavior.
36+
`Ctrl+C` to exit.
37+
38+
Modify config in `.project.toml` to change platform for phytium pi.
39+
40+
Find `shell=[[ ... "make A=examples/helloworld ARCH=aarch64" ]]`, add `PLATFORM` like:
41+
42+
`"make A=examples/helloworld PLATFORM=aarch64-phytium-pi"`.
43+
44+
Find `elf = "examples/helloworld/helloworld_aarch64-qemu-virt.elf"` and change to:
45+
46+
`elf = "examples/helloworld/helloworld_aarch64-phytium-pi.elf"`.
47+
48+
Then run `ostool run uboot` again. When see `等待 U-Boot 启动...` , put board power on or reset.
3749

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

modules/axhal/src/platform/aarch64_common/boot.rs

Lines changed: 100 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ static mut BOOT_PT_L0: [A64PTE; 512] = [A64PTE::empty(); 512];
1414
#[unsafe(link_section = ".data.boot_page_table")]
1515
static mut BOOT_PT_L1: [A64PTE; 512] = [A64PTE::empty(); 512];
1616

17+
const FLAG_LE: usize = 0b0;
18+
const FLAG_PAGE_SIZE_4K: usize = 0b10;
19+
const FLAG_ANY_MEM: usize = 0b1000;
20+
1721
unsafe fn switch_to_el1() {
1822
SPSel.write(SPSel::SP::ELx);
1923
SP_EL0.set(0);
@@ -47,11 +51,13 @@ unsafe fn switch_to_el1() {
4751
+ SPSR_EL2::I::Masked
4852
+ SPSR_EL2::F::Masked,
4953
);
50-
core::arch::asm!(
51-
"
52-
mov x8, sp
53-
msr sp_el1, x8"
54-
);
54+
unsafe {
55+
core::arch::asm!(
56+
"
57+
mov x8, sp
58+
msr sp_el1, x8"
59+
)
60+
};
5561
ELR_EL2.set(LR.get());
5662
asm::eret();
5763
}
@@ -100,44 +106,75 @@ unsafe fn init_boot_page_table() {
100106
crate::platform::mem::init_boot_page_table(addr_of_mut!(BOOT_PT_L0), addr_of_mut!(BOOT_PT_L1));
101107
}
102108

103-
/// The earliest entry point for the primary CPU.
109+
/// Kernel entry point with Linux image header.
110+
///
111+
/// Some bootloaders require this header to be present at the beginning of the
112+
/// kernel image.
113+
///
114+
/// Documentation: <https://docs.kernel.org/arch/arm64/booting.html>
104115
#[naked]
105116
#[unsafe(no_mangle)]
106117
#[unsafe(link_section = ".text.boot")]
107118
unsafe extern "C" fn _start() -> ! {
108-
// PC = 0x8_0000
109-
// X0 = dtb
110-
core::arch::naked_asm!("
111-
mrs x19, mpidr_el1
112-
and x19, x19, #0xffffff // get current CPU id
113-
mov x20, x0 // save DTB pointer
114-
115-
adrp x8, {boot_stack} // setup boot stack
116-
add x8, x8, {boot_stack_size}
117-
mov sp, x8
118-
119-
bl {switch_to_el1} // switch to EL1
120-
bl {enable_fp} // enable fp/neon
121-
bl {init_boot_page_table}
122-
bl {init_mmu} // setup MMU
123-
124-
mov x8, {phys_virt_offset} // set SP to the high address
125-
add sp, sp, x8
126-
127-
mov x0, x19 // call rust_entry(cpu_id, dtb)
128-
mov x1, x20
129-
ldr x8, ={entry}
130-
blr x8
131-
b .",
132-
switch_to_el1 = sym switch_to_el1,
133-
init_boot_page_table = sym init_boot_page_table,
134-
init_mmu = sym init_mmu,
135-
enable_fp = sym enable_fp,
136-
boot_stack = sym BOOT_STACK,
137-
boot_stack_size = const TASK_STACK_SIZE,
138-
phys_virt_offset = const PHYS_VIRT_OFFSET,
139-
entry = sym crate::platform::rust_entry,
140-
)
119+
unsafe {
120+
// PC = bootloader load address
121+
// X0 = dtb
122+
core::arch::naked_asm!("
123+
add x13, x18, #0x16 // 'MZ' magic
124+
b {entry} // Branch to kernel start, magic
125+
126+
.quad 0 // Image load offset from start of RAM, little-endian
127+
.quad _ekernel - _start // Effective size of kernel image, little-endian
128+
.quad {flags} // Kernel flags, little-endian
129+
.quad 0 // reserved
130+
.quad 0 // reserved
131+
.quad 0 // reserved
132+
.ascii \"ARM\\x64\" // Magic number
133+
.long 0 // reserved (used for PE COFF offset)",
134+
flags = const FLAG_LE | FLAG_PAGE_SIZE_4K | FLAG_ANY_MEM,
135+
entry = sym _start_primary,
136+
)
137+
}
138+
}
139+
140+
/// The earliest entry point for the primary CPU.
141+
#[naked]
142+
#[unsafe(link_section = ".text.boot")]
143+
unsafe extern "C" fn _start_primary() -> ! {
144+
unsafe {
145+
// X0 = dtb
146+
core::arch::naked_asm!("
147+
mrs x19, mpidr_el1
148+
and x19, x19, #0xffffff // get current CPU id
149+
mov x20, x0 // save DTB pointer
150+
151+
adrp x8, {boot_stack} // setup boot stack
152+
add x8, x8, {boot_stack_size}
153+
mov sp, x8
154+
155+
bl {switch_to_el1} // switch to EL1
156+
bl {enable_fp} // enable fp/neon
157+
bl {init_boot_page_table}
158+
bl {init_mmu} // setup MMU
159+
160+
mov x8, {phys_virt_offset} // set SP to the high address
161+
add sp, sp, x8
162+
163+
mov x0, x19 // call rust_entry(cpu_id, dtb)
164+
mov x1, x20
165+
ldr x8, ={entry}
166+
blr x8
167+
b .",
168+
switch_to_el1 = sym switch_to_el1,
169+
init_boot_page_table = sym init_boot_page_table,
170+
init_mmu = sym init_mmu,
171+
enable_fp = sym enable_fp,
172+
boot_stack = sym BOOT_STACK,
173+
boot_stack_size = const TASK_STACK_SIZE,
174+
phys_virt_offset = const PHYS_VIRT_OFFSET,
175+
entry = sym crate::platform::rust_entry,
176+
)
177+
}
141178
}
142179

143180
/// The earliest entry point for the secondary CPUs.
@@ -146,26 +183,28 @@ unsafe extern "C" fn _start() -> ! {
146183
#[unsafe(no_mangle)]
147184
#[unsafe(link_section = ".text.boot")]
148185
unsafe extern "C" fn _start_secondary() -> ! {
149-
core::arch::naked_asm!("
150-
mrs x19, mpidr_el1
151-
and x19, x19, #0xffffff // get current CPU id
152-
153-
mov sp, x0
154-
bl {switch_to_el1}
155-
bl {init_mmu}
156-
bl {enable_fp}
157-
158-
mov x8, {phys_virt_offset} // set SP to the high address
159-
add sp, sp, x8
160-
161-
mov x0, x19 // call rust_entry_secondary(cpu_id)
162-
ldr x8, ={entry}
163-
blr x8
164-
b .",
165-
switch_to_el1 = sym switch_to_el1,
166-
init_mmu = sym init_mmu,
167-
enable_fp = sym enable_fp,
168-
phys_virt_offset = const PHYS_VIRT_OFFSET,
169-
entry = sym crate::platform::rust_entry_secondary,
170-
)
186+
unsafe {
187+
core::arch::naked_asm!("
188+
mrs x19, mpidr_el1
189+
and x19, x19, #0xffffff // get current CPU id
190+
191+
mov sp, x0
192+
bl {switch_to_el1}
193+
bl {init_mmu}
194+
bl {enable_fp}
195+
196+
mov x8, {phys_virt_offset} // set SP to the high address
197+
add sp, sp, x8
198+
199+
mov x0, x19 // call rust_entry_secondary(cpu_id)
200+
ldr x8, ={entry}
201+
blr x8
202+
b .",
203+
switch_to_el1 = sym switch_to_el1,
204+
init_mmu = sym init_mmu,
205+
enable_fp = sym enable_fp,
206+
phys_virt_offset = const PHYS_VIRT_OFFSET,
207+
entry = sym crate::platform::rust_entry_secondary,
208+
)
209+
}
171210
}

0 commit comments

Comments
 (0)