|
19 | 19 | [bss]: https://en.wikipedia.org/wiki/.bss |
20 | 20 |
|
21 | 21 | ## 相比之前的变化(diff) |
22 | | -```diff |
23 | 22 |
|
24 | | -diff -uNr 01_wait_forever/Cargo.toml 02_runtime_init/Cargo.toml |
25 | | ---- 01_wait_forever/Cargo.toml |
26 | | -+++ 02_runtime_init/Cargo.toml |
27 | | -@@ -4,6 +4,9 @@ |
28 | | - authors = ["Andre Richter <andre.o.richter@gmail.com>"] |
29 | | - edition = "2018" |
30 | | - |
31 | | -+[profile.release] |
32 | | -+lto = true |
33 | | -+ |
34 | | - # The features section is used to select the target board. |
35 | | - [features] |
36 | | - default = [] |
37 | | - |
38 | | -diff -uNr 01_wait_forever/src/_arch/aarch64/cpu/boot.S 02_runtime_init/src/_arch/aarch64/cpu/boot.S |
39 | | ---- 01_wait_forever/src/_arch/aarch64/cpu/boot.S |
40 | | -+++ 02_runtime_init/src/_arch/aarch64/cpu/boot.S |
41 | | -@@ -7,5 +7,15 @@ |
42 | | - .global _start |
43 | | - |
44 | | - _start: |
45 | | --1: wfe // Wait for event |
46 | | -- b 1b // In case an event happened, jump back to 1 |
47 | | -+ mrs x1, mpidr_el1 // Read Multiprocessor Affinity Register |
48 | | -+ and x1, x1, #3 // Clear all bits except [1:0], which hold core id |
49 | | -+ cbz x1, 2f // Jump to label 2 if we are core 0 |
50 | | -+1: wfe // Wait for event |
51 | | -+ b 1b // In case an event happened, jump back to 1 |
52 | | -+2: // If we are here, we are core0 |
53 | | -+ ldr x1, =_start // Load address of function "_start()" |
54 | | -+ mov sp, x1 // Set start of stack to before our code, aka first |
55 | | -+ // address before "_start()" |
56 | | -+ bl runtime_init // Jump to the "runtime_init()" kernel function |
57 | | -+ b 1b // We should never reach here. But just in case, |
58 | | -+ // park this core aswell |
59 | | - |
60 | | -diff -uNr 01_wait_forever/src/_arch/aarch64/cpu.rs 02_runtime_init/src/_arch/aarch64/cpu.rs |
61 | | ---- 01_wait_forever/src/_arch/aarch64/cpu.rs |
62 | | -+++ 02_runtime_init/src/_arch/aarch64/cpu.rs |
63 | | -@@ -0,0 +1,30 @@ |
64 | | -+// SPDX-License-Identifier: MIT OR Apache-2.0 |
65 | | -+// |
66 | | -+// Copyright (c) 2018-2022 Andre Richter <andre.o.richter@gmail.com> |
67 | | -+ |
68 | | -+//! Architectural processor code. |
69 | | -+//! |
70 | | -+//! # Orientation |
71 | | -+//! |
72 | | -+//! Since arch modules are imported into generic modules using the path attribute, the path of this |
73 | | -+//! file is: |
74 | | -+//! |
75 | | -+//! crate::cpu::arch_cpu |
76 | | -+ |
77 | | -+//-------------------------------------------------------------------------------------------------- |
78 | | -+// Public Code |
79 | | -+//-------------------------------------------------------------------------------------------------- |
80 | | -+ |
81 | | -+/// Pause execution on the core. |
82 | | -+#[inline(always)] |
83 | | -+pub fn wait_forever() -> ! { |
84 | | -+ unsafe { |
85 | | -+ loop { |
86 | | -+ #[rustfmt::skip] |
87 | | -+ asm!( |
88 | | -+ "wfe", |
89 | | -+ options(nomem, nostack, preserves_flags) |
90 | | -+ ); |
91 | | -+ } |
92 | | -+ } |
93 | | -+} |
94 | | - |
95 | | -diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/raspberrypi/link.ld |
96 | | ---- 01_wait_forever/src/bsp/raspberrypi/link.ld |
97 | | -+++ 02_runtime_init/src/bsp/raspberrypi/link.ld |
98 | | -@@ -13,5 +13,27 @@ |
99 | | - *(.text._start) *(.text*) |
100 | | - } |
101 | | - |
102 | | -+ .rodata : |
103 | | -+ { |
104 | | -+ *(.rodata*) |
105 | | -+ } |
106 | | -+ |
107 | | -+ .data : |
108 | | -+ { |
109 | | -+ *(.data*) |
110 | | -+ } |
111 | | -+ |
112 | | -+ /* Section is zeroed in u64 chunks, align start and end to 8 bytes */ |
113 | | -+ .bss ALIGN(8): |
114 | | -+ { |
115 | | -+ __bss_start = .; |
116 | | -+ *(.bss*); |
117 | | -+ . = ALIGN(8); |
118 | | -+ |
119 | | -+ /* Fill for the bss == 0 case, so that __bss_start <= __bss_end_inclusive holds */ |
120 | | -+ . += 8; |
121 | | -+ __bss_end_inclusive = . - 8; |
122 | | -+ } |
123 | | -+ |
124 | | - /DISCARD/ : { *(.comment*) } |
125 | | - } |
126 | | - |
127 | | -diff -uNr 01_wait_forever/src/bsp/raspberrypi/memory.rs 02_runtime_init/src/bsp/raspberrypi/memory.rs |
128 | | ---- 01_wait_forever/src/bsp/raspberrypi/memory.rs |
129 | | -+++ 02_runtime_init/src/bsp/raspberrypi/memory.rs |
130 | | -@@ -0,0 +1,37 @@ |
131 | | -+// SPDX-License-Identifier: MIT OR Apache-2.0 |
132 | | -+// |
133 | | -+// Copyright (c) 2018-2022 Andre Richter <andre.o.richter@gmail.com> |
134 | | -+ |
135 | | -+//! BSP Memory Management. |
136 | | -+ |
137 | | -+use core::{cell::UnsafeCell, ops::RangeInclusive}; |
138 | | -+ |
139 | | -+//-------------------------------------------------------------------------------------------------- |
140 | | -+// Private Definitions |
141 | | -+//-------------------------------------------------------------------------------------------------- |
142 | | -+ |
143 | | -+// Symbols from the linker script. |
144 | | -+extern "Rust" { |
145 | | -+ static __bss_start: UnsafeCell<u64>; |
146 | | -+ static __bss_end_inclusive: UnsafeCell<u64>; |
147 | | -+} |
148 | | -+ |
149 | | -+//-------------------------------------------------------------------------------------------------- |
150 | | -+// Public Code |
151 | | -+//-------------------------------------------------------------------------------------------------- |
152 | | -+ |
153 | | -+/// Return the inclusive range spanning the .bss section. |
154 | | -+/// |
155 | | -+/// # Safety |
156 | | -+/// |
157 | | -+/// - Values are provided by the linker script and must be trusted as-is. |
158 | | -+/// - The linker-provided addresses must be u64 aligned. |
159 | | -+pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { |
160 | | -+ let range; |
161 | | -+ unsafe { |
162 | | -+ range = RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()); |
163 | | -+ } |
164 | | -+ assert!(!range.is_empty()); |
165 | | -+ |
166 | | -+ range |
167 | | -+} |
168 | | - |
169 | | -diff -uNr 01_wait_forever/src/bsp/raspberrypi.rs 02_runtime_init/src/bsp/raspberrypi.rs |
170 | | ---- 01_wait_forever/src/bsp/raspberrypi.rs |
171 | | -+++ 02_runtime_init/src/bsp/raspberrypi.rs |
172 | | -@@ -4,4 +4,4 @@ |
173 | | - |
174 | | - //! Top-level BSP file for the Raspberry Pi 3 and 4. |
175 | | - |
176 | | --// Coming soon. |
177 | | -+pub mod memory; |
178 | | - |
179 | | -diff -uNr 01_wait_forever/src/cpu.rs 02_runtime_init/src/cpu.rs |
180 | | ---- 01_wait_forever/src/cpu.rs |
181 | | -+++ 02_runtime_init/src/cpu.rs |
182 | | -@@ -4,4 +4,13 @@ |
183 | | - |
184 | | - //! Processor code. |
185 | | - |
186 | | -+#[cfg(target_arch = "aarch64")] |
187 | | -+#[path = "_arch/aarch64/cpu.rs"] |
188 | | -+mod arch_cpu; |
189 | | -+ |
190 | | - mod boot; |
191 | | -+ |
192 | | -+//-------------------------------------------------------------------------------------------------- |
193 | | -+// Architectural Public Reexports |
194 | | -+//-------------------------------------------------------------------------------------------------- |
195 | | -+pub use arch_cpu::wait_forever; |
196 | | - |
197 | | -diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs |
198 | | ---- 01_wait_forever/src/main.rs |
199 | | -+++ 02_runtime_init/src/main.rs |
200 | | -@@ -102,6 +102,7 @@ |
201 | | - //! |
202 | | - //! 1. The kernel's entry point is the function [`cpu::boot::arch_boot::_start()`]. |
203 | | - //! - It is implemented in `src/_arch/__arch_name__/cpu/boot.rs`. |
204 | | -+//! 2. Once finished with architectural setup, the arch code calls [`runtime_init::runtime_init()`]. |
205 | | - //! |
206 | | - //! [`cpu::boot::arch_boot::_start()`]: cpu/boot/arch_boot/fn._start.html |
207 | | - |
208 | | -@@ -112,6 +113,15 @@ |
209 | | - |
210 | | - mod bsp; |
211 | | - mod cpu; |
212 | | -+mod memory; |
213 | | - mod panic_wait; |
214 | | -+mod runtime_init; |
215 | | - |
216 | | --// Kernel code coming next tutorial. |
217 | | -+/// Early init code. |
218 | | -+/// |
219 | | -+/// # Safety |
220 | | -+/// |
221 | | -+/// - Only a single core must be active and running this function. |
222 | | -+unsafe fn kernel_init() -> ! { |
223 | | -+ panic!() |
224 | | -+} |
225 | | - |
226 | | -diff -uNr 01_wait_forever/src/memory.rs 02_runtime_init/src/memory.rs |
227 | | ---- 01_wait_forever/src/memory.rs |
228 | | -+++ 02_runtime_init/src/memory.rs |
229 | | -@@ -0,0 +1,30 @@ |
230 | | -+// SPDX-License-Identifier: MIT OR Apache-2.0 |
231 | | -+// |
232 | | -+// Copyright (c) 2018-2022 Andre Richter <andre.o.richter@gmail.com> |
233 | | -+ |
234 | | -+//! Memory Management. |
235 | | -+ |
236 | | -+use core::ops::RangeInclusive; |
237 | | -+ |
238 | | -+//-------------------------------------------------------------------------------------------------- |
239 | | -+// Public Code |
240 | | -+//-------------------------------------------------------------------------------------------------- |
241 | | -+ |
242 | | -+/// Zero out an inclusive memory range. |
243 | | -+/// |
244 | | -+/// # Safety |
245 | | -+/// |
246 | | -+/// - `range.start` and `range.end` must be valid. |
247 | | -+/// - `range.start` and `range.end` must be `T` aligned. |
248 | | -+pub unsafe fn zero_volatile<T>(range: RangeInclusive<*mut T>) |
249 | | -+where |
250 | | -+ T: From<u8>, |
251 | | -+{ |
252 | | -+ let mut ptr = *range.start(); |
253 | | -+ let end_inclusive = *range.end(); |
254 | | -+ |
255 | | -+ while ptr <= end_inclusive { |
256 | | -+ core::ptr::write_volatile(ptr, T::from(0)); |
257 | | -+ ptr = ptr.offset(1); |
258 | | -+ } |
259 | | -+} |
260 | | - |
261 | | -diff -uNr 01_wait_forever/src/panic_wait.rs 02_runtime_init/src/panic_wait.rs |
262 | | ---- 01_wait_forever/src/panic_wait.rs |
263 | | -+++ 02_runtime_init/src/panic_wait.rs |
264 | | -@@ -4,9 +4,10 @@ |
265 | | - |
266 | | - //! A panic handler that infinitely waits. |
267 | | - |
268 | | -+use crate::cpu; |
269 | | - use core::panic::PanicInfo; |
270 | | - |
271 | | - #[panic_handler] |
272 | | - fn panic(_info: &PanicInfo) -> ! { |
273 | | -- unimplemented!() |
274 | | -+ cpu::wait_forever() |
275 | | - } |
276 | | - |
277 | | -diff -uNr 01_wait_forever/src/runtime_init.rs 02_runtime_init/src/runtime_init.rs |
278 | | ---- 01_wait_forever/src/runtime_init.rs |
279 | | -+++ 02_runtime_init/src/runtime_init.rs |
280 | | -@@ -0,0 +1,38 @@ |
281 | | -+// SPDX-License-Identifier: MIT OR Apache-2.0 |
282 | | -+// |
283 | | -+// Copyright (c) 2018-2022 Andre Richter <andre.o.richter@gmail.com> |
284 | | -+ |
285 | | -+//! Rust runtime initialization code. |
286 | | -+ |
287 | | -+use crate::{bsp, memory}; |
288 | | -+ |
289 | | -+//-------------------------------------------------------------------------------------------------- |
290 | | -+// Private Code |
291 | | -+//-------------------------------------------------------------------------------------------------- |
292 | | -+ |
293 | | -+/// Zero out the .bss section. |
294 | | -+/// |
295 | | -+/// # Safety |
296 | | -+/// |
297 | | -+/// - Must only be called pre `kernel_init()`. |
298 | | -+#[inline(always)] |
299 | | -+unsafe fn zero_bss() { |
300 | | -+ memory::zero_volatile(bsp::memory::bss_range_inclusive()); |
301 | | -+} |
302 | | -+ |
303 | | -+//-------------------------------------------------------------------------------------------------- |
304 | | -+// Public Code |
305 | | -+//-------------------------------------------------------------------------------------------------- |
306 | | -+ |
307 | | -+/// Equivalent to `crt0` or `c0` code in C/C++ world. Clears the `bss` section, then jumps to kernel |
308 | | -+/// init code. |
309 | | -+/// |
310 | | -+/// # Safety |
311 | | -+/// |
312 | | -+/// - Only a single core must be active and running this function. |
313 | | -+#[no_mangle] |
314 | | -+pub unsafe fn runtime_init() -> ! { |
315 | | -+ zero_bss(); |
316 | | -+ |
317 | | -+ crate::kernel_init() |
318 | | -+} |
319 | | - |
320 | | -``` |
| 23 | +Please check [the english version](README.md#diff-to-previous), which is kept up-to-date. |
0 commit comments