Skip to content

Commit 02c01c8

Browse files
committed
Refactor memory subsystem code
This patch refactors big chunks of the memory subsystem code. Most of all, it does away with the the design being based around the raw pointer type "*const Page". While raw pointers to an actual page seemed like a compelling idea, in practice it turned out difficult. Rust feels a bit inconsistent with respect to raw pointers. While it is safe to create them out of nowhere (only dereferencing is unsafe), it gets weird when multi-threading comes into picture. For example, wrapping them into synchronization primitives caused issues because they don't implement Send. For this reason, we switch to the PageAddress type which is based on usize, which makes things a lot easier. Other changes/benefits include: - Gets rid of unsafe code in the removed PageSlice type. - Decouple the translation table code and MMIO VA allocation. - For the translation table tool, make better use of what the ELF format already provides with respect to memory segmentation and translation. For example, the tool now queries the ELF file for VA->PA translations and other segment attributes. This has also the added benefit of reduced BSP code and more generic code in the tool. - Packs rbelftools in the Docker image now (used by translation table tool). - In tutorials 14/15/16, rearrange the PA and VA layout.
1 parent 89472ab commit 02c01c8

File tree

115 files changed

+5926
-3764
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+5926
-3764
lines changed

Diff for: .rubocop.yml

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ Layout/IndentationWidth:
1616
Layout/LineLength:
1717
Max: 100
1818

19+
Metrics/AbcSize:
20+
Max: 25
21+
1922
Metrics/ClassLength:
2023
Enabled: false
2124

Diff for: 01_wait_forever/src/bsp/raspberrypi/link.ld

+12-6
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,31 @@
33
* Copyright (c) 2018-2021 Andre Richter <andre.o[email protected]>
44
*/
55

6-
/* The address at which the the kernel binary will be loaded by the Raspberry's firmware */
7-
__rpi_load_addr = 0x80000;
6+
/* The physical address at which the the kernel binary will be loaded by the Raspberry's firmware */
7+
__rpi_phys_binary_load_addr = 0x80000;
88

9-
ENTRY(__rpi_load_addr)
109

10+
ENTRY(__rpi_phys_binary_load_addr)
11+
12+
/* Flags:
13+
* 4 == R
14+
* 5 == RX
15+
* 6 == RW
16+
*/
1117
PHDRS
1218
{
13-
segment_rx PT_LOAD FLAGS(5); /* 5 == RX */
19+
segment_code PT_LOAD FLAGS(5);
1420
}
1521

1622
SECTIONS
1723
{
18-
. = __rpi_load_addr;
24+
. = __rpi_phys_binary_load_addr;
1925

2026
/***********************************************************************************************
2127
* Code
2228
***********************************************************************************************/
2329
.text :
2430
{
2531
KEEP(*(.text._start))
26-
} :segment_rx
32+
} :segment_code
2733
}

Diff for: 02_runtime_init/README.md

+41-15
Original file line numberDiff line numberDiff line change
@@ -200,21 +200,47 @@ diff -uNr 01_wait_forever/src/bsp/raspberrypi/cpu.rs 02_runtime_init/src/bsp/ras
200200
diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/raspberrypi/link.ld
201201
--- 01_wait_forever/src/bsp/raspberrypi/link.ld
202202
+++ 02_runtime_init/src/bsp/raspberrypi/link.ld
203-
@@ -11,17 +11,43 @@
203+
@@ -3,6 +3,8 @@
204+
* Copyright (c) 2018-2021 Andre Richter <[email protected]>
205+
*/
206+
207+
+__rpi_phys_dram_start_addr = 0;
208+
+
209+
/* The physical address at which the the kernel binary will be loaded by the Raspberry's firmware */
210+
__rpi_phys_binary_load_addr = 0x80000;
211+
212+
@@ -13,21 +15,58 @@
213+
* 4 == R
214+
* 5 == RX
215+
* 6 == RW
216+
+ *
217+
+ * Segments are marked PT_LOAD below so that the ELF file provides virtual and physical addresses.
218+
+ * It doesn't mean all of them need actually be loaded.
219+
*/
204220
PHDRS
205221
{
206-
segment_rx PT_LOAD FLAGS(5); /* 5 == RX */
207-
+ segment_rw PT_LOAD FLAGS(6); /* 6 == RW */
222+
- segment_code PT_LOAD FLAGS(5);
223+
+ segment_boot_core_stack PT_LOAD FLAGS(6);
224+
+ segment_code PT_LOAD FLAGS(5);
225+
+ segment_data PT_LOAD FLAGS(6);
208226
}
209227

