Egy assemblyben megírt függvény QEMU alatt helyesen számol. Következik ebből, hogy Raspberry Pi-n is gyors lesz? Nem: az utasítások jelentése és végrehajtásuk költsége két külön kérdés. A fizikai gép akkor ad többletinformációt, amikor már nemcsak a helyességet, hanem a cache, az elágazásbecslés, az órajel vagy az operációs rendszer ütemezésének hatását vizsgáljuk.
Natív végrehajtásnak (native execution) nevezzük, amikor a program gépi utasításait közvetlenül a célarchitektúrát megvalósító processzor hajtja végre, nem pedig egy másik program emulálja őket. Ebben az alfejezetben ez A64 utasításokat végrehajtó Raspberry Pi 4 vagy 5 gépet jelent, 64 bites Linux-felhasználói környezettel.
A fizikai gép opcionális kiegészítés. A kötelező út
továbbra is az Ubuntu 24.04 x86_64 hoston futó
qemu-aarch64. Az Assemble-link-run
munkafolyamat natív és cross környezetben lépéseire építünk;
bare-metal indítással, GPIO-val és perifériacímekkel itt nem
foglalkozunk.
A processzor 64 bites képessége önmagában nem elegendő. A kernel, a felhasználói környezet és az elkészített végrehajtható állomány architektúráját külön kell ellenőrizni.
Az opcionális telepítés javasolt menete:
lab-rpi, valamint
egyedi adminisztrációs fiókot, például lab-admin. Ne
támaszkodj történeti alapértelmezett felhasználónévre vagy
jelszóra.A telepítő menüpontjai és az egyes rendszerképek aktuális modelltámogatása változhat. Ezeket a tényleges telepítéskor a hivatalos dokumentáció alapján kell ellenőrizni; itt nincs aktuálisan ellenőrzött kiadásmegjelölés.
Célkörnyezet: natív Raspberry Pi, rendszerazonosítás.
uname -m
getconf LONG_BIT
dpkg --print-architecture
cat /etc/os-releaseA kívánt, várt első három eredmény rendre
aarch64, 64, illetve arm64. Ezek
külön nézetek:
| Ellenőrzés | Mit jellemez? |
|---|---|
uname -m |
A futó kernel által jelentett géparchitektúrát |
getconf LONG_BIT |
A parancs futási környezetében a C long típus
bitszélességét |
dpkg --print-architecture |
A csomagrendszer alapértelmezett architektúráját |
A 64 bites kernel mellett létezhet 32 bites felhasználói környezet
is. Ezért a uname -m önmagában nem igazolja a könyv natív
laborprofilját. Eltérés esetén előbb a környezetet tisztázd, ne az
assemblyforrást módosítsd.
A biztonságos távoli parancssor, a Secure Shell (SSH) kényelmessé teszi a fizikai gép használatát, de hálózati hozzáférési pontot is létrehoz.
Két szerepet válassz szét:
lab-admin fiók kizárólag telepítéshez és
karbantartáshoz kapjon sudo-jogot.lab-user fiók futtassa a laborprogramokat,
adminisztrációs és közvetlen eszközhozzáférési jogosultság nélkül.A lab-user ne kerüljön például sudo,
gpio vagy docker csoportba. Az utóbbi tagság
különösen nem tekinthető ártalmatlan kényelmi beállításnak.
Az adminisztrátor létrehozhatja a laborfiókot, majd telepítheti annak
saját nyilvános SSH-kulcsát. A privát kulcs maradjon a fejlesztői
hoston. A célfiók .ssh könyvtárának tulajdonosa a célfiók
legyen, jogosultsága 700; az authorized_keys
fájlé 600. Kulcsos belépés ellenőrzése után a jelszavas
SSH-belépés kikapcsolható, de a helyi helyreállítási lehetőséget őrizd
meg.
Célkörnyezet: natív Raspberry Pi, egyszeri adminisztráció.
sudo adduser lab-user
sudo apt update
sudo apt install binutils fileSiker esetén a parancsok kilépési állapota 0. A
csomagtelepítéshez kell emelt jogosultság; a későbbi fordításhoz és
futtatáshoz nem.
A gépazonosító kulcs ujjlenyomatát első kapcsolódáskor megbízható csatornán, például a Pi helyi konzolján ellenőrizd.
Célkörnyezet: natív Raspberry Pi, helyi konzol.
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubEz a parancs a meglévő nyilvános hostkulcs ujjlenyomatát mutatja; nem generál új kulcsot.
Kapcsolódás: Ubuntu fejlesztői host → natív Raspberry Pi.
ssh lab-user@lab-rpi.localA lab-rpi.local csak akkor használható, ha a helyi
hálózaton működik az ehhez szükséges névfeloldás. Máskülönben a saját,
ellenőrzött gépnevedet használd. Ne kapcsold ki automatikusan a
hostkulcs-ellenőrzést, és a labor kedvéért ne állíts be internet felőli
porttovábbítást.
A következő összevetés az A64 ISA, ARMv8-A alapprofil, little-endian Linux környezetére vonatkozik.
| Szempont | qemu-aarch64, user-mode |
Natív Raspberry Pi |
|---|---|---|
| A64 utasítások jelentése | Az emulátor megvalósítása és CPU-beállítása szerint | A fizikai processzor megvalósítása szerint |
| Linux-rendszerhívások | A QEMU a host operációs rendszer szolgáltatásaihoz közvetít | Közvetlenül a Pi Linux kerneléhez kerülnek |
| Cache és elágazásbecslés | Nem a Pi mikroarchitektúrájának időzítéshű modellje | A tényleges processzor viselkedése érvényesül |
| Futási idő | Az emuláció és az x86_64 host terhelése is alakítja | A Pi terhelése, órajele, hőállapota is alakítja |
| Opcionális ISA-bővítések | A választott emulált CPU-tól függnek | A konkrét processzortól függnek |
A funkcionális helyesség (functional correctness) azt jelenti, hogy a megadott bemenetre a szerződés szerinti eredmény és megengedett mellékhatás keletkezik. Ez nem azonos a teljesítménnyel.
A könyv alapprofiljába tartozó egész aritmetikai utasítások eredményének egyeznie kell. Ebből nem következik azonos futási idő. A QEMU user-mode ráadásul nem teljes Raspberry Pi gépet emulál: nem ad Pi-specifikus perifériakörnyezetet, és nem indít külön vendégkernelt.
A mérnöki feladat most egyszerű: igazoljuk, hogy ugyanaz a könyvtárfüggetlen AArch64 ELF mindkét környezetben ugyanazzal az eredménnyel fejeződik be.
A program 40 + 2 értékét kilépési állapotként adja
vissza. A 42 tehát szándékos eredmény, nem önmagában
hibajelzés. Nincs fájlművelet, hálózati hozzáférés, adatmemória-írás
vagy ciklus.
Buildkörnyezet: Ubuntu x86_64, cross-toolchain; első futtatási cél: qemu-user.
mkdir -p ~/arm-labor/a64/a008
cd ~/arm-labor/a64/a008Mentsd a következő forrást lab-pi.s néven.
A64 ISA, ARMv8-A; GNU assembler-direktívák AArch64 ELF-célhoz.
.text
.p2align 2
.global _start
.type _start, %function
_start:
movz w0, #40
add w0, w0, #2
movz x8, #93
svc #0
.size _start, . - _start
.section .note.GNU-stack,"",%progbitsAz A64 W0 a megfelelő általános célú regiszter 32 bites
nézete. A beleírás az A64 X0 felső 32 bitjét nullázza. Az
összeadás eredménye itt előjel nélküli olvasatban 42.
Az AArch64 Linux rendszerhívási megállapodása szerint az A64
X8 tartalmazza a hívásszámot; a 93 az
exit. Első argumentuma az A64 X0, itt a
kilépési állapot. Ez Linux-szabály, nem az A64 ISA általános
tulajdonsága; részletesen a Linux syscall-konvenció
AArch64-en tárgyalja.
Az alkalmazott konstansok kódolhatók:
| A64 utasításforma | Immediate-korlát |
|---|---|
MOVZ W0, #40 |
16 bites mező; a 32 bites változatban az eltolás 0 vagy
16 |
ADD W0, W0, #2 |
12 bites előjel nélküli mező, opcionális 12 bites balra
tolással |
MOVZ X8, #93 |
16 bites mező; a 64 bites változatban az eltolás 0,
16, 32 vagy 48 |
SVC #0 |
16 bites immediate; itt nem ez hordozza a Linux-hívásszámot |
Az elhagyott eltolás mindkét MOVZ és az ADD
esetén 0.
Build és futtatás: Ubuntu cross-toolchain → qemu-user, little-endian cél.
aarch64-linux-gnu-as -EL -march=armv8-a \
-o lab-pi.o lab-pi.s
aarch64-linux-gnu-ld -EL -static -e _start -z noexecstack \
-o lab-pi-a64 lab-pi.o
aarch64-linux-gnu-readelf -h lab-pi-a64
qemu-aarch64 ./lab-pi-a64
lab_status=$?
printf 'qemu-user: exit=%s\n' "$lab_status"
test "$lab_status" -eq 42A readelf fejlécében várt az
ELF64, az AArch64 géptípus és a little-endian
adatjelölés. A futtatás után várt sor:
qemu-user: exit=42. A végső test sikeres
ellenőrzéskor 0 állapottal tér vissza.
A parancssort ne olyan set -e beállítású scriptből
futtasd, amely a szándékos 42 miatt az ellenőrzés előtt
megszakad.
Most ugyanazt az ELF-et és a forrást másoljuk át.
Átvitel: Ubuntu host → natív Raspberry Pi; munkakönyvtár
mindkét gépen: ~/arm-labor/a64/a008.
ssh lab-user@lab-rpi.local 'mkdir -p ~/arm-labor/a64/a008'
scp lab-pi.s lab-pi-a64 lab-user@lab-rpi.local:arm-labor/a64/a008/A sikeres átvitel parancsainak várt kilépési állapota
0.
Futtatás: natív Raspberry Pi, SSH-munkamenetben,
lab-user fiókkal.
cd ~/arm-labor/a64/a008
chmod u+x lab-pi-a64
file lab-pi-a64
readelf -h lab-pi-a64
./lab-pi-a64
lab_status=$?
printf 'native: exit=%s\n' "$lab_status"
test "$lab_status" -eq 42A várt eredmény native: exit=42, majd sikeres,
0 állapotú ellenőrzés. A célszámítógépen nincs szükség
dinamikus betöltőre vagy C-könyvtárra ehhez a statikusan linkelt
példához.
Opcionálisan natívan is újraépítheted.
Build és futtatás: natív Raspberry Pi, A64 little-endian cél.
as -EL -march=armv8-a -o lab-native.o lab-pi.s
ld -EL -static -e _start -z noexecstack \
-o lab-native lab-native.o
./lab-native
lab_status=$?
printf 'native rebuild: exit=%s\n' "$lab_status"
test "$lab_status" -eq 42Itt is 42 a program várt állapota. A két build
fájljainak bájtonkénti azonosságát nem követeljük meg: eltérő
toolchain-kiadások eltérő ELF-elrendezést készíthetnek.
Ezek levezetett, várt eredmények; a példák itt nem kerültek ténylegesen futtatásra.
A fenti négyutasításos program nem megfelelő teljesítménymérésre. Teljes futási idejében a folyamatindítás és a rendszerhívás költsége is megjelenik; QEMU-ban ehhez emulációs többlet társul.
Fizikai gépen később releváns lehet:
Elméleti levezetés: állandó magórajel mellett egy ciklus ideje , ahol egysége Hz, egysége másodperc. Ebből még nem következik egy utasítás végrehajtási ideje: az utasításkésleltetés, az átlapolt végrehajtás és a memóriavárakozás külön kérdés.
A tényleges frekvencia változhat. Egy architekturális időszámláló frekvenciája pedig nem feltétlenül azonos a magórajelével, ezért annak változását nem szabad automatikusan processzorciklusnak nevezni. A hardveres teljesítményszámlálók hozzáférését az operációs rendszer is korlátozhatja.
Méréskor rögzítsd a Pi modelljét, az OS- és kernelverziót, az eszközláncot, a hűtési és tápellátási körülményeket, valamint a háttérterhelést. A részletes módszert az Egyszerű instrumentáció: ciklusszámlálás és időmérés építi fel. QEMU-időt ne tüntess fel Pi-ciklusszámként.
A QEMU azért elsődleges, mert hardver nélkül reprodukálható, és kisebb a veszélye a fizikai eszközök téves kezelésének. A QEMU user-mode azonban nem biztonsági homokozó (sandbox): a vendégprogram rendszerhívásokon keresztül a futtató felhasználó fájljait és hálózati lehetőségeit is elérheti.
| Gyakorlat | Fizikai hoston futtatható? |
|---|---|
| Átnézett, véges aritmetikai program, csak kilépéssel | Igen, normál felhasználóként |
| Saját tömb feldolgozása ismert méretkorláttal | Igen, helyességi ellenőrzés után |
| Ismeretlen eredetű bináris | Nem a szokásos laborhoston |
| Korlátlan allokáció, folyamatindítás vagy lemezírás | Nem változtatás nélkül |
Nyers eszközhozzáférés, /dev/mem, GPIO, rootként
futás |
Nem ennek az alfejezetnek a keretében |
| Kontrollált biztonsági hibademonstráció | Külön izolált környezetet és eljárást igényel |
Az assembly nyelv önmagában nem tesz egy programot veszélyessé vagy biztonságossá. Az elérhető jogosultságok, mellékhatások és erőforráskorlátok számítanak.
Hibakereséskor egyetlen hipotézist vizsgálj egyszerre:
Exec format error: ellenőrizd a
kernelarchitektúrát és az ELF fejlécét. Lehet, hogy rossz gépen vagy
rossz architektúrájú fájlt indítottál.Permission denied: nézd meg a
végrehajthatóságot és a fájlrendszer csatolási korlátozásait. Ne
sudo-val kerüld meg a tünetet.Illegal instruction: hasonlítsd össze
a fordítás célprofilját a CPU képességeivel. A példának nincs szüksége
ARMv8-A utáni bővítésre.$? értékét. Egy közbeiktatott sikeres parancs
már felülírja.(magyarázó, alapszint — cél:
megértés-ellenőrzés) Miért nem elegendő a uname -m
eredménye a teljes 64 bites laborprofil igazolására? Mit nem igazol a
QEMU-ban kapott helyes eredmény?
(implementációs, alapszint — cél: rutinépítés)
Módosítsd a programot úgy, hogy előjel nélküli 70 + 5
eredményével lépjen ki. Futtasd QEMU-ban, majd opcionálisan a Pi-n. Add
meg az A64 W0 és X0 várt tartalmát közvetlenül
az SVC előtt.
(hibakeresési, középszint — cél: rutinépítés) A
program után egy echo kész parancs fut, majd a hallgató
$? értékeként 0-t lát. Következtethet-e hibás
összeadásra? Javítsd az ellenőrzés sorrendjét.
(biztonsági/mérési, középszint — cél: megértés-ellenőrzés) Egy ismeretlen program rootjogot kér „pontos ciklusméréshez”. Másik program saját, korlátozott méretű tömbön számol normál felhasználóként. Melyik vihető át a Pi-re, és milyen további ellenőrzés szükséges?
1. megoldás — Segítség. Nézd meg a fejezet
táblázatát: a uname -m, a getconf LONG_BIT és
a dpkg --print-architecture három KÜLÖNBÖZŐ réteget
jellemez — létezhet olyan kombináció, ahol az egyik 64 bitet mutat, a
másik mégsem?
1. megoldás — Teljes megoldás. A
uname -m a kernel géparchitektúráját jelzi; mellette 32
bites felhasználói környezet is létezhet. A getconf és a
csomagarchitektúra ezért további adat. A QEMU-eredmény a vizsgált
funkcionális viselkedést támasztja alá, nem a Pi teljesítményét vagy
valamennyi bővítés elérhetőségét.
2. megoldás — Segítség. 70+5=75; nézd
meg a kódolási táblázatot — belefér-e mindkét konstans a
MOVZ/ADD immediate-mezőjébe eltolás
nélkül?
2. megoldás — Teljes megoldás. Az A64
MOVZ W0 immediate értéke legyen 70, az A64
ADD W0, W0 immediate értéke 5. Mindkettő
belefér a bemutatott kódolásba. Az eredmény
W0 = 0x0000004b, illetve
X0 = 0x000000000000004b; a felső bitek nullázását a 32
bites regiszterírás biztosítja. A várt kilépési állapot 75,
ezért a shell ellenőrzését is erre kell módosítani.
3. megoldás — Segítség. Melyik parancs fut el
UTOLJÁRA közvetlenül a $? kiértékelése előtt — a
laborprogram, vagy az echo?
3. megoldás — Teljes megoldás. Nem: a
$? ekkor az echo állapotát jelenti. A helyes
sorrend a mintában látható: programfuttatás, azonnali
lab_status=$?, majd kiírás és összehasonlítás. Ez mérési
hiba az ellenőrző környezetben, nem bizonyíték ISA-hibára.
4. megoldás — Segítség. Vesd össze mindkét programot a fejezet „Gyakorlat / Fizikai hoston futtatható?” táblázatával — melyik sorba illik egyik, melyikbe a másik?
4. megoldás — Teljes megoldás. Az ismeretlen programot nem futtatjuk rootként. A számlálóhozzáférés igénye nem indokol ellenőrizetlen jogosultságnövelést. A második program átnézés, méretkorlát-ellenőrzés és QEMU-helyességi próba után alkalmas lehet natív futásra. Időeredményét ettől még megfelelő ismétléssel és környezetleírással kell értelmezni.
A Raspberry Pi 4/5 opcionális natív ellenőrzési és később mérési környezet, nem a kötelező QEMU-labor helyettesítője. A processzor képessége mellett a kernelt, a felhasználói környezetet és az ELF architektúráját is ellenőrizni kell. Ugyanaz a statikus A64 program mindkét környezetben azonos eredményt adhat, miközben végrehajtási ideje teljesen eltér. A fizikai gép értéke a tényleges mikroarchitekturális viselkedés megfigyelése. A labor normál felhasználóként fusson; a QEMU user-mode használata sem szünteti meg a fájl- és hálózati mellékhatások kockázatát.
A linkek és a dokumentumverziók közös állapota az Olvasói útmutató forrásállapot-táblájában van; itt csak az alfejezet saját megállapításai szerepelnek.
master ág dokumentációja (közös
verziókorlát).Ellenőrzési hiányok, amelyek a fenti ellenőrzés után is ténylegesen fennmaradnak: a Raspberry Pi OS aktuális modelltámogatása, a telepítő kezelőfelülete és a csomagverziók helyben ellenőrizendők. Sem natív, sem QEMU-futtatás, sem teljesítménymérés nem történt; a megadott eredmények várt, levezetett ellenőrzési feltételek.