Tételezzük fel, hogy egy kollégánk átad egy .bin
firmware-t, és azt kérdezi: „Ez most miért nem indul el a QEMU-ban,
amikor a main()-ben már csak egy LED-villogtatás van?” A
hibakeresés kulcsa ilyenkor nem a C-forrásban, hanem a futási
modell ismeretében van: hol keresi a processzor az első
utasítást, honnan tölti be a veremmutatót, milyen címen éri el az első
periféria-regisztert, és melyik címtartomány mit jelent egy
linker script-ben. A Cortex-M világában ezek nem
operációsrendszer-konfiguráció kérdései: rögzített,
architektúra-szintű címek, amelyeket a linker script és a
startup kód együtt „töltenek fel” tartalommal.
Ez az alfejezet a Cortex-M3-as futási modell alapját adja meg:
megrajzoljuk a memóriatérképet, levezetjük a régiók méretét, majd nyomon
követjük, mi történik közvetlenül a reset után, mielőtt
bármilyen main() futna. Az AArch64 Linuxos
világából érkező olvasó számára a legnagyobb váltás: nincs MMU, nincs
virtuális cím, nincs _start libc-ről; a memória fizikai,
fix, és a linker script dönti el, mi hova kerül.
Az Armv7-M architektúra (amelybe a Cortex-M3 tartozik) egy fix, 4 GB-os fizikai címtér-et definiál, nyolc darab 512 MB-os régióra osztva. Nem opcionális: ezek a címtartományok a specifikáció részei, és a mag viselkedése (pl. milyen bitet lehet gyorsítótárazni, milyen utasítás engedélyezett) ettől függ.
| Régió | Kezdőcím | Végcím | Méret | Tipikus tartalom |
|---|---|---|---|---|
| Code | 0x00000000 |
0x1FFFFFFF |
512 MB | Flash / ROM, vektorok, konstans adat |
| SRAM | 0x20000000 |
0x3FFFFFFF |
512 MB | statikus változók, .data, .bss, verem,
halom |
| Peripheral | 0x40000000 |
0x5FFFFFFF |
512 MB | memory-mapped I/O (UART, GPIO, timer) |
| External RAM | 0x60000000 |
0x9FFFFFFF |
1 GB | külső memória (opcionális) |
| External device | 0xA0000000 |
0xDFFFFFFF |
1 GB | külső periféria (opcionális) |
| System: Private Peripheral Bus (PPB) | 0xE0000000 |
0xE00FFFFF |
1 MB | SCS (SCB, SysTick, NVIC, MPU), ITM, DWT, FPB |
| System: vendor system | 0xE0100000 |
0xFFFFFFFF |
511 MB | gyártóspecifikus |
A sorok hézag és átfedés nélkül fedik a teljes 4 GB-ot: minden
kezdőcím az előző sor végcíme + 1, az utolsó végcím
0xFFFFFFFF, és a méret mindig végcím − kezdőcím + 1. A két
külső tartomány egyenként 1 GB, vagyis két-két 512 MB-os egység; a
0xE0000000-tól kezdődő utolsó 512 MB-os egységet (System)
az architektúra tovább bontja PPB-re és gyártói részre.
A táblázat fogalmi jelentése: a 32 bites cím felső 3 bitje
dönti el, melyik 512 MB-os egységbe esik (a két 1 GB-os külső
tartomány két-két egységből áll, a 0xE0000000-s System
egységet pedig az architektúra tovább bontja). A régiók méretét
a mag nem korlátozza — egy adott chipen belül csak egy töredékük van
„kitöltve” memóriával; a lyukakra írás BusFault-ot vált ki
(azaz a mag fault kivételt dob, nem csendben eldobja az írást).
Definíció (memóriatérkép). A memory map az a hivatalos hozzárendelés, amely a 32 bites címtér szeleteit funkciókhoz (kód, RAM, periféria, mag-belső regiszterek) rendeli, és amelyet a mag és a linker script egyaránt ismer.
Definíció (bare-metal futási modell). Bare-metal (csupasz fém) futás alatt azt értjük, hogy a mag közvetlenül a reset-vektorról indul, nincs operációs rendszer, nincs dinamikus betöltő, minden címet (kód, verem, periféria) a fejlesztő által adott linker script és startup kód rendez el.
A 32 bites címtér bájt = 4 GB. Ha nyolc egyenlő részre osztjuk:
Ezért a régiók felső 3 bit alapján szelektálhatók.
Az Address bitjei A[31:29] a régióindex; az alsó 29 bit a
régión belüli eltolás. Például:
0x00000000 → A[31:29] = 0b000 → Code.0x20000000 → A[31:29] = 0b001 → SRAM.0x40000000 → A[31:29] = 0b010 →
Peripheral.0xE0000000 → A[31:29] = 0b111 → System
(ezt az egységet az architektúra tovább bontja).A cím értelmezése tehát két külön lépés: előbb a régió azonosítása, aztán a régión belüli dekódolás.
A[31:29] kiválasztja
az 512 MB-os egységet. A System egységen belül
A[31:20] = 0xE00 jelöli az 1 MB-os PPB-t
(0xE0000000–0xE00FFFFF), minden más
(0xE0100000–0xFFFFFFFF) gyártói terület.A[31:20] = 0xE00), ezért ezek a
bitek az egyes eszközöket nem különítik el. Az eszközt
az alacsonyabb bitek választják ki: A[19:12] a 4 KiB-os
blokkot (például 0x0E a System Control Space, SCS:
0xE000E000–0xE000EFFF), azon belül
A[11:0] a regisztert.Kidolgozott dekódolás: 0xE000E100.
| Lépés | Bitek | Érték | Jelentés |
|---|---|---|---|
| régió | A[31:29] |
0b111 |
System egység |
| PPB-e? | A[31:20] |
0xE00 |
igen, PPB |
| blokk a PPB-n belül | A[19:12] |
0x0E |
SCS (0xE000E000–0xE000EFFF) |
| regiszter az SCS-ben | A[11:0] |
0x100 |
NVIC ISER0 (az NVIC 0xE000E100-tól
kezdődik) |
Ugyanígy 0xE000E010 az SCS-en belül a 0x010
eltolás, a SysTick vezérlőregisztere (SYST_CSR, a SysTick
blokk 0xE000E010–0xE000E01F). A
0xE000E010 és a 0xE000E100 tehát
A[31:12]-ben megegyezik, és csak az SCS-en belüli
eltolásban különbözik.
Code régió (0x00000000–). Ezen a címen
található a vektortábla első szava (kezdeti SP), majd a
második szava (reset-vektor), utána a többi kivétel belépési címe. Ezt
követi a tényleges programkód (.text) és a konstans
inicializált adatok (.rodata). Fizikailag ez lehet
beágyazott Flash, vagy — QEMU-ban — egyszerű RAM, amit „ROM-ként”
használunk. Fontos: a vektortáblának a régió kezdetén kell
lennie (alapértelmezésben 0x00000000), mert a mag
reset után ezt a címet használja; később a VTOR (Vector Table Offset
Register) átírásával elmozdítható, ezzel a következő alfejezetekben még
foglalkozunk.
SRAM régió (0x20000000–). Itt él a
statikus adat (.data), a nulla-kezdőértékű
(.bss), a verem (stack) és a halom (heap). A verem
a legmagasabb címről lefelé nő (a PUSH a
SP-t csökkenti ARM-en). A .data szakasz
tartalma a Flash-ből másolódik át a startup kódban (lásd
[a066](a066.html)), mert a Flash nem írható futás
közben.
Periféria régió (0x40000000–). Itt
helyezkednek el a Memory-mapped I/O regiszterek. A mag
ugyanazokkal a LDR/STR utasításokkal éri el
őket, mint a RAM-ot; a különbség az, hogy az írás/olvasás itt hardveres
mellékhatást vált ki (UART-ba küld, GPIO-t billent, időzítőt indít). A
pontos címek és bitmezők gyártó- és táblaspecifikusak; a részletes
kezelés a [ach17](index.html#ach17) fejezetben következik.
Most csak annyi a fontos: a 0x40000000-s régióban
nem szabad „véletlen” programadatot elhelyezni.
PPB
(0xE0000000–0xE00FFFFF). A mag belső
perifériái: NVIC, SysTick, SCB, MPU, hibaregiszterek. Ide írva
konfiguráljuk a megszakításokat ([ach16](index.html#ach16))
és a rendszerszintű viselkedést.
Amikor a mag feszültség alá kerül (vagy a
qemu-system-arm elindul), a hardver a reset-szekvenciát
hajtja végre. A Reset a vektortáblában az 1-es
vektorszámot kapja (a második szó), de a reset
nem szokásos kivételbelépés: nincs veremre mentett
keret, nincs EXC_RETURN, és a mag nem Handler módba lép. A
szekvencia az architektúrában rögzített, operációs rendszertől
függetlenül:
0x00000000 címen lévő 32 bites szót, és beírja a fő
veremmutatóba (MSP, az R13 reset utáni nézete). Ez a
kezdeti veremmutató, tipikusan az SRAM legfelső
címe.0x00000004 címen lévő szó a reset-vektor.
A bit0-ja nem a cím része: az EPSR.T bitbe kerül, és 1-nek
kell lennie, mert a Cortex-M csak Thumb állapotot ismer. A
PC-be a bit0 nélküli érték kerül, ez a reset-handler első
utasításának (páros) címe. A vektor tehát például
0x00000041, a végrehajtás pedig a
0x00000040-en kezdődik. Ha a vektor bit0-ja 0, az első
utasítás INVSTATE UsageFaultot okoz, ami HardFaulttá
eszkalálódik.LR (R14)
0xFFFFFFFF-re áll; ez azt jelzi, hogy nincs visszatérési
cím (a BX LR itt fault-ot okoz, ami néha hasznos a „nem
szabadna ide visszatérni” jelzésre).CONTROL.nPRIV = 0,
CONTROL.SPSEL = 0), és az IPSR (Interrupt
Program Status Register) értéke 0. Az IPSR az
aktív kivétel számát mutatja Handler módban, Thread módban
pedig 0-t. A „vektorszám 1” és az „aktív kivételszám 0” tehát nem
ellentmondás: a reset-handler Thread módban fut, nem egy aktív
Reset-kivétel kezelőjeként.Ezek után a CPU már a saját reset-handlerünk első utasításánál tart,
a main() fogalmilag még nem létezik — a
reset-handler az, ami majd meghívja.
A mechanizmus kulcsa: a mag nem tudja, hogy az
[SP] és [PC] érték honnan „származik”; csak
azt tudja, hogy a 0-s címen lévő szavak tartalmát tölti be. Ezért a
linkelési folyamatnak gondoskodnia kell arról, hogy a
.vectors szekció pontosan a 0-s címre
kerüljön, benne a helyes kezdeti SP-vel és reset-vektorral.
A reset utáni állapot a reset-handler első utasítása
előtt GDB-vel ellenőrizhető. A -S kapcsolóval
indított QEMU a resetet már elvégezte, de még egyetlen utasítást sem
hajtott végre:
qemu-system-arm -machine mps2-an385 -cpu cortex-m3 -kernel lab-a063.elf \
-S -gdb tcp::3333 -nographic # egyik terminál
gdb-multiarch lab-a063.elf -ex "target remote :3333" # másik terminál(gdb) x/2xw 0 # vektor[0] = kezdeti SP, vektor[1] = reset-vektor (bit0 = 1)
(gdb) p/x $sp # = vektor[0]
(gdb) p/x $pc # = vektor[1] & ~1 (páros cím), a Reset_Handler első utasítása
(gdb) p/x $xpsr & 0x1ff # IPSR = 0: Thread mód
(gdb) p/x ($xpsr >> 24) & 1 # EPSR.T = 1
(gdb) p/x $lr # 0xffffffff
(gdb) p/x $control # 0: privilegizált, MSP (ha a QEMU/GDB kiteszi ezt a regisztert)
Az ellenőrzés lényege a vektor és a végrehajtási cím különbsége: a
x/2xw 0 második szava páratlan, a $pc ugyanez
bit0 nélkül.
mps2-an385 memóriatérképeA könyv II. részének QEMU-baseline-ja az ARM MPS2+ AN385
tábla, Cortex-M3 maggal. A dokumentáció szerinti fő tartományok (a
pontos címeket és bitmezőket a QEMU hivatalos machine-definíciója és a
CMSDK periféria-dokumentáció alapján ellenőrizni
szükséges a generálás időpontjában; az alábbi értékek a QEMU
hw/arm/mps2.c forrásában és a hivatalos MPS2+
dokumentációban szereplő baseline-t tükrözik):
| Címtartomány | Méret | Szerep |
|---|---|---|
0x00000000–0x003FFFFF |
4 MiB | ZBT SSRAM1 — Code (vektortábla, kód, .rodata);
a linker scriptben FLASH néven |
0x20000000–0x203FFFFF |
4 MiB | ZBT SSRAM 2 & 3 együtt — SRAM
(.data, .bss, stack); ez az egyetlen kanonikus
RAM-tartomány |
0x20400000–0x207FFFFF |
(4 MiB) | az előző sor tükre (alias): ugyanaz a fizikai tár, nem második blokk |
0x40000000– |
— | CMSDK APB periféria-sáv kezdete (UART, timer, dual-timer,
FPGAIO, SCC, GPIO) |
0xE0000000–0xE00FFFFF |
1 MiB | PPB: SCS (SCB, SysTick, NVIC) |
A QEMU 8.2.2 hw/arm/mps2.c forrása szerint az AN385-ön a
0x20000000–0x203fffff tartomány az SSRAM 2 és
3 együttese, a 0x20400000–0x207fffff pedig
ennek tükre. Aki a tükröt külön tárolóként számolja (például oda teszi a
vermet, a .data-t pedig az alsó tartományba), a program
saját adatait írja felül egy másik címen keresztül: a
0x20400000 + x és a 0x20000000 + x ugyanaz a
bájt. A könyv linker scriptjei ezért csak a 0x20000000-tól
induló 4 MiB-ot használják.
A linker scriptek FLASH nevű régiója itt egy
betöltött SRAM-ra adott név, nem fizikai
flash-tulajdonság: a QEMU az ELF-et ide tölti, és a tartalom futás
közben akár írható is. A név a valódi mikrokontrollerek szokását követi,
ahol ugyanez a szerep valódi flashre esik; a „flash nem írható” jellegű
állítások a QEMU-gépre nem érvényesek.
A konkrét 0x40000000-ás periféria-offsetek (melyik UART
hol van, hol a timer) a [ach17](index.html#ach17)
fejezetben és a XVII. fejezet laborjaiban lesznek tételesen bevezetve.
Itt csak annyit szögezzünk le: amit a linker script
MEMORY blokkja megad, annak egyeznie kell a QEMU machine
tényleges térképével — különben a firmware betöltődik ugyan, de
a Python __main vagy a verem az első PUSH-nál
BusFault-ot okoz.
Megjegyzés. A fenti 4 MiB-os ZBT SSRAM értékek a szimulált QEMU-memóriamodellek méretei. A fizikai MPS2+ táblán a tényleges SSRAM ennél nagyobb is lehet; natív hardveren a linker script által kijelölt régiók a tábla CMSIS-fájljából (device header) származnak, nem a QEMU-ból.
Munkakönyvtár: ~/arm-labor/cm/a063/ —
az alfejezet minden laborfájlja ide kerül, és minden parancs innen
futtatandó (a könyvtárrendet a Labor-alapkörnyezet alfejezet írja le).
mkdir -p ~/arm-labor/cm/a063
cd ~/arm-labor/cm/a063Az alábbi GNU assembler forrás egy minimális, de
teljes vektortáblát mutat, amely pontosan azt kódolja, amiről
az előbb szó volt. A feltételezett címtér: 4 MB Code
0x00000000-tól, 4 MB SRAM 0x20000000-tól.
/* lab-a063-vectors.s: minimális vektortábla Cortex-M3-hoz */
.syntax unified
.cpu cortex-m3
.thumb
.section .vectors, "a", %progbits
.word 0x20010000 /* [0x00] kezdeti SP: a verem teteje az SRAM-ban */
.word Reset_Handler /* [0x04] reset-vektor (a .thumb_func miatt bit0 = 1) */
/* [0x08] NMI, [0x0C] HardFault, ... itt kihagyva a rövidség kedvéért */
.section .text
.thumb_func
.global Reset_Handler
Reset_Handler:
/* Itt még nincs C-runtime. Legalább egy végtelen ciklus kell. */
ldr r0, =0x20000000
1: b 1b /* végtelen ciklus, önmagára ugrik */
A hozzá tartozó linker script-részlet a MEMORY régiókat
a fenti térképhez köti:
/* lab-a063.ld: memóriatérkép MPS2-AN385-höz */
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 4M
SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 4M
}
SECTIONS
{
.vectors : { KEEP(*(.vectors)) } > FLASH
.text : { *(.text*) } > FLASH
}
A vektortábla és a reset-handler itt a II. rész kanonikus neveit
használja (.vectors, Reset_Handler); a teljes,
közös startup/linker párt a Linker script
alapjai és a Startup kód alfejezet adja.
Várható regiszterállapot a Reset_Handler első
utasítása előtt (levezetett, a fenti GDB-lépésekkel
ellenőrizendő):
| Regiszter | Érték | Miért |
|---|---|---|
SP (R13, MSP) |
0x20010000 |
a [0x00000000] szó betöltve |
[0x00000004] (reset-vektor) |
Reset_Handler címe, bit0 = 1 |
a .thumb_func miatt páratlan |
PC (R15) |
a reset-vektor bit0 nélkül (páros) | a végrehajtás címe |
LR (R14) |
0xFFFFFFFF |
reset szekvencia |
EPSR.T |
1 |
a reset-vektor bit0-jából |
IPSR |
0 |
Thread mód, nincs aktív kivétel |
CONTROL |
0 |
privilegizált, MSP |
A futtatás QEMU-ban (qemu-system-arm) tipikusan úgy
indul, hogy a -kernel opcióként átadott ELF-ből a QEMU
kiolvassa a belépési pontot, és a 0-s címen elhelyezi a tartalmat.
A várt viselkedés illusztratív: tényleges
regiszterértékek helyes ellenőrzése a laborban GDB-vel
(info registers) történik. Ezt a
[a067](a067.html) alfejezet részletesen tárgyalja.
„A firmware elindul, de azonnal HardFault-ba
esik.” Gyakori ok: a vektortábla nincs a 0-s címen, vagy a
linker script másik szekciót tett oda előbb. Ellenőrzés:
arm-none-eabi-objdump -h lab-a063.elf — a
.vectors szekció VMA-ja legyen
0x00000000. Ha nem, a SECTIONS sorrendet vagy
a KEEP-et kell módosítani.
„A PUSH utasítás BusFault-ot okoz.”
A kezdeti SP rossz helyre mutat — tipikusan az SRAM-on kívülre, például
egy nem inicializált vagy rossz méretű régióba. Ellenőrzés: a
[0x00000000] szó (objdump -s -j .vectors),
illetve a linker script LENGTH értéke.
„A QEMU elfogadja a binárist, de natív MPS2+-on nem indul.” A QEMU-memóriamodell és a fizikai tábla memóriatérképe eltérhet (pl. SSRAM méret). Az ilyen eltéréseket külön kell jelölni; a QEMU-eredmény nem helyettesíti a fizikai validálást.
Az ellenpróba minden esetben ugyanaz: gyanú → adatgyűjtés
(objdump -h, objdump -s, GDB
info registers) → egyetlen változtatás → újrafuttatás.
1. feladat (magyarázó). Egy kolléga ezt a
MEMORY definíciót adta:
FLASH (rx) : ORIGIN = 0x20000000, LENGTH = 1M. Magyarázd
el, mi a hiba, és mi fog történni a reset után.
2. feladat (implementációs). Módosítsd a fenti
lab-a063-vectors.s vektortáblát úgy, hogy a verem a 4
MiB-os kanonikus SRAM-tartomány
(0x20000000–0x203FFFFF) tetejéről induljon, 8
bájtra igazítva. Írd le, melyik szót kell megváltoztatni, miért marad
érvényben a vektorok sorrendje, és miért nem szabad a
0x20400000-tól kezdődő területet második veremblokkként
használni.
3. feladat (hibakeresés/mérés). A firmware-ed
qemu-system-arm -machine mps2-an385 alatt elindul, de
azonnal HardFault-ba esik. Írj egy lépéslistát, amivel
gdb-multiarch + objdump -h segítségével
eldöntöd, hogy a vektortábla rossz helyen van-e, vagy a kezdeti SP
értéke rossz.
1. megoldás. A 0x20000000 az
SRAM régió kezdete, nem a Code régió. A reset
szekvencia a 0x00000000-s címről olvassa az SP-t és a PC-t,
nem a 0x20000000-ról. Következmény: a mag a 0-s címen lévő
(esetleg törölt vagy véletlen) szavakat tölti be; tipikusan
HardFault vagy UsageFault az első utasításnál,
mielőtt bármit is kiírna. Javítás: ORIGIN = 0x00000000.
2. megoldás. Csak az első .word sor
értékét kell módosítani: 0x20000000 + 4 MiB = 0x20400000.
Ez a tartomány utáni első cím (kizárólagos felső határ), és ez a helyes
kezdeti SP. A Cortex-M verme „full descending”: a PUSH
előbb csökkenti az SP-t, és csak utána ír, ezért az első mentett szó a
0x203FFFFC-re kerül, ami még a tartományon belül van. A
0x20400000 8-cal (sőt 16-tal) osztható, így teljesül az
AAPCS 8 bájtos veremigazítási szabálya a nyilvános interfészeken. A
vektorok sorrendje változatlan marad, csak az SP szó értéke változik. A
0x20400000–0x207FFFFF terület nem második
blokk, hanem az alsó 4 MiB tükre: egy oda tett verem a
.data/.bss bájtjait írná felül egy másik címen
keresztül.
3. megoldás. Lépések: (a)
arm-none-eabi-objdump -h build/lab-a063.elf — nézd meg a
.vectors VMA-ját; ha nem 0x00000000, a linker
script a hibás. (b) objdump -s -j .vectors — az első szó
legyen érvényes SRAM-cím (0x20xxxxxx), a második a
Reset_Handler címe, páratlanul. (c)
gdb-multiarch + target remote :3333 (a QEMU-t
-S -gdb tcp::3333-mal indítva) — a reset utáni, első
utasítás előtti állapot a fenti GDB-lépésekkel: ha SP és
PC a vektortáblából várt értéktől eltér, akkor vagy a
betöltés rossz (QEMU -kernel
vs. -device loader), vagy a szekció rossz helyen van. Ha
PC jó, de máshol faultol, akkor az SRAM mérete/igazítása a
gyanús.
A Cortex-M3 fix, architektúra-szintű memóriatérképet használ:
0x00000000-tól a Code régió, 0x20000000-tól az
SRAM, 0x40000000-tól a periféria,
0xE0000000-tól a mag belső perifériái (PPB). A régiókat a
cím felső 3 bitje választja el, egyenként 512 MB-os tartományban. Reset
után a mag az első szót az MSP-be tölti, a második szó bit0-ját az
EPSR.T-be, a bit0 nélküli értékét a PC-be, LR-t
0xFFFFFFFF-re állítja, és privilegizált Thread módban,
IPSR = 0 mellett indul; a main() csak ezután,
a reset-handler által hívva jelenik meg. QEMU mps2-an385
alatt a 4 MiB Code (FLASH nevű, de betöltött SSRAM) / 4 MiB
kanonikus SRAM (0x20400000-tól tükör) /
0x40000000-ás periféria-baseline az irányadó, de a konkrét
periféria-offseteket és a QEMU-machine verzióját a generálás idején
ellenőrizni szükséges.
Továbbhasznált definíciók: - memóriatérkép
(memory map): a 32 bites címtér hivatalos felosztása funkciók
(Code/SRAM/Peripheral/PPB) szerint. - reset-vektor: a
0x00000004 címen lévő szó, amely a reset-handler belépési
címét tartalmazza. - bare-metal futási modell: nincs
operációs rendszer; a linker script és a startup kód rendezi el a címtér
használatát.
Az alábbiak dokumentációs kiindulópontok (forrásállapot: nem megnyitott, lásd az Olvasói útmutató jelöléseit):
mps2-an385 machine-definíció; a
konkrét periféria-címek forrása.as dokumentáció — a .section,
.word, .thumb_func direktívák
szemantikája.hw/arm/mps2.c (8.2.2) — az AN385
memóriaelrendezése, köztük az SSRAM 2&3 és tükre.Ellenőrzési hiányok (jelölve): - Az
mps2-an385 konkrét periféria-offsetjei (melyik UART hol,
FPGAIO/SCC/GPIO pontos címe) a
generálás idején ellenőrizendők a QEMU
hw/arm/mps2.c forrása és a hivatalos MPS2+ dokumentáció
alapján. A QEMU-machine definíció verzióról verzióra változhat. - Az
SRAM-tükör (0x20400000–0x207FFFFF = a
0x20000000–0x203FFFFF aliasa) a lektor által a
QEMU 8.2.2 hw/arm/mps2.c forrásában ellenőrzött állapot;
más QEMU-verzióban a monitor info mtree parancsával
erősítendő meg. - A reset szekvencia lépései (MSP, PC és T-bit a
reset-vektorból, LR, privilegizált Thread mód, IPSR = 0) az
Armv7-M ARM-ben rögzítettek (a Cortex-M3 útmutató is Thread módot ír). A
közölt GDB-lépéseket ebben a munkafolyamatban nem futtattuk QEMU alatt;
a $control regiszter elérhetősége QEMU- és GDB-verziófüggő.
A vektortábla-tulajdonságokat (bit0 = 1, páros végrehajtási cím) a
helyettesítő eszközlánccal épített ELF-en ellenőriztük.