210228
SECTIONS
211229
{
212-
. = __rpi_load_addr;
213-
+ /* ^ */
214-
+ /* | stack */
215-
+ /* | growth */
216-
+ /* | direction */
217-
+ __boot_core_stack_end_exclusive = .; /* | */
230+
- . = __rpi_phys_binary_load_addr;
231+
+ . = __rpi_phys_dram_start_addr;
232+
+
233+
+ /***********************************************************************************************
234+
+ * Boot Core Stack
235+
+ ***********************************************************************************************/
236+
+ .boot_core_stack (NOLOAD) :
237+
+ {
238+
+ /* ^ */
239+
+ /* | stack */
240+
+ . += __rpi_phys_binary_load_addr; /* | growth */
241+
+ /* | direction */
242+
+ __boot_core_stack_end_exclusive = .; /* | */
243+
+ } :segment_boot_core_stack
218244

219245
/***********************************************************************************************
220246
- * Code
@@ -226,24 +252,24 @@ diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/ra
226252
+ *(.text._start_arguments) /* Constants (or statics in Rust speak) read by _start(). */
227253
+ *(.text._start_rust) /* The Rust entry point */
228254
+ *(.text*) /* Everything else */
229-
} :segment_rx
255+
} :segment_code
230256
+
231-
+ .rodata : ALIGN(8) { *(.rodata*) } :segment_rx
232-
+ .got : ALIGN(8) { *(.got) } :segment_rx
257+
+ .rodata : ALIGN(8) { *(.rodata*) } :segment_code
258+
+ .got : ALIGN(8) { *(.got) } :segment_code
233259
+
234260
+ /***********************************************************************************************
235261
+ * Data + BSS
236262
+ ***********************************************************************************************/
237-
+ .data : { *(.data*) } :segment_rw
263+
+ .data : { *(.data*) } :segment_data
238264
+
239265
+ /* Section is zeroed in pairs of u64. Align start and end to 16 bytes */
240-
+ .bss : ALIGN(16)
266+
+ .bss (NOLOAD) : ALIGN(16)
241267
+ {
242268
+ __bss_start = .;
243269
+ *(.bss*);
244270
+ . = ALIGN(16);
245271
+ __bss_end_exclusive = .;
246-
+ } :NONE
272+
+ } :segment_data
247273
}
248274

249275
diff -uNr 01_wait_forever/src/bsp/raspberrypi.rs 02_runtime_init/src/bsp/raspberrypi.rs

Diff for: 02_runtime_init/src/bsp/raspberrypi/link.ld

+36-17
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,44 @@
33
* Copyright (c) 2018-2021 Andre Richter <andre.o[email protected]>
44
*/
55

6-
/* The address at which the the kernel binary will be loaded by the Raspberry's firmware */
7-
__rpi_load_addr = 0x80000;
6+
__rpi_phys_dram_start_addr = 0;
87

9-
ENTRY(__rpi_load_addr)
8+
/* The physical address at which the the kernel binary will be loaded by the Raspberry's firmware */
9+
__rpi_phys_binary_load_addr = 0x80000;
1010

11+
12+
ENTRY(__rpi_phys_binary_load_addr)
13+
14+
/* Flags:
15+
* 4 == R
16+
* 5 == RX
17+
* 6 == RW
18+
*
19+
* Segments are marked PT_LOAD below so that the ELF file provides virtual and physical addresses.
20+
* It doesn't mean all of them need actually be loaded.
21+
*/
1122
PHDRS
1223
{
13-
segment_rx PT_LOAD FLAGS(5); /* 5 == RX */
14-
segment_rw PT_LOAD FLAGS(6); /* 6 == RW */
24+
segment_boot_core_stack PT_LOAD FLAGS(6);
25+
segment_code PT_LOAD FLAGS(5);
26+
segment_data PT_LOAD FLAGS(6);
1527
}
1628

