66
66
< h1 class ="title "> Inside Arm64 MMU: Unicorn Emulator vs Apache NuttX RTOS</ h1 >
67
67
< nav id ="rustdoc "> < ul >
68
68
< li > < a href ="#memory-management-unit " title ="Memory Management Unit "> 1 Memory Management Unit</ a > < ul > </ ul > </ li >
69
- < li > < a href ="#map-virtual-address-to-physical-address " title ="Map Virtual Address to Physical Address "> 2 Map Virtual Address to Physical Address</ a > < ul > </ ul > </ li >
70
- < li > < a href ="#translation-control-register " title ="Translation Control Register "> 3 Translation Control Register</ a > < ul > </ ul > </ li >
71
- < li > < a href ="#enable-the-mmu " title ="Enable the MMU "> 4 Enable the MMU</ a > < ul > </ ul > </ li >
72
- < li > < a href ="#populate-the-ram " title ="Populate the RAM "> 5 Populate the RAM</ a > < ul > </ ul > </ li >
73
- < li > < a href ="#nuttx-crashes-in-unicorn " title ="NuttX crashes in Unicorn "> 6 NuttX crashes in Unicorn</ a > < ul > </ ul > </ li >
74
- < li > < a href ="#before-fixing-nuttx " title ="Before Fixing NuttX "> 7 Before Fixing NuttX</ a > < ul > </ ul > </ li >
75
- < li > < a href ="#nuttx-vs-mmu-demo " title ="NuttX vs MMU Demo "> 8 NuttX vs MMU Demo</ a > < ul > </ ul > </ li >
76
- < li > < a href ="#after-fixing-nuttx " title ="After Fixing NuttX "> 9 After Fixing NuttX</ a > < ul > </ ul > </ li >
77
- < li > < a href ="#boot-flow " title ="Boot Flow "> 10 Boot Flow</ a > < ul > </ ul > </ li >
78
- < li > < a href ="#todo " title ="TODO "> 11 TODO</ a > < ul > </ ul > </ li >
79
- < li > < a href ="#todo-1 " title ="TODO "> 12 TODO</ a > < ul > </ ul > </ li >
80
- < li > < a href ="#whats-next " title ="What’s Next "> 13 What’s Next</ a > < ul > </ ul > </ li >
81
- < li > < a href ="#appendix-simplified-nuttx-for-qemu " title ="Appendix: Simplified NuttX for QEMU "> 14 Appendix: Simplified NuttX for QEMU</ a > < ul > </ ul > </ li > </ ul > </ nav > < p > 📝 < em > 9 Apr 2025</ em > </ p >
69
+ < li > < a href ="#level-1-page-table " title ="Level 1 Page Table "> 2 Level 1 Page Table</ a > < ul > </ ul > </ li >
70
+ < li > < a href ="#page-table-entry " title ="Page Table Entry "> 3 Page Table Entry</ a > < ul > </ ul > </ li >
71
+ < li > < a href ="#translation-control-register " title ="Translation Control Register "> 4 Translation Control Register</ a > < ul > </ ul > </ li >
72
+ < li > < a href ="#enable-the-mmu " title ="Enable the MMU "> 5 Enable the MMU</ a > < ul > </ ul > </ li >
73
+ < li > < a href ="#populate-the-ram " title ="Populate the RAM "> 6 Populate the RAM</ a > < ul > </ ul > </ li >
74
+ < li > < a href ="#nuttx-crashes-in-unicorn " title ="NuttX crashes in Unicorn "> 7 NuttX crashes in Unicorn</ a > < ul > </ ul > </ li >
75
+ < li > < a href ="#before-fixing-nuttx " title ="Before Fixing NuttX "> 8 Before Fixing NuttX</ a > < ul > </ ul > </ li >
76
+ < li > < a href ="#nuttx-vs-mmu-demo " title ="NuttX vs MMU Demo "> 9 NuttX vs MMU Demo</ a > < ul > </ ul > </ li >
77
+ < li > < a href ="#after-fixing-nuttx " title ="After Fixing NuttX "> 10 After Fixing NuttX</ a > < ul > </ ul > </ li >
78
+ < li > < a href ="#boot-flow " title ="Boot Flow "> 11 Boot Flow</ a > < ul > </ ul > </ li >
79
+ < li > < a href ="#todo " title ="TODO "> 12 TODO</ a > < ul > </ ul > </ li >
80
+ < li > < a href ="#todo-1 " title ="TODO "> 13 TODO</ a > < ul > </ ul > </ li >
81
+ < li > < a href ="#whats-next " title ="What’s Next "> 14 What’s Next</ a > < ul > </ ul > </ li >
82
+ < li > < a href ="#appendix-simplified-nuttx-for-qemu " title ="Appendix: Simplified NuttX for QEMU "> 15 Appendix: Simplified NuttX for QEMU</ a > < ul > </ ul > </ li > </ ul > </ nav > < p > 📝 < em > 9 Apr 2025</ em > </ p >
82
83
< p > < img src ="https://lupyuen.org/images/unicorn3-title.png " alt ="TODO " /> </ p >
83
84
< p > < a href ="TODO "> < strong > Unicorn Emulator</ strong > </ a > has a fascinating demo of < a href ="TODO "> < strong > Arm64 MMU</ strong > </ a > < em > (Memory Management Unit)</ em > … Only < a href ="TODO "> < strong > 18 Lines of Arm64 Assembly</ strong > </ a > ! < em > (Pic above)</ em > </ p >
84
85
< p > This article deciphers the code inside < strong > Arm64 MMU Demo</ strong > , how it works. And why it’s super helpful for emulating < a href ="TODO "> < strong > Apache NuttX RTOS</ strong > </ a > compiled for Arm64 SBCs!</ p >
@@ -196,7 +197,7 @@ <h1 id="memory-management-unit"><a class="doc-anchor" href="#memory-management-u
196
197
</ li >
197
198
</ ol >
198
199
< p > Yeah the steps for < em > “Map Virtual Address”</ em > and < em > “Enable MMU”</ em > are extremely cryptic. We break them down…</ p >
199
- < h1 id ="map-virtual-address-to-physical-address "> < a class ="doc-anchor " href ="#map-virtual-address-to-physical-address "> §</ a > 2 Map Virtual Address to Physical Address </ h1 >
200
+ < h1 id ="level-1-page-table "> < a class ="doc-anchor " href ="#level-1-page-table "> §</ a > 2 Level 1 Page Table </ h1 >
200
201
< p > < em > What’s this mystery code from above?</ em > </ p >
201
202
202
203
< div class ="example-wrap "> < pre class ="rust rust-example-rendered "> < code > < span class ="comment "> // Init the MMU Registers:
@@ -212,9 +213,9 @@ <h1 id="map-virtual-address-to-physical-address"><a class="doc-anchor" href="#ma
212
213
// TTBR0_EL1 becomes ttb0_base
213
214
</ span > adr X0, ttb0_base < span class ="comment "> // Load ttb0_base into Register X0
214
215
</ span > msr TTBR0_EL1, X0 < span class ="comment "> // Write X0 into System Register TTBR0_EL1</ span > </ code > </ pre > </ div >
215
- < p > This code will < strong > Map Virtual Address</ strong > to Physical Address, so that < em > 0x8000_0000</ em > (virtually) becomes < em > 0x4000_0000</ em > . We ’ll explain TCR and MAIR in the next section , but first…</ p >
216
+ < p > This code will < strong > Map Virtual Address</ strong > to Physical Address, so that < em > 0x8000_0000</ em > (virtually) becomes < em > 0x4000_0000</ em > . Later we ’ll explain TCR and MAIR, but first…</ p >
216
217
< p > < em > What’s TTBR0_EL1? Why set it to ttb0_base?</ em > </ p >
217
- < p > That’s the < a href ="TODO "> < strong > Level 1 Page Table</ strong > </ a > that describes to MMU our < strong > Virtual-to-Physical Mapping</ strong > . Suppose we’re mapping this…</ p >
218
+ < p > That’s the < a href ="TODO "> < strong > Level 1 Page Table</ strong > </ a > telling MMU our < strong > Virtual-to-Physical Mapping</ strong > . Suppose we’re mapping this…</ p >
218
219
< div > < table > < thead > < tr > < th style ="text-align: center "> Virtual Address</ th > < th style ="text-align: center "> Physical Address</ th > </ tr > </ thead > < tbody >
219
220
< tr > < td style ="text-align: center "> < strong > < code > 0x0000_0000</ code > </ strong > </ td > < td style ="text-align: center "> < code > 0x0000_0000</ code > </ td > </ tr >
220
221
< tr > < td style ="text-align: center "> < strong > < code > 0x4000_0000</ code > </ strong > </ td > < td style ="text-align: center "> < code > 0xA000_0000</ code > </ td > </ tr >
@@ -224,35 +225,55 @@ <h1 id="map-virtual-address-to-physical-address"><a class="doc-anchor" href="#ma
224
225
</ div >
225
226
< p > Our < a href ="TODO "> < strong > Level 1 Page Table</ strong > </ a > will be this…</ p >
226
227
< p > TODO: Pic of Level 1 Page Table</ p >
228
+ < p > Which we < strong > Store in RAM</ strong > < em > (ttb0_base)</ em > as…</ p >
229
+ < div > < table > < thead > < tr > < th style ="text-align: center "> Address</ th > < th style ="text-align: center "> Value</ th > < th style ="text-align: left "> Because</ th > </ tr > </ thead > < tbody >
230
+ < tr > < td style ="text-align: center "> < strong > < code > 0x1000</ code > </ strong > </ td > < td style ="text-align: center "> < code > 0x0000_0741</ code > </ td > < td style ="text-align: left "> < em > Page Table Entry #0</ em > </ td > </ tr >
231
+ < tr > < td style ="text-align: center "> < strong > < code > 0x1008</ code > </ strong > </ td > < td style ="text-align: center "> < code > 0xA000_0741</ code > </ td > < td style ="text-align: left "> < em > Page Table Entry #1</ em > </ td > </ tr >
232
+ < tr > < td style ="text-align: center "> < strong > < code > 0x1010</ code > </ strong > </ td > < td style ="text-align: center "> < code > 0x4000_0741</ code > </ td > < td style ="text-align: left "> < em > Page Table Entry #2</ em > </ td > </ tr >
233
+ < tr > < td style ="text-align: center "> < strong > < code > 0x1018</ code > </ strong > </ td > < td style ="text-align: center "> < code > 0x8000_0741</ code > </ td > < td style ="text-align: left "> < em > Page Table Entry #3</ em > </ td > </ tr >
234
+ </ tbody > </ table >
235
+ </ div >
227
236
< p > < a href ="https://gist.github.com/lupyuen/6c8cf74ee68a6f11ca61c2fa3c5573d0 "> (See the < strong > Unicorn Log</ strong > )</ a > </ p >
228
237
< p > < a href ="TODO "> (And the < strong > Unicorn Code</ strong > )</ a > </ p >
229
238
< p > < a href ="https://developer.arm.com/documentation/ddi0601/2024-12/AArch64-Registers/TTBR0-EL1--Translation-Table-Base-Register-0--EL1- "> (< strong > TTBR0_EL1</ strong > is < em > “Translation Table Base Register 0 for Exception Level 1”</ em > )</ a > </ p >
230
- < p > < em > Why 741?</ em > </ p >
231
- < div class ="example-wrap "> < pre class ="language-text "> < code > Bit 00-01: PTE_BLOCK_DESC=1
232
- Bit 06-07: PTE_BLOCK_DESC_AP_USER=1
233
- Bit 08-09: PTE_BLOCK_DESC_INNER_SHARE=3
234
- Bit 10: PTE_BLOCK_DESC_AF=1</ code > </ pre > </ div >
239
+ < h1 id ="page-table-entry "> < a class ="doc-anchor " href ="#page-table-entry "> §</ a > 3 Page Table Entry</ h1 >
240
+ < p > < em > In the Page Table Entries above: Why 741?</ em > </ p >
241
+ < p > We decode each < strong > Page Table Entry</ strong > based on < a href ="TODO "> < strong > VMSAv8-64 Block Descriptors</ strong > </ a > < em > (Page D8-6491)</ em > …</ p >
235
242
< p > < img src ="https://lupyuen.org/images/unicorn3-block.png " alt ="TODO " /> </ p >
236
- < p > < a href ="https://github.com/apache/nuttx/blob/master/arch/arm64/src/common/arm64_mmu.h#L95-L122 "> arm64_mmu.h</ a > </ p >
243
+ < ul >
244
+ < li >
245
+ < p > < strong > Bits 00-01:</ strong > BLOCK_DESC = 1 < br > < em > This Page Table Entry describes a Block, not a Page</ em > </ p >
246
+ </ li >
247
+ < li >
248
+ < p > < strong > Bits 06-07:</ strong > BLOCK_DESC_AP_USER = 1 < br > < em > This Block is Read-Writeable by Kernel, Read-Writeable by Apps</ em > </ p >
249
+ </ li >
250
+ < li >
251
+ < p > < strong > Bits 08-09:</ strong > BLOCK_DESC_INNER_SHARE = 3 < br > < em > This Block is Inner Shareable (see below)</ em > </ p >
252
+ </ li >
253
+ < li >
254
+ < p > < strong > Bits 10-10:</ strong > BLOCK_DESC_AF = 1 < br > < em > Allow this Virtual-to-Physical Mapping to be cached</ em > </ p >
255
+ </ li >
256
+ </ ul >
257
+ < p > NuttX defines the whole list here: < a href ="https://github.com/apache/nuttx/blob/master/arch/arm64/src/common/arm64_mmu.h#L95-L122 "> arm64_mmu.h</ a > </ p >
237
258
< div class ="example-wrap "> < pre class ="language-c "> < code > // PTE descriptor can be Block descriptor or Table descriptor or Page descriptor
238
259
#define PTE_BLOCK_DESC 1U
239
260
#define PTE_TABLE_DESC 3U
240
261
241
262
// Block and Page descriptor attributes fields
242
263
#define PTE_BLOCK_DESC_MEMTYPE(x) ((x) << 2)
243
- #define PTE_BLOCK_DESC_NS (1ULL << 5) /* Non-secure */
244
- #define PTE_BLOCK_DESC_AP_USER (1ULL << 6) /* User */
245
- #define PTE_BLOCK_DESC_AP_RO (1ULL << 7) /* Read-only */
246
- #define PTE_BLOCK_DESC_AP_RW (0ULL << 7) /* Read-write */
264
+ #define PTE_BLOCK_DESC_NS (1ULL << 5) // Non-Secure
265
+ #define PTE_BLOCK_DESC_AP_USER (1ULL << 6) // User Read-Write
266
+ #define PTE_BLOCK_DESC_AP_RO (1ULL << 7) // Kernel Read-Only
267
+ #define PTE_BLOCK_DESC_AP_RW (0ULL << 7) // Kernel Read-Write
247
268
#define PTE_BLOCK_DESC_AP_MASK (3ULL << 6)
248
269
#define PTE_BLOCK_DESC_NON_SHARE (0ULL << 8)
249
270
#define PTE_BLOCK_DESC_OUTER_SHARE (2ULL << 8)
250
271
#define PTE_BLOCK_DESC_INNER_SHARE (3ULL << 8)
251
- #define PTE_BLOCK_DESC_AF (1ULL << 10) /* A-flag */
252
- #define PTE_BLOCK_DESC_NG (1ULL << 11) /* Non-global */
253
- #define PTE_BLOCK_DESC_DIRTY (1ULL << 51) /* D-flag */
254
- #define PTE_BLOCK_DESC_PXN (1ULL << 53) /* Kernel execute never */
255
- #define PTE_BLOCK_DESC_UXN (1ULL << 54) /* User execute never */ </ code > </ pre > </ div >
272
+ #define PTE_BLOCK_DESC_AF (1ULL << 10) // A Flag
273
+ #define PTE_BLOCK_DESC_NG (1ULL << 11) // Non-Global
274
+ #define PTE_BLOCK_DESC_DIRTY (1ULL << 51) // D Flag
275
+ #define PTE_BLOCK_DESC_PXN (1ULL << 53) // Kernel Execute Never
276
+ #define PTE_BLOCK_DESC_UXN (1ULL << 54) // User Execute Never </ code > </ pre > </ div >
256
277
< p > < em > What if we read from 0x4000_0000 AFTER enabling MMU?</ em > </ p >
257
278
< p > We’ll see < a href ="TODO "> < em > 0xAA AA AA AA…</ em > </ a > . Yep the MMU can remap memory in fun interesting ways!</ p >
258
279
< p > < em > Why map 0x0000_0000 to itself?</ em > </ p >
@@ -279,7 +300,7 @@ <h1 id="map-virtual-address-to-physical-address"><a class="doc-anchor" href="#ma
279
300
— For a stage 1 translation, translate a VA to an IPA.
280
301
— For a stage 2 translation, translate an IPA to a PA for each of the stage 1 translation table lookups.
281
302
— For a stage 2 translation, translate an IPA to a PA for the stage 1 OA.</ code > </ pre > </ div >
282
- < p > TODO: stage 1 vs stage 2 </ p >
303
+ < p > < em > Why are we doing Stage 1? Not Stage 2? </ em > </ p >
283
304
< p > < img src ="https://lupyuen.org/images/unicorn3-stage.png " alt ="TODO " /> </ p >
284
305
< p > TODO: PTE_BLOCK_DESC_AP_USER=1</ p >
285
306
< div class ="example-wrap "> < pre class ="language-text "> < code > [7] AP[2] Stage 1 Indirect permissions are disabled.
@@ -302,7 +323,7 @@ <h1 id="map-virtual-address-to-physical-address"><a class="doc-anchor" href="#ma
302
323
< p > < img src ="https://lupyuen.org/images/unicorn3-table.png " alt ="TODO " /> </ p >
303
324
< p > TODO</ p >
304
325
< p > < img src ="https://lupyuen.org/images/unicorn3-access.png " alt ="TODO " /> </ p >
305
- < h1 id ="translation-control-register "> < a class ="doc-anchor " href ="#translation-control-register "> §</ a > 3 Translation Control Register</ h1 >
326
+ < h1 id ="translation-control-register "> < a class ="doc-anchor " href ="#translation-control-register "> §</ a > 4 Translation Control Register</ h1 >
306
327
< div class ="example-wrap "> < pre class ="rust rust-example-rendered "> < code > < span class ="comment "> // Initialize translation table control registers
307
328
</ span > ldr X0, =< span class ="number "> 0x180803F20
308
329
</ span > msr TCR_EL1, X0
@@ -358,7 +379,7 @@ <h1 id="translation-control-register"><a class="doc-anchor" href="#translation-c
358
379
</ span > ldr X0, =< span class ="number "> 0xFFFFFFFF
359
380
</ span > msr MAIR_EL1, X0</ code > </ pre > </ div >
360
381
< p > Hmmm it looks fake? Unicorn Emulator probably ignores the bits. We’ll see a Real MAIR in a while.</ p >
361
- < h1 id ="enable-the-mmu "> < a class ="doc-anchor " href ="#enable-the-mmu "> §</ a > 4 Enable the MMU</ h1 >
382
+ < h1 id ="enable-the-mmu "> < a class ="doc-anchor " href ="#enable-the-mmu "> §</ a > 5 Enable the MMU</ h1 >
362
383
< p > TODO</ p >
363
384
< p > < a href ="https://developer.arm.com/documentation/ddi0601/2024-12/AArch64-Registers/SCTLR-EL1--System-Control-Register--EL1- "> SCTLR_EL1, System Control Register (EL1)</ a > </ p >
364
385
@@ -389,13 +410,13 @@ <h1 id="enable-the-mmu"><a class="doc-anchor" href="#enable-the-mmu">§</a>4 Ena
389
410
</ ul >
390
411
< p > < em > What’s this EL1?</ em > </ p >
391
412
< p > EL0 then EL1. Show log</ p >
392
- < h1 id ="populate-the-ram "> < a class ="doc-anchor " href ="#populate-the-ram "> §</ a > 5 Populate the RAM</ h1 >
413
+ < h1 id ="populate-the-ram "> < a class ="doc-anchor " href ="#populate-the-ram "> §</ a > 6 Populate the RAM</ h1 >
393
414
< p > TODO</ p >
394
415
395
416
< div class ="example-wrap "> < pre class ="rust rust-example-rendered "> < code > < span class ="comment "> // Omitted: TODO
396
417
397
418
// Omitted: Enable the MMU</ span > </ code > </ pre > </ div >
398
- < h1 id ="nuttx-crashes-in-unicorn "> < a class ="doc-anchor " href ="#nuttx-crashes-in-unicorn "> §</ a > 6 NuttX crashes in Unicorn</ h1 >
419
+ < h1 id ="nuttx-crashes-in-unicorn "> < a class ="doc-anchor " href ="#nuttx-crashes-in-unicorn "> §</ a > 7 NuttX crashes in Unicorn</ h1 >
399
420
< p > < em > What’s Unicorn got to do with NuttX?</ em > </ p >
400
421
< p > TODO Years Ago: We tried creating a PinePhone Emulator with Unicorn. But it kept crashing while booting NuttX…</ p >
401
422
< p > TODO Years Later: The bug stops here!</ p >
@@ -475,7 +496,7 @@ <h1 id="nuttx-crashes-in-unicorn"><a class="doc-anchor" href="#nuttx-crashes-in-
475
496
Virtual Address: 0x5027_ffff (Why?)
476
497
Target Exception Level: 1</ code > </ pre > </ div >
477
498
< p > Which means: < a href ="https://github.com/lupyuen/pinephone-emulator?#arm64-mmu-exception "> < strong > “Oops! Can’t enable MMU”</ strong > </ a > </ p >
478
- < h1 id ="before-fixing-nuttx "> < a class ="doc-anchor " href ="#before-fixing-nuttx "> §</ a > 7 Before Fixing NuttX</ h1 >
499
+ < h1 id ="before-fixing-nuttx "> < a class ="doc-anchor " href ="#before-fixing-nuttx "> §</ a > 8 Before Fixing NuttX</ h1 >
479
500
< p > < em > How different is NuttX from MMU Demo?</ em > </ p >
480
501
< p > Before Fix: CONFIG_ARM64_VA_BITS=36</ p >
481
502
< p > < a href ="https://github.com/lupyuen2/wip-nuttx/blob/unicorn-qemu/arch/arm64/src/qemu/qemu_boot.c#L59-L89 "> qemu_boot.c</ a > </ p >
@@ -632,7 +653,7 @@ <h1 id="before-fixing-nuttx"><a class="doc-anchor" href="#before-fixing-nuttx">
632
653
Bit 13
633
654
Bit 23
634
655
Bit 31
635
- Bit 32</ code > </ pre > </ div > < h1 id ="nuttx-vs-mmu-demo "> < a class ="doc-anchor " href ="#nuttx-vs-mmu-demo "> §</ a > 8 NuttX vs MMU Demo</ h1 >
656
+ Bit 32</ code > </ pre > </ div > < h1 id ="nuttx-vs-mmu-demo "> < a class ="doc-anchor " href ="#nuttx-vs-mmu-demo "> §</ a > 9 NuttX vs MMU Demo</ h1 >
636
657
< ul >
637
658
< li > < strong > Bits 00-05:</ strong > T0SZ = 0x1C < br > < em > 36 bits of Virtual Address Space</ em > </ li >
638
659
</ ul >
@@ -656,7 +677,7 @@ <h1 id="before-fixing-nuttx"><a class="doc-anchor" href="#before-fixing-nuttx">
656
677
< ul >
657
678
< li > < strong > Bits 10-11:</ strong > ORGN0_WBNWA = 3 < br > < em > Normal memory, Outer Write-Back Read-Allocate No Write-Allocate Cacheable</ em > </ li >
658
679
</ ul >
659
- < h1 id ="after-fixing-nuttx "> < a class ="doc-anchor " href ="#after-fixing-nuttx "> §</ a > 9 After Fixing NuttX</ h1 >
680
+ < h1 id ="after-fixing-nuttx "> < a class ="doc-anchor " href ="#after-fixing-nuttx "> §</ a > 10 After Fixing NuttX</ h1 >
660
681
< p > Change 36 bits of Virtual Address Space to 32 bits:</ p >
661
682
< p > < a href ="https://github.com/apache/nuttx/commit/ce18a505fb295fc95167f505261f060c7601ce61 "> CONFIG_ARM64_VA_BITS=32</ a > </ p >
662
683
< p > boards/arm64/qemu/qemu-armv8a/configs/knsh/defconfig</ p >
@@ -693,9 +714,9 @@ <h1 id="after-fixing-nuttx"><a class="doc-anchor" href="#after-fixing-nuttx">§<
693
714
< p > Maybe Unicorn doesn’t support 36 bits</ p >
694
715
< p > Or maybe NuttX didn’t populate the Page Tables correctly for 36 bits? (Something about 0x5027ffff)</ p >
695
716
< p > Needs more investigation. But at least NuttX boots OK on Unicorn!</ p >
696
- < h1 id ="boot-flow "> < a class ="doc-anchor " href ="#boot-flow "> §</ a > 10 Boot Flow</ h1 >
717
+ < h1 id ="boot-flow "> < a class ="doc-anchor " href ="#boot-flow "> §</ a > 11 Boot Flow</ h1 >
697
718
< p > TODO</ p >
698
- < h1 id ="todo "> < a class ="doc-anchor " href ="#todo "> §</ a > 11 TODO</ h1 >
719
+ < h1 id ="todo "> < a class ="doc-anchor " href ="#todo "> §</ a > 12 TODO</ h1 >
699
720
< div class ="example-wrap "> < pre class ="rust rust-example-rendered "> < code > < span class ="comment "> // Read data from physical address
700
721
</ span > ldr X0, =< span class ="number "> 0x40000000
701
722
</ span > ldr X1, [X0]
@@ -722,7 +743,7 @@ <h1 id="todo"><a class="doc-anchor" href="#todo">§</a>11 TODO</h1>
722
743
< span class ="comment "> // Read the same memory area through virtual address
723
744
</ span > ldr X0, =< span class ="number "> 0x80000000
724
745
</ span > ldr X2, [X0]</ code > </ pre > </ div >
725
- < h1 id ="todo-1 "> < a class ="doc-anchor " href ="#todo-1 "> §</ a > 12 TODO</ h1 > < div class ="example-wrap "> < pre class ="language-bash "> < code > ## Level 1 Page Table with 4 Page Table Entries
746
+ < h1 id ="todo-1 "> < a class ="doc-anchor " href ="#todo-1 "> §</ a > 13 TODO</ h1 > < div class ="example-wrap "> < pre class ="language-bash "> < code > ## Level 1 Page Table with 4 Page Table Entries
726
747
## Entry #0
727
748
Page Table Entry @ 0x1000:
728
749
0x0000_0741
@@ -1270,7 +1291,7 @@ <h1 id="todo-1"><a class="doc-anchor" href="#todo-1">§</a>12 TODO</h1><div clas
1270
1291
call_graph: tasklist_initialize --> gic_validate_redist_version
1271
1292
call_graph: click tasklist_initialize href "https://github.com/apache/nuttx/blob/master/sched/init/nx_start.c#L313" "sched/init/nx_start.c " _blank
1272
1293
hook_block: address=0x40281514, size=32, arm64_syscall, arch/arm64/src/common/arm64_syscall.c:299:32
1273
- call_graph: gic_validate_redist_version --> arm64_syscall</ code > </ pre > </ div > < h1 id ="whats-next "> < a class ="doc-anchor " href ="#whats-next "> §</ a > 13 What’s Next</ h1 >
1294
+ call_graph: gic_validate_redist_version --> arm64_syscall</ code > </ pre > </ div > < h1 id ="whats-next "> < a class ="doc-anchor " href ="#whats-next "> §</ a > 14 What’s Next</ h1 >
1274
1295
< p > Special Thanks to < a href ="https://lupyuen.org/articles/sponsor "> < strong > My Sponsors</ strong > </ a > for supporting my writing. Your support means so much to me 🙏</ p >
1275
1296
< ul >
1276
1297
< li >
@@ -1300,7 +1321,7 @@ <h1 id="todo-1"><a class="doc-anchor" href="#todo-1">§</a>12 TODO</h1><div clas
1300
1321
</ ul >
1301
1322
< p > < em > Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…</ em > </ p >
1302
1323
< p > < a href ="https://codeberg.org/lupyuen/lupyuen.org/src/branch/master/src/unicorn3.md "> < strong > lupyuen.org/src/unicorn3.md</ strong > </ a > </ p >
1303
- < h1 id ="appendix-simplified-nuttx-for-qemu "> < a class ="doc-anchor " href ="#appendix-simplified-nuttx-for-qemu "> §</ a > 14 Appendix: Simplified NuttX for QEMU</ h1 >
1324
+ < h1 id ="appendix-simplified-nuttx-for-qemu "> < a class ="doc-anchor " href ="#appendix-simplified-nuttx-for-qemu "> §</ a > 15 Appendix: Simplified NuttX for QEMU</ h1 >
1304
1325
< p > TODO: Simpler for debugging</ p >
1305
1326
< p > (Could one of these changes, contribute to Unicorn Non-Crashing? It’s possible)</ p >
1306
1327
< p > Why did we simplify? So we can be as close to MMU Demo as possible. And isolate the crashing problem.</ p >
0 commit comments