|
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