1729
SECTIONS
1830
{
19-
. = __rpi_load_addr;
20-
/* ^ */
21-
/* | stack */
22-
/* | growth */
23-
/* | direction */
24-
__boot_core_stack_end_exclusive = .; /* | */
31+
. = __rpi_phys_dram_start_addr;
32+
33+
/***********************************************************************************************
34+
* Boot Core Stack
35+
***********************************************************************************************/
36+
.boot_core_stack (NOLOAD) :
37+
{
38+
/* ^ */
39+
/* | stack */
40+
. += __rpi_phys_binary_load_addr; /* | growth */
41+
/* | direction */
42+
__boot_core_stack_end_exclusive = .; /* | */
43+
} :segment_boot_core_stack
2544

2645
/***********************************************************************************************
2746
* Code + RO Data + Global Offset Table
@@ -32,22 +51,22 @@ SECTIONS
3251
*(.text._start_arguments) /* Constants (or statics in Rust speak) read by _start(). */
3352
*(.text._start_rust) /* The Rust entry point */
3453
*(.text*) /* Everything else */
35-
} :segment_rx
54+
} :segment_code
3655

37-
.rodata : ALIGN(8) { *(.rodata*) } :segment_rx
38-
.got : ALIGN(8) { *(.got) } :segment_rx
56+
.rodata : ALIGN(8) { *(.rodata*) } :segment_code
57+
.got : ALIGN(8) { *(.got) } :segment_code
3958

4059
/***********************************************************************************************
4160
* Data + BSS
4261
***********************************************************************************************/
43-
.data : { *(.data*) } :segment_rw
62+
.data : { *(.data*) } :segment_data
4463

4564
/* Section is zeroed in pairs of u64. Align start and end to 16 bytes */
46-
.bss : ALIGN(16)
65+
.bss (NOLOAD) : ALIGN(16)
4766
{
4867
__bss_start = .;
4968
*(.bss*);
5069
. = ALIGN(16);
5170
__bss_end_exclusive = .;
52-
} :NONE
71+
} :segment_data
5372
}

Diff for: 03_hacky_hello_world/src/bsp/raspberrypi/link.ld

+36-17
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,44 @@
33
* Copyright (c) 2018-2021 Andre Richter <andre.o[email protected]>
44
*/
55

6-
/* The address at which the the kernel binary will be loaded by the Raspberry's firmware */
7-
__rpi_load_addr = 0x80000;
6+
__rpi_phys_dram_start_addr = 0;
87

9-
ENTRY(__rpi_load_addr)
8+
/* The physical address at which the the kernel binary will be loaded by the Raspberry's firmware */
9+
__rpi_phys_binary_load_addr = 0x80000;
1010

11+
12+
ENTRY(__rpi_phys_binary_load_addr)
13+
14+
/* Flags:
15+
* 4 == R
16+
* 5 == RX
17+
* 6 == RW
18+
*
19+
* Segments are marked PT_LOAD below so that the ELF file provides virtual and physical addresses.
20+
* It doesn't mean all of them need actually be loaded.
21+
*/
1122
PHDRS
1223
{
13-
segment_rx PT_LOAD FLAGS(5); /* 5 == RX */
14-
segment_rw PT_LOAD FLAGS(6); /* 6 == RW */
24+
segment_boot_core_stack PT_LOAD FLAGS(6);
25+
segment_code PT_LOAD FLAGS(5);
26+
segment_data PT_LOAD FLAGS(6);
1527
}
1628

1729
SECTIONS
1830
{
19-
. = __rpi_load_addr;
20-
/* ^ */
21-
/* | stack */
22-
/* | growth */
23-
/* | direction */
24-
__boot_core_stack_end_exclusive = .; /* | */
31+
. = __rpi_phys_dram_start_addr;
32+
33+
/***********************************************************************************************
34+
* Boot Core Stack
35+
***********************************************************************************************/
36+
.boot_core_stack (NOLOAD) :
37+
{
38+
/* ^ */
39+
/* | stack */
40+
. += __rpi_phys_binary_load_addr; /* | growth */
41+
/* | direction */
42+
__boot_core_stack_end_exclusive = .; /* | */
43+
} :segment_boot_core_stack
2544

2645
/***********************************************************************************************
2746
* Code + RO Data + Global Offset Table
@@ -32,22 +51,22 @@ SECTIONS
3251
*(.text._start_arguments) /* Constants (or statics in Rust speak) read by _start(). */
3352
*(.text._start_rust) /* The Rust entry point */
3453
*(.text*) /* Everything else */
35-
} :segment_rx
54+
} :segment_code
3655

