A fenti mondat jutott eszembe, amit lelki szemeim előtt a szarvas nyuszi mond a Koalának. Ugyanis tegnapi hekkelésem a Koala-ban lévő kernel (jelenleg: 2.6.31-rc1) felhúzása Jaunty alá, így mondhatjuk, hogy Nyuszi Koalán "lovagol". Ezen felül tettem néhány szánalmas további próbálkozást a bootolás felgyorsítására (lényegében ez lett volna a célom).
Nem állítottam át a csomagkezelőt (hogyisne, még csak az kéne), hanem szépen megkerestem, hogy a Koala repo-ban a linux-source csomag hová mutat, majd letöltöttem:
wget "http://hu.archive.ubuntu.com/ubuntu/pool/main/l/linux/linux_2.6.31-1.13.tar.gz"
Némi telepítenivaló a kernel fordításhoz (a szokásos...):
apt-get install build-essential libncurses5-dev kernel-package
A letöltött, gzipelt állományt kitömörítettem a /usr/src alá. Készített egy ubuntu-karmic (vagy valami igen hasonló) alkönyvtárat, ami nekem éppen megfelelt. Beléptem tehát a /usr/src/ubuntu-karmic könyvtárba, majd generáltam egy alapértelmezett értékekkel feltöltött kernel konfigot (ez a .config nevű fájlban keletkezett meg):
make defconfig
Kernel fordítás for dummies
Ezek után egy olyan szkriptet használtam, amit a neten találtam, és aminek a használatát röviden így foglalnám össze:
1. Bebootolunk az alapértelmezett kernellel, ahogyan szoktunk.
2. Az udev (a szokásos módon) felismeri a hardvereszközeinket, és automatikusan behúzza a szükséges modulokat
3. az lsmod-dal kilistáztatható, hogy milyen kernel modulok vannak a memóriában
4. A szkript végigmegy a létező kernel konfiguráción, és szépen "y"-re állítja azokat a modulokat, amelyek eddig modulban voltak.
Az egész hatása az, hogy pl. az eddig modulban lévő IDE (SATA, PATA...) modul a kernel része lesz, következésképp nem kell initrd ami behúzza a modult, következésképpen nem kell initrd sem. Elegánsan hangzik.
Ez most tényleg fontos! Ahhoz, hogy ez jól működjön, értelemszerűen be kell dugni minden hardvert, fel kell mountolni az összes partíciót és hálózati elérést, amit használunk, meg kell szólaltatnunk a hangkártyát, csatlakozzunk a netre stb. különben annak modulja nem lesz behúzva, ergo nem lesz beállítva sem!
Az előbbi megjegyzés akkor is igaz, ha lehet hogy szerencsénk van és az alapértelmezett kernel konfigurációban pont a mi hardverünk be van állítva modulnak, így észre sem vesszük és az új kernel behúzza modulként a hardver kezeléséhez szükséges meghajtót. Erre ne építsünk, ha lehet. :-)
Tehát, a fenti szkriptet töltsük le (később majd részletezem a működését), és másoljuk le a /usr/src/ubuntu-karmic alá. Az eredeti konfigot is elmentettem, így össze tudom hasonlítani a kettőt, ha esetleg valami rosszul sült el:
perl buildin_used_mods.pl > configused
mv .config config_orig
mv configused .config
Ha hihetetlenül magabiztosak vagyunk, akkor léphetünk tovább a kernel lefordítására. Én inkább futtatok egy make menuconfig -ot, és leellenőrzöm hogy minden, számomra lényeges be, illetve ki van kapcsolva. Az alábbi táblázatba szedtem ezeket:
Beállítás | Menüpont neve |
y | General setup / Kernel .config support |
y | General setup / Enable access to .config through /proc/config.gz |
Pentium IV, mindenki válassza ki amije van | General setup / Processor type and features / Processor family |
Én kivettem az AMD-s részeket, mivel Intel a processzor | General setup / Processor type and features / Machine Check Exception sorok |
Akinek valamelyik menüben szerepel a laptopja, azt állítsa y-re, a többi nem fog kelleni | General setup / Processor type and features / speciális laptopok támogatása (Toshiba, Dell... ) |
Nekem kevesebb van, mint 1Gb, ezért off-ra állítottam. 1-4Gb között állítsuk 4-re, efölött (van ilyen? :-) 64-re | General setup / Processor type and features / High Memory support |
Modulba raktam, sose lehet tudni | "Executable file formats / Emulations" / Kernel support for a.out and ECOFF binaries |
A RAID0-t és RAID1-et "y"-re kapcsoltam, szintén sose lehet tudni jeligével | Device Drivers / Multiple devices driver support (RAID and LVM) |
n | Device Drivers / Network device support / Token ring |
n | Device Drivers / Network device support / Ethernet (1000 Mbit) |
n | Device Drivers / Network device support / Ethernet (10000 MBit) |
A PPP-t, és minden almenüjét modulba raktam | Device Drivers / Network device support / PPP |
Az ATI-t bejelöltem, mivel nekem az van | Device Drivers / Graphics Support / Direct Rendering Manager |
Ha laptopunk van, érdemes végigböngészni | Device Drivers / X86 Platform Specific Device Drivers |
Ellenőrizzük, hogy megvan-e minden, ami kell. Az ext2-es dolgokat és a fuse-t mindenképp jelöljük be (utóbbi pl. az NTFS felcsatolásához kell, és hiába jelöljük be az NTFS támogatást, az Ubuntu a FUSE-t használja ezért ez mindenképp kell!) | File systems |
Nézzünk bele, hátha kell valami, én az eCrypt-et beválasztottam (y) | File systems / Miscellaneous |
Nekem egyszerűen nem fordult le a kernel, ha ez be volt kapcsolva úgyhogy (n) | Ubuntu Supplied Third-Party Device Drivers / Two Level Segregate Fit Allocator |
Nem kellett, kiszedtem (n) | Ubuntu Supplied Third-Party Device Drivers / Apple USB Infrared Receiver |
Nem kellett, kiszedtem (n) | Ubuntu Supplied Third-Party Device Drivers / LIRC Device support |
Nem kellett, kiszedtem (n) | Ubuntu Supplied Third-Party Device Drivers / Software kill switch for Averatec 5100P |
Nem kellett, kiszedtem (n) | Ubuntu Supplied Third-Party Device Drivers / Software kill switch for Packard Bell EasyNote E5 |
Nem kellett, kiszedtem (n) | Ubuntu Supplied Third-Party Device Drivers / Toshiba ACPI laptop driver |
Ezt azért írtam le, hogy merrefelé érdemes körbenézni. Ettől függetlenül ha később valami nem indul el, akkor bootoljunk vissza az eredeti kernellel és az lspci (usb-s dolog esetén lsusb) paranccsal kérdezzük le a kérdéses hardvert, és amit ott kiír, az alapján a neten megtaláljuk a szükséges beállítást.
Exit, exit, "Save kernel config?" -> naná, hogy yes.
make-kpkg kernel_image kernel_headers modules
Ez ellesz egy darabig, majd a /usr/src könyvtárba szépen és flottul előállítja az új kernelünket .deb csomag formájában. Ha már futtattuk a fordítást, akkor maradhattak hátra szemetek, szóval a fenti parancs előtt ilyenkor nyomjunk egy make-kpkg clean -t is.
A kernel csomag simán telepíthető a
dpkg -i <csomagnév>
paranccsal. A kernel-headerst nem kell feltennünk, csak akkor ha az új kernelhez szeretnénk olyan programot fordítani, ami használja (pl. kernel modult fordít, ilyen lehet a vmware).
Most ismét egy nagyon fontos lépés
Mielőtt rebootolnánk...! Mivel kihagyjuk az initrd-t úgy ahogyan van, ezért nem tud lefutni az udev a legelején, csak később. Következésképpen nem jönnek létre a disk-by-uuid bejegyzések, így a grub-ban hiába hivatkozunk a root partíciónkra az uuid-vel. Ezt le kell cserélni a konkrét /dev/sdx névre. Nekem például a /boot/grub/menu.lst megfelelő részét így kellett átírnom: #title Ubuntu 9.04, kernel 2.6.31-rc1
#uuid 3b745ea2-f32d-4635-9a97-23884a4bcdc9
#kernel /boot/vmlinuz-2.6.31-rc1 root=UUID=3b745ea2-f32d-4635-9a97-23884a4bcdc9 ro quiet splash.
#quiet
title Ubuntu 9.04, kernel 2.6.31-rc1
kernel /boot/vmlinuz-2.6.31-rc1 root=/dev/sda5 ro quiet
quiet
Ezek után kutyakötelessége a kernelnek, hogy bebootoljon. Ha mégsem, nézd meg a tipikus hibákat, hátha segít.
Bút Túning
Gondoltam, mérjük le, mennyire gyors ez az új kernel; és rendezzük kicsit át a boot szkriptek sorrendjét is, hátha okosabb vagyok, mint egy ötödikesUbuntu mérnök.
A végén fogom egy kis táblázatban összefoglalni az eredményeket.
rc szkriptek rendezgetése
Tehát elsőként bebootoltam az új kernellel. Aztán a /etc/rc2.d alatt vágtam egy kis rendet:
- S10apmd -> kuka, acpit használok
- S10sysklogd, S11klogd -> S40sysklogd, S41klogd. Átrendeztem a sorrendet, desktopon nem baj, ha kicsit később indul el a rendszernapló, kibírom
- S20apport -> töröltem (automatikusan elemzi az összeomlott programokat és hibajelentést ad fel, vagy mifene)
- S50cups -> S99cups (nem gond, ha a nyomtató támogatás csak a legvégén indul el)
- S50pulseaudio -> S35pulseaudio (az audio támogatás viszont induljon el jó hamar)
- S89atd -> kuka (nem használom, csak a crond-t)
- S98usplash -> kuka (mivel nincs splash az új kernellel, semmi értelme)
Ezek után ismét megmértem a boot időt; majd jött a /etc/rcS.d alatti "rombolás":
- S40networking, S45mountnfs.sh, S46mountnfs-bootclean.sh, S49console-setup, S55urandom -> bemásoltam a /etc/rc2.d alá; így később indulnak el és megvolt az az elképzelésem, hogy így az X talán hamarabb feltápászkodik
- S70x11-common -> S38x11-common (szintén a gyorsabb X indulás miatt mozgattam korábbra az rcS.d könyvtáron belül)
Profiling
Negyedik lépésként, olvastam valahol hogy a profiling nagyban meg tudja növelni a bootolás sebességét. Ehhez nem kell mást tennünk, csak a kernel boot paraméterei közé betenni a "profile" kulcsszót, és egy szkript automatikusan optimalizálja a boot szkripteket. Legalábbis ez az elmélet. Megtudjuk, hogy mi a valóság, mert az utolsó két mérést a profiling után végeztem.
A boot paraméter beállítása úgy zajlik, hogy amikor indul a grub, és választhatunk, hogy melyik kernelt vagy oprendszert töltjük be (akinek csak linux van, annak elképzelhető, hogy nyomni kell egy Escape-et), szóval a boot menünél ráállunk a "fénygerendával" a kívánt kernelre, majd nyomunk egy 'e'-t, és a bejövő almenüben a 'kernel' sorra ismét egy 'e'-t (az 'e' jelentése: edit). A sor végére biggyesszük oda, hogy " profile" (azaz szóközt hagyjunk előtte), majd enter és a 'b' betűvel bebootolhatjuk az új paraméterrel az adott kernelt.
Eredmények
Úgyis mindenki erre kíváncsi, lássuk:
Kernel | Boot a login képernyőig | Login képernyőtől Gnome menüig |
2.6.28-13 | 32,1 sec | 22,4 sec |
2.6.31-rc1 | 29,4 sec | 21,7 sec |
rc2 átrendezés után | 28,1 sec | 22,2 sec |
rcS átrendezés után | 28,4 | 21,4 |
Profiling után 1 | 32,2 | 22,4 |
Profiling után 2 | 31,9 | 22,1 |
Mértem a grub menütől a gdm képernyőig, majd a jelszó beütés enter-étől egészen odáig, hogy megjelent a gnome-panel (ekkor azonnal rákattintottam a gnome menüre), és akkor állt le a stopper amikor végre le tudott gördülni a főmenü.
Látható, hogy a Koala kernel épp annyival gyorsabb az én gépemen, amennyit az initrd elvisz a boot időből. Következésképpen az én hardveremmel vagy nem lehet párhuzamosítani, vagy valamit én nem csináltam jól (esetleg a kernelfejlesztők :-)). Az rc2 alatti rendrakás ismét hozott egy másodpercet, de az rcS alatt hiába tettem át későbbre a hálózat inicializálást, valószínűleg az nem vesz el jelentős időt (vagy már ki van optimalizálva). A profiling pedig egyenesen visszarontotta a boot időt az eredeti hosszára.
Így hát nem vagyok okosabb, mint egy Ubuntus mérnök, és pár óra után ugyanott tartok, ahol voltam - csak a kernelem lett újabb. :-) Úgy érzem, még mindig csak kesztyűs kézzel paskolom a bootolás részt, ha amúgy igazán odacsapnék egy teljesen saját megoldással, egyedül az javítana látványosan az eredményeken.