Rövid ismertető
Linux kernellel kapcsolatos fejelsztéseknél fontos, hogy a változatásainkat gyorsan tudjuk tesztelni. A saját, fejlesztői gépünkön (host) való tesztelés lassú:
- Letöltünk egy új kernel verziót, vagy módosítjuk a kódot
- Fordítjuk a kernelt
- Telepítjük a kernelt (felülírjuk az előzőt vagy szimbolikus linket átállítjuk az új kernel imagere)
- Újraindítjuk a gépünket
- Ha a módosítás nem rontja el a kernelt (kernel panic, bootloop, stb.), megvárjuk ameddig betölt
- Újrakezdjük/új módosítást csinálunk a kódban
Ezek közül a lépések közül időigényes a kernel fordítás, ha csak egy részét módosítjuk, akkor gyorsabb mert nem kell a teljes forrást újrafordítania mindig. Viszont az kernel image-t monden esetben meg kell, hogy csinálja, ez eltart egy rövid ideig. Sajnos ezen nem lehet spórolni. Sajnos az újraindítás géptől függően sok ideig eltarthat. Legrosszabb esetben valamilyen hiba miatt nem tud majd az új kernellel bebootolni a számítógép. Ekkor diszribúciótól függően elképzelhető, hogy manuálisan kell kiválasztani egy korábbi, még működő kernel verziót, ha ez lehetséges. Még ha siekresen betölt és lefuttatjuk a teszteket amivel ellenőrizzük, jók-e a módosításaink, akkor is időbe telik eljutni idáig. Ha a módosításaink a kódban rosszak és javítanunk kell, akkor megint sok idő, mire újra eljutunk az ellenőrző lépésig.
Ez a rövid leírás lépésről lépésre végigvezet egy olyan tesztkörnyezet elkészítésén, amivel virtuális gépen tudjuk tesztelni a kernelen végzett módosításainkat.
A leírásban használt fejlesztői gépen Ubuntu 18.04-es verzió futott. A leírt módszer más gépeken is működhet, viszont a felhasznált csomagok neve, verziója, hibaüzenetek, a parancsok paraméterezése, stb. eltérhet.
Ez a leírás csak iránymutatásul szolgál, elképzelhető, hogy a leírtaknál léteznek kényelmesebb, könnyebben konfigurálható megoldások is. A leírásban ismertetett módszer nem túl egyszerű, de jól követhető és maximálisan konfigurálható.
A leírásban használt fogalmak ismertetése
Host: host rendszer, host gép. A gazda gépet/operációsrendszert fogjuk így hivatkozni. Ez a gép, amin a fejlesztés folyik. A leírás elkészítéséhez egy 4 magos (8 szálas) processzorral, 16Gb RAM-al felszerelt gép volt felhasználva, Ubuntu 18.04 operációsrendszerrel.
Guest: guest rendszer, vendég operációsrendszer. Röviden így fogjuk hivatkozni a teszteléshez használt gépet/operációsrendszert. Ezt a rendszert virtualizációs eljárással futtatjuk a host gépen, egyszerre több guest rendszert is futtathatunk.
QEMU: virtualizációs szoftver, ami képes gépeket emulálni (többféle architektúra támogatott). Ez a virtuális gép a kernel és a szoftverek számára úgy fog tűnni, mintha valós hardver lenne. A QEMU weboldala: https://www.qemu.org/
Függőségek beszerzése
A kernel fordításhoz szükség van néhány csomagra. Mindegyk elérhető az Ubuntu hivatalos tárolóiban.
sudo apt install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc bison flex libelf-dev
A QEMU és a függőségeinek a telepítése
sudo apt install qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager cloud-utils
Kernel kód beszerzése
Több lehetőség is van, a hivatalos oldal a https://www.kernel.org/ innen elérhető több verzió is betömörített formában. Ha egy fix verzióval akarunk dolgozni, ez elég. Lehet olyan is, hogy egy dolgot több kernel verzióval is ki szeretnénk próbálni, ilyenkor jobban megéri git-el letölteni az adott verziót, mert utána egyszerűen lehet váltani más verziókra egy paranccsal.
git clone -b v4.20 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Ez letölti a kernel 4.20-as verziójának a forráskódját. Ha később váltani akarunk 5.0-ra elég kiadni a következő parancsot:
git checkout -b v5.0
Operációs rendszer beszerzése
Rengeteg lehetőség van, mert bármelyik GNU/Linux disztribúció futtatható QEMU virtuális gépként. Lehet Ubuntu-t telepíteni, de már előre elkészített lemezfájlok is betölthetőek. Szerver környezethez szánt Ubuntu 18.04 lemezek érhetőek el itt: https://cloud-images.ubuntu.com/bionic/current/
A leírásban a https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img lemezképet fogjuk használni. Ez egy minimális, csak a legszükségesebb könyvtárakat és programokat tartalmazó szerverekre szánt Ubuntu verzió, telepítést nem igényel, minden fontosabb beállítást cloud-init
szolgáltatással állítunk majd be.
A cloud-init egy szolgáltatás, ami megtalálható a legtöbb szerverre szánt disztribúcióban. A virtuális gép indulásakor egy init fájl alapján minden beállítást elvégez. Például van a lemezkép egy működő Ubuntuval, amin nincsenek felhasználók, de a cloud-init létrehoz rajta a megadott bejelentkezési adatokkal felhasználót, így később be tudunk rá jelentkezni (jelszóval vagy pritvát kulccsal).
cloud-init
lemezkép létrehozása
Készítsünk egy fájlt, ami tartalmazza a bejelentkezéshez szükséges adatokat, más konfigurációs beállításokat. A neve bármi lehet, ebben a leírásban az init.conf
. A tartalma legyen a következő:
#cloud-config
hostname: ubu
users:
- name: myusername
ssh-authorized-keys:
- ssh-rsa AAAAB3Nz[...]34twdf/ myusername@pc
sudo: ['ALL=(ALL) NOPASSWD:ALL']
groups: sudo
shell: /bin/bash
Az ssh-rsa
a publikus kulcsunk (a példában pár karakter kimaradt), ezt hozzáadja a .ssh/authorized_hosts
fájlhoz a virtuális gépben így be lehet ssh
-val jelentkezni. Ha nincs a host gépen kulcspárunk, akkor ssh-keygen
-el tudunk generálni, és a publikus kulcs az ~/.ssh/id_rsa.pub
fájlban lesz ha mást nem mondunk.
Az init fájlból készítenünk kell egyet init lemezképet. Ezt majd a virtuális gépnek fogjuk megadni.
cloud-localds init.img init.conf
A virtuális gép indításakor a letöltött Ubuntu lemezképre új adatok lesznek írva. Ha nem szeretnénk az eredeti lemezképet felülírni érdemes egy új lemezképet csinálni a letöltött “tetején” (snapshot image). A továbbiakban ide lesz írva minden módosításunk és az új fájlok is.
qemu-img create -f qcow2 -b bionic-server-cloudimg-amd64.img ubuntu.img
Próbáljuk ki, hogy feláll-e a rendszer:
sudo qemu-system-x86_64 \
-hda ubuntu.img \
-hdb init.img \
-m 2048 \
--nographic \
--enable-kvm \
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0
Ennek hatására be kell töltsön a gép. Bejelentkezni ssh
-val lehet:
ssh myusername@127.0.0.1 -p 2222
Saját kernel használata
A gép elindul, be lehet jelentkezni de az alap, Ubuntu lemezképbe csomagult kernel verziót használja. QEMU-ban lehetőség van saját kernel megadására is. Ezt a host gépen fordítjuk és adjuk meg a guest gépnek.
Fordítsuk le a kernel kódot.
cd linux/
make x86_64_defconfig
make kvmconfig
make -j `nproc --all`
Ha lefordult, a kernel lemezkép a arch/x86/boot/bzImage
helyen lesz.
Most indíthatjuk a gépet úgy, hogy ezt a lemezképet használja (a példa parancsban teljes elérési úttal szerepel).
sudo qemu-system-x86_64 \
-kernel /home/myusername/linux/arch/x86/boot/bzImage \
-append "root=/dev/sda1 single console=ttyS0 systemd.unit=graphical.target" \
-hda ubuntu.img \
-hdb init.img \
-m 2048 \
--nographic \
--enable-kvm \
-netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0
A virtuális gépre belépve ellenőrizzük a kernel verziót:
uname -r
QEMU 2.12 és újabb verzióknál lehetőség van rövidíteni a hálózati kártya paramétert.
A -netdev user,id=net0,hostfwd=tcp::2222-:22 -device e1000,netdev=net0
helyett elég a -nic user,hostfwd=tcp::2222-:22