37-
.rodata : ALIGN(8) { *(.rodata*) } :segment_rx
38-
.got : ALIGN(8) { *(.got) } :segment_rx
56+
.rodata : ALIGN(8) { *(.rodata*) } :segment_code
57+
.got : ALIGN(8) { *(.got) } :segment_code
3958

4059
/***********************************************************************************************
4160
* Data + BSS
4261
***********************************************************************************************/
43-
.data : { *(.data*) } :segment_rw
62+
.data : { *(.data*) } :segment_data
4463

4564
/* Section is zeroed in pairs of u64. Align start and end to 16 bytes */
46-
.bss : ALIGN(16)
65+
.bss (NOLOAD) : ALIGN(16)
4766
{
4867
__bss_start = .;
4968
*(.bss*);
5069
. = ALIGN(16);
5170
__bss_end_exclusive = .;
52-
} :NONE
71+
} :segment_data
5372
}

Diff for: 04_safe_globals/src/bsp/raspberrypi/link.ld

+36-17
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,44 @@
33
* Copyright (c) 2018-2021 Andre Richter <andre.o[email protected]>
44
*/
55

6-
/* The address at which the the kernel binary will be loaded by the Raspberry's firmware */
7-
__rpi_load_addr = 0x80000;
6+
__rpi_phys_dram_start_addr = 0;
87

9-
ENTRY(__rpi_load_addr)
8+
/* The physical address at which the the kernel binary will be loaded by the Raspberry's firmware */
9+
__rpi_phys_binary_load_addr = 0x80000;
1010

11+
12+
ENTRY(__rpi_phys_binary_load_addr)
13+
14+
/* Flags:
15+
* 4 == R
16+
* 5 == RX
17+
* 6 == RW
18+
*
19+
* Segments are marked PT_LOAD below so that the ELF file provides virtual and physical addresses.
20+
* It doesn't mean all of them need actually be loaded.
21+
*/
1122
PHDRS
1223
{
13-
segment_rx PT_LOAD FLAGS(5); /* 5 == RX */
14-
segment_rw PT_LOAD FLAGS(6); /* 6 == RW */
24+
segment_boot_core_stack PT_LOAD FLAGS(6);
25+
segment_code PT_LOAD FLAGS(5);
26+
segment_data PT_LOAD FLAGS(6);
1527
}
1628

1729
SECTIONS
1830
{
19-
. = __rpi_load_addr;
20-
/* ^ */
21-
/* | stack */
22-
/* | growth */
23-
/* | direction */
24-
__boot_core_stack_end_exclusive = .; /* | */
31+
. = __rpi_phys_dram_start_addr;
32+
33+
/***********************************************************************************************
34+
* Boot Core Stack
35+
***********************************************************************************************/
36+
.boot_core_stack (NOLOAD) :
37+
{
38+
/* ^ */
39+
/* | stack */
40+
. += __rpi_phys_binary_load_addr; /* | growth */
41+
/* | direction */
42+
__boot_core_stack_end_exclusive = .; /* | */
43+
} :segment_boot_core_stack
2544

2645
/***********************************************************************************************
2746
* Code + RO Data + Global Offset Table
@@ -32,22 +51,22 @@ SECTIONS
3251
*(.text._start_arguments) /* Constants (or statics in Rust speak) read by _start(). */
3352
*(.text._start_rust) /* The Rust entry point */
3453
*(.text*) /* Everything else */
35-
} :segment_rx
54+
} :segment_code
3655

37-
.rodata : ALIGN(8) { *(.rodata*) } :segment_rx
38-
.got : ALIGN(8) { *(.got) } :segment_rx
56+
.rodata : ALIGN(8) { *(.rodata*) } :segment_code
57+
.got : ALIGN(8) { *(.got) } :segment_code
3958

4059
/***********************************************************************************************
4160
* Data + BSS
4261
***********************************************************************************************/
43-
.data : { *(.data*) } :segment_rw
62+
.data : { *(.data*) } :segment_data
4463

4564
/* Section is zeroed in pairs of u64. Align start and end to 16 bytes */
46-
.bss : ALIGN(16)
65+
.bss (NOLOAD) : ALIGN(16)
4766
{
4867
__bss_start = .;
4968
*(.bss*);
5069
. = ALIGN(16);
5170
__bss_end_exclusive = .;
52-
} :NONE
71+
} :segment_data
5372
}

0 commit comments

Comments
 (0)