3.3 Opcionális fizikai hardver: Raspberry Pi 64-bit módban

3.3.1 Miért érdemes fizikai géppel is kiegészíteni a labort?

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.

3.3.2 A 64 bites környezet előkészítése

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:

  1. Külön labor-adathordozót használj. A rendszerkép kiírása törölheti a kiválasztott meghajtó tartalmát. Ellenőrizd az eszköz azonosítását és a szükséges mentést.
  2. A Raspberry Pi hivatalos telepítőeszközével válassz az adott Pi 4/5 modellhez támogatott Raspberry Pi OS, 64-bit rendszerképet. Konzolos használathoz grafikus felület nem szükséges.
  3. Állíts be egyedi gépnevet, például 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.
  4. Használj megfelelő tápegységet és hűtést. Teljesítménymérésnél az elégtelen tápellátás és a túlmelegedés miatti órajel-visszavétel különösen zavaró tényező.
  5. Első indítás után végezd el a szükséges rendszerfrissítést. Rögzítsd a rendszerkép kiadását és a csomagverziókat: egy későbbi frissítés már más mérési környezetet jelenthet.

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-release

A 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.

3.3.3 SSH és elkülönített jogosultságok

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:

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 file

Siker 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.pub

Ez 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.local

A 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.

3.3.4 Mit jelent ugyanaz a program QEMU-ban és a Pi-n?

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.

3.3.5 Kidolgozott példa: ugyanaz az ELF két végrehajtási környezetben

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/a008

Mentsd 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,"",%progbits

Az 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 42

A 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 42

A 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 42

Itt 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.

3.3.6 Mikor ad valóban többet a fizikai hardver?

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ó ff magórajel mellett egy ciklus ideje T=1/fT=1/f, ahol ff egysége Hz, TT 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.

3.3.7 Biztonsági döntés és hibakeresési ellenpróbák

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:

3.3.8 Feladatok

  1. (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?

  2. (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.

  3. (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.

  4. (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?

3.3.9 Megoldások

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.

3.3.10 Rövid összefoglaló

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.

3.3.11 Források és ellenőrzési hiányok

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.

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.