5 lutego 2009

Dłubiemy w systemie - cz. 2: Konfiguracja i kompilacja jądra

Poniższy opis odnosi się do Linuksa w wersji 2.6.x. W przypadku kompilacji jądra serii 2.4 i 2.6 występują subtelne różnice.

Przebieg kompilacji i instalacji jądra możemy bardzo ogólnie opisać w paru punktach:
  • Zdobycie źródeł, oraz informacji o sprzęcie

  • Konfiguracja – od zera, lub z wykorzystaniem istniejącej konfiguracji

  • Kompilacja
    • Obrazu jądra
    • Modułów

  • Instalacja (kolejność nie ma znaczenia)
    • Modułów
    • Skopiowanie lub przeniesienie obrazu jądra do /boot
    • Wygenerowanie ramdysku initrd i umieszczenie go w /boot (opcjonalnie – w przypadku gdy główny system plików, którego obsługa jest niezbędna do załadowania systemu nie został wkompilowany na stałe w jądro, lub w przypadku korzystania z duetu bufora ramki (frame buffer, pozwalający na osiągnięcie wysokiej rozdzielczości w konsoli, a także 32 bitowej palety kolorów, co pozwala m.in. oglądać filmy w czystej konsoli (po uprzednim ustawieniu wyjscia video w naszym ulubionym odtwarzaczu na bufor ramki)) i tzw. bootsplash'a, czyli grafiki/animacji wyświetlanej podczas uruchamiania systemu)
  • Konfiguracja bootloadera (dodanie nowych wpisów dla nowego kernela)
  • Reboot i pacierz ;)


Pierwszym krokiem jest zaopatrzenie się w źródła jądra. Archiwa 'waniliowego' (czyli gołego, bez dodatkowych patchsetów dostępnych w dystrybucyjnych Linuksach) kernela możemy pobrać ze strony http://www.kernel.org. Naukę kompilacji najlepiej przeprowadzać pod Slackware, ponieważ nie korzysta on z żadnych patchsetów, co pozwoli nam na uniknięcie przykrych niespodzianek typu „Po kompilacji jądra nie działa mi skaner” (bo jego sterownik dostępny był w postaci patcha lub wchodził w skład patchsetu). Jeśli już musimy kompilować jądra np. pod Mandrivą, Fedorą czy Ubuntu zalecam aby zaopatrzyć się w pakiet ze źródłami jądra pochodzący z repozytorium. W ten sposób otrzymamy kompletne, połatane źródła Linuksa.

Źródła „jajka” najczęściej umieszcza się w /usr/src. Po wypakowaniu archiwum naszym oczom ukaże się katalog linux-wersja. Warto utworzyć sobie dowiązanie symboliczne /usr/src/linux prowadzące do źródeł naszego jądra.

Niektóre programy podczas kompilacji wymagają dostępu do źródeł jądra. Przykładem mogą być sterowniki dostarczane w postaci kodu źródłowego, z którego budowany jest moduł jądra. Jeśli w systemie mamy kilka kerneli, może pojawić się pytanie – skąd wiadomo w którym katalogu szukać źródeł jądra? Modyfikacja dowiązania /usr/src/linux przy każdym uruchomieniu systemu na danym jądrze jest rozwiązaniem bardzo nieeleganckim, poszukiwanie źródeł w /usr/src/ z wykorzystaniem uname -r także nie jest zbyt szczęśliwym wyjściem z sytuacji bo te niekoniecznie muszą się znajdować akurat tam. Dlatego istnieją inne dowiązania - /lib/modules/`uname -r`/source

Sam katalog /lib/modules
jak sama nazwa wskazuje jest miejscem, w którym przechowywane są skompilowane moduły jądra, w każdej chwili gotowe do załadowania.



Jeśli chodzi o informacje na temat sprzętu – podstawowe informacje możemy otrzymać poprzez wykorzystanie polecenialspci, lsusb oraz dmesg.

Czym są moduły?
Większość ficzerów możemy zbudować w postaci modułu, zamiast integrować z samym jądrem (co ma wpływ na wielkość jego obrazu). Główną zaletą modułów jest możliwość ich ładowania i usuwania z pamięci, czyli poszerzanie/zwężanie możliwości naszego Linuksa i to bez potrzeby ponownego uruchamiania systemu (Co ma niebagatelne znaczenie np. w przypadku serwerów)! Ficzery z których korzystamy rzadko, a są pamięciożerne (np. obsługa systemów plików – jeśli nie używamy danego systemu plików na danej maszynie, lub rzadko zachodzi taka potrzeba) warto kompilować do postaci modułu (załóżmy, że zdarza się, iż raz na miesiąc musimy coś przekopiować z cudzego dysku na którym wykorzystuje się inny system plików. Trzymanie w pamięci funkcji odpowiedzialnych za jego obsługę jest marnotrawieniem czasu, podobnie jak kompilacja osobnego jądra wyposażonego w daną funkcjonalność. W takim przypadku mamy możliwość załadowania modułu na czas wykonania odpowiednich zadań i późniejsze ich wyłączenie, bez ponownego startu systemu).



Ogromne pole do popisu dają tzw. SoftLevele, dostępne m.in. w Gentoo, które pozwalają tworzyć osobne profile skryptów startowych, w zależności od parametru podanego w bootloaderze. Co to oznacza w praktyce? Jeśli np. w domu korzystamy z połączenia kablowego, natomiast na uczelni przesiadamy się na sieć bezprzewodową, to możemy z poziomu bootloadera zadecydować m.in. które skrypty startowe zostaną załadowane (możemy stworzyć 2 skrypty startowe, z czego 1 odpowiada za załadowanie modułów do obsługi karty wlan oraz podniesienie odpowiednich interfejsów, a drugi dotyczy tradycyjnej karty sieciowej). I nie marnujemy czasu na kompilację 2 linuksów, tym samym oszczędzając wolną pamięć.



Kwestia konfiguracji – tysiące przeróżnych HOWTO's i Artykułów powstało na ten temat. Najlepszą metodą na opanowanie tej sztuki jest eksperymentowanie i samodzielne próby. Dobrą techniką jest użycie konfiguracji wykorzystywanej w jądrze dystrybucyjnym i jego modyfikacja pod kątem własnych potrzeb. Jeśli jądro zostało skompilowane z obsługą IKCONFIG_PROC („General Setup” → „Enable access to .config through /proc/config.gz”, wymaga uwcześniejszego zaznaczenia opcji „Kernel .config support” znajdujuącego się w tym samym podmenu) możemy wyświetlić config kernela przy pomocy polecenia zcat /proc/config.gz. W przeciwnym wypadku kopia pliku konfiguracyjnego powinna znajdować się w katalogu /boot.
Moja rada: Początkujący powienien trzymać się zasady, że jeśli nie jest pewien jakiejś opcji to powinien jej nie ruszać.



Konfiguracja jądra zawiera się w 1 pliku tekstowym .config (kropka na początku nazwy), znajdującym się w katalogu źródeł. Jego modyfikacji, czyli „skrajania kernela na miarę”, możemy dokonywac na kilka sposobów:

  • Edycję pliku przy pomocy ulubionego edytora tekstowego, jednak jest to rozwiązanie dla masochistów ;)

  • Użycie jednego z kilku dostępnych narzędzi (wywołujemy poprzez polecenie make nazwa_narzędzia):
    • menuconfig – tekstowy edytor wykorzystujący bibliotekę ncurses. W tym przypadku symbol gwiazdki ('*') oznacza 'wkompilowane w jądro', duża litera 'M' oznacza moduł, natomiast puste pole to wyłączenie danej funkcji z jądra. Jeśli '*'/'M'/' ' jest otoczone ostrymi nawiasami – osnacza to, iż dana opcja może zostać wkompilowana w jądro na stałe, jako moduł, lub wcale. Nawias indeksowy oznacza, że dana opcja nie może pojawić się w postaci modułu. Przykładem może być widoczna na obrazku obsługa modułów (2 pozycja w menu). Myśliki oznaczają brak możliwości zmiany statusu. Strzałka za nazwą oznacza, iż opcja posiada podmenu.

      Podsumowując - jest to najlepsze narzedzie, ze względu na przejrzystość interfejsu oraz niewielkie zależności software'owe.

      Ilustracja 2: xconfig (biblioteka QT)

      Ilustracja 3: gconfig (GTK)

    • xconfig, gconfig – graficzne narzędzie do konfiguracji jądra, których filozofia i obsługa jest analogiczna do menuconfig. Ich wadą jsą zależności – poza systemem Xwindow (X.Org/XFree86[starsza wersja]) wymagane są także odpowiednie biblioteki, np. Qt, czy GTK. Niewątpliwą zaletą tych 2 rozwiązań jest przejrzystość.

    • oldconfig – po wcześniejszym skopiowaniu pliku konfiguracyjnego pochodzącego ze starszego lub nowszego jądra w katalogu ze źródłami, narzędzie to uaktualnia jego zawartość (jeśli w skopiowanym .config'u któraś z opcji się nie pojawiła, dopisuje ją i ustawia jej domyślny atrybut)

    • defconfig – tworzy nowy .config używając domyślnych ustawień.


  • Więcej aktualnych informacji można uzyskać poprzez komendę make help

    Praktyczne i uniwersalna wskazówka z mojej strony: Takie rzeczy jak obsługa kontrolera dysków, czy systemu plików znajdującego się na głównej partycji zawsze warto integrować z jądrem. Są to rzeczy z których korzystać będziemy zawsze, więc zbudowanie ich w postaci modułów nie przyniesie nam żadnych korzyści (chyba że jest się deweloperem jakiejś dystrybucji odpowiedzialnym za sam kernel i chce się zapewnić uniwersalność, połączoną z możliwościa wyłączenia niepotrzebnych sterowników [z tym, że jeśli ktoś się chwyta za takie rzeczy to posiada odpowiednią wiedzę i nie trzeba go pouczać]). W przeciwnym wypadku musimy pamiętać nie tylko o wygenerowaniu initrd, ale także o włączeniu odpowiedniej opcji w jądrze, która umożliwia zastosowanie tego rozwiązania.

    Dlaczego?
    Jak już wcześniej wspominałem – moduły znajdują się na dysku twardym, w katalogu /lib/modules/wersja_jądra/. Aby się do nich dostać wymagana jest obsługa kontrolera i systemu plików. Nie jesteśmy w stanie wczytac sterownika, które zapewnia obsługę danego urządzenia, jeśli znajduje się na tym urządzeniu (tutaj goraco pozdrawiam producentów napedów blu-ray, którzy sterowniki umieszczają na krążkach blue-ray ;) ). Aby ominąć ten problem, należy umieścić sterownik w ram dysku (initrd).

    Przejdźmy do kolejnego kroku – czyli właściwej kompilacji. Możemy kompilowac na dwa sposoby:

      • Używając jednego polecenia: make all lub make (bo domyślnym targetem dla make jest 'all'), które: skompiluje jądro (make vmlinux), utworzy jego skompresowany obraz (make bzImage), oraz zbuduje moduły (make modules).

      • Używając 2 poniższych poleceń, etap po etapie, zachowując przy tym większą kontrolę nad całym procesem kompilacji oraz umożliwiając łatwe zdiagnozowanie której części procesu kompilacji dotyczy ew. błąd.
        make bzImage (bzImage wyzwala vmlinux – wystarczy zajrzeć do Makefile znajdującego się w podkatalogu arch/`uname -m`/)
        make modules

      Teraz przechodzimy do instalacji nowego jądra. Instalujemy moduły następującym poleceniem:

      • make modules_install

      Tutaj możemy również skorzystać z jednego polecenia, lub wykonać cały zabieg ręcznie:

      • make install – to polecenie skopiuje obraz jądra do /boot, doda odpowiedni wpisy do bootloadera. Podczas instalacji wykorzystywany jest skrypt ~/bin/installkernel, /sbin/installkernel lub jądro jest instalowane w $(INSTALL_PATH) i automatycznie uruchamiany jest wyzwalacz dla LILO (dodanie wpsiu do booltoadera).

        Lub poprzez:

      • cp arch/`uname -m`/boot/bzImage /boot/jajko-wersja oraz ręczne dodanie wpisów do bootloadera. Jeśli korzystamy z LILO, modyfikujemy plik /etc/lilo.conf, zachowując składnię przedstawioną poniżej:

        image=/boot/nazwa_obrazu opcje #sciezka do obrazu jadram oraz ew. opcje (dla jądra, dla framebuffera, czy def. softlevelu)
        label=nowe_jajko #label czyli tresc etykiety w menu LILO
        initrd=/boot/initrd-2.2.12-20.img #opcjonalnie
        read-only
        root=/dev/sda1 #tutaj podajemy partycję główną



    W przypadku GRUB'a edytujemy /etc/grub.conf, /boot/grub/menu.lst/boot/grub/grub.conf, wg schematu:

    title nowe_jajko
    root (hd0,0)
    kernel sciezka_do_obrazu_jadra opcje
    initrd sciezka_do_initrd



        Jeśli istnieje taka potrzeba – należy jeszcze utworzyć plik initrd, np. przy pomocy narzędzia mkinitrd

        Po kazdej rekompilacji jądra (a dokładnie – przebudowie modułów) należy pamiętać iż sterowniki dostarczane w postaci zewnętrznych modułów, jak np. nvidia-drivers, wymagają reinstalacji.

    23 października 2008

    Dłubiemy w systemie - cz. 1: Kompilacja oprogramowania

    Chciałbym tym wpisem rozpocząć krótką serie, w której opisywać będę najpopularniejsze metody dostrajania systemu i oprogramowania. Zaczynamy!

    Ręczna kompilacja oprogramowania.
    Zanim zaczniemy zastanówmy się dlaczego warto cokolwiek ręcznie kompilować. No właśnie - po co? Najczęstsze przyczyny to:

    • Brak danego programu/biblioteki repozytorium dystrybucji,
    • Chęć lepszego dostosowania oprogramowania do naszych potrzeb,
    • Optymalizacja kodu (flagi kompilatora, flagi linkera, stripowanie),
    • Chcemy zaingerować w kod programu/biblioteki (łaty, własne modyfikacje)
    • Gdy nie mamy dostępu do root'a, a koniecznie musimy zainstalować jakiś program, podczas gdy admin wypoczywa przy szklance soku w Pcimiu Dolnym.

    Pierwszym krok""iem jest zaopatrzenie się w odpowiednie narzędzia - niezbędny będzie kompilator (gcc), linker (ld, wchodzi w skład binutils), biblioteki (przede wszystkim glibc-devel), automake, autoconf i inne. Skąd mieć pewność, że mamy wszystko co potrzebne - o tym za chwilę.

    Następny krok to zaopatrzenie się w źródła (kod źródłowy) danego programu/biblioteki. W tym celu musimy udać się na stronę danego projektu lub zapytać wujka google'a. Najczęściej występują w postaci archiwum tar skompresowanych gzip'em/bzip'em (*.tar.gz, *.tar.bz2, czasem skracane do *.tgz, *.tbz2). Naukę najlepiej zacząć od niewielkich programów, np. irssi - konsolowy klient IRC.

    W konsoli przechodzimy do katalogu, gdzie zapisaliśmy archiwum (zalecam wypakowywanie do pustego katalogu), następnie rozpakowujemy je poleceniem:

    $ tar jxvf nazwa_archiwum.tar.bz2

    lub

    $ tar zxvf nazwa_archiwum.tar.gz

    Flaga (opcja) 'z' informuje program tar, że mamy do czynienia z archiwum spakowanym gzipem, a w przypadku 'j' - bzipem. 'x' mówi że chcemy coś wypakować, 'v' oznacza tryb "gadatliwy" (ang. verbose), a 'f' wskazuje, że chcemy rozpakować plik, którego nazwa jest dalej. Szczegółowe opisy opcji polecenia tar można znaleźć w man tar

    Jeśli w wyniku tego procesu otrzymamy nowy podkatalog - przechodzimy do niego (ok. 85% przypadków).

    Na moment zostawię konsolę w spokoju, aby poruszyć kwestię optymalizacji. Informacje o tym jak ustawiać flagi, które z nich są 'bezpieczne', a które nie, można znaleźć w Hoppke Repo. Dodam tylko, że zauważyłem, iż w ostatnim czasie stosowanie flagi -fomit-frame-pointer dla C++ ($CXXFLAGS) przestało powodować problemy (sam używam tej flagi, korzystam z gcc serii 4.3).Nawet jeśli ktoś nie ma zamiaru skupiać się na studiowaniu flag kompilatora, to nie zaszkodzi na stałe ustawić popularnych i bezpiecznych flag dla konkretnego modelu procesora. Chyba, że zależy nam na przenośności (np. tworzymy paczkę, która ma być dostępna dla każdego użytkownika danej dystrybucji), wtedy najlepiej kompilować pod i686 (pentium pro i nowsze).

    Wróćmy do procesu kompilacji. Etapem wstępnym do właściwej kompilacji jest konfiguracja. Odbywa się to poprzez wywołanie skryptu configure z odpowiednimi opcjami. Własnie - jakimi opcjami? Listę dostępnych opcji uzyskamy po wpisaniu:

    $ ./configure --help

    Część opcji występuje zawsze, lub bardzo często, natomiast spora część bywa unikatowa, tylko dla danego oprogramowania. Ich opisy znajdziemy po wywołaniu w.w. polecenia, ale pozwolę sobie opisać (moim zdaniem) najważniejszą, czyli --prefix=... Czym jest prefix? W Linuksie oraz Uniksie stosuje sie filozofię, iż biblioteki lądują w katalogu lib, binarki w bin lub sbin, pliki nagłówkowe w includes itd. Są to założenia standardu FHS
    Prefix definuje ścieżkę gdzie umieszczona ma zostać w.w. struktura. Prosze zauważyć że podobne katalogi znajdziemy w /,
    /usr, /usr/local, a czasem /opt/nazwa_programu/. Za pomocą prefiksu definiujemy gdzie zainstalujemy dany program. Ktoś teraz zapyta: "super, mamy wybór gdzie chcemy instalować oprogramowanie, ale co nam to daje i dlaczego ten nawiedzony człowiek nazwał to najwazniejsza opcją?" Otóż jest kilka istotnych powodów:

    • Wyobraźmy sobie sytuację, że posiadamy konto shellowe, bez uprawnień pozwalających na instalację pakietów binarnych, czy zapisu w /usr, /usr/local, czy /opt. W takim przypadku możemy ustawić prefix na miejsce, do którego mamy pełne prawa i gdzie nie zajrzy nam inny użytkownik - takim miejscem jest katalog domowy użytkownika, jednak by nie robic sobie balaganu proponuje utworzyc specjalny katalog na wlasne oprogramowanie i dodac go do sciezki podanej w prefixie. Przyklad użycia:

      $ ./configure --prefix=~/moje_programy [--inne-opcje]

      Przy zastosowaniu takiego egzotycznego prefiksu standardowo nie będziemy mogli uruchamiać programów poprzez samo wpisane ich nazwy. Musimy podawać pełną ścieżkę do binarki - czyli ~/moje_programy/bin/nazwa_programu. Da się to łatwo zmienić. Wystarczy zmodyfikować zmienną środowiskową $PATH przechowującą listę katalagów, gdzie powłoka ma szukać programów. Poszczególne ścieżki oddzielone są dwukropkami, a im wcześniej dana lokalizacja występuje tym wyższy ma priorytet. W praktyce wystarczy zmodyfikować/utworzyć ~/.bashrc (ukryty (kropka na początku nazwy) plik teksotwy, którego zawartość jest wykonywana podczas każdego uruchomienia powłoki BASH). Umieszczamy w nim następującą linijkę (najlepiej dopisać do końca):

      export PATH=~/moje_programy/bin:$PATH


      Jak widać nowa ściezka będzie miała najwyższy priorytet (jeśli w systemie jest już zainstalowany dany program, ale np. jego wersja/konfiguracja nam nie odpowiada, to mamy pewność, że po wpisaniu samej nazwy polecenia uruchomi się "nasz" program). Aby 'wczytać' nowe ustawienia wydajemy polecenie:

      $ source ~/.bashrc



    • Domyślną wartością opcji prefix jest /usr/local. Jak mówi FHS jest to specjalne miejsce na oprogramowanie instalowane lokalnie, wydzielone w celu uniknięcia 'kolizji' plików należących do pakietów binarnych (dla których przeznaczono /usr) z 'naszymi' podczas ew. aktualizacji systemu. Nie polecam instalacji z prefixem do /usr, chyba że wiemy co robimy (np. konfigurujemy żródła z myślą o budowie pakietu binarnego dla naszej ulubionej dystrybucji)

    To właśnie ./configure i jego opcje są jedna z największych zalet własnoręcznej kompilacji i systemów typu source-based. Możemy zdecydowac, z których funkcji programu będziemy korzystać i (co za tym idzie) maja zostać wkompilowane, a które sa z naszego punktu zbędne i chcemy odchudzić z nich program.

    Działanie skryptu możemy podzielic na 2 fazy - sprawdzającą i generującą. Podczas pierwszej sprawdzana jest dostępność niezbędnych bibliotek i narzędzi w systemie, im więcej ficzerów (opcji, funkcji - używam tutaj popularnego spolszczenia od ang. 'features') wybierzemy (--with-costam) tym większe zalezności ("wymagania software'owe") będzie miał nasz kompilat. Działa to również w drugą stronę - jeśli ./configure przerywa działanie i krzyczy że brakuje mu libcośtam najpierw sprawdzamy czy dana biblioteka/narzędzie nie ma związku z ficzerem, którego nie zamierzamy używać - jeśli tak to możemy spokojnie ogołocić nasz program z danej funkcji uruchamiając skrypt jeszcze raz, tym razem z dodatkową opcja --without-cośtam. W przeciwnym wypadku - musimy "spełnić zależności" czyli doinstalowac co trzeba. Jeśli mimo tego ./configure dalej nie 'widzi' biblioteki/narzędzia, to nie trzeba się załamywać - prawdopodobnie to wina nietypowego prefiksu i wystarczy odp. skonfigurować konsolidator dynamiczny/zmienną środowiskową $PATH aby rozwiązać problem, ale to już temat na osobny wpis.

    Drugą fazą procesu jest automatyczne tworzenie plików makefile, które są fundamentem kolejnego etapu, czyli właściwej kompilacji. I tu niespodzianka bo..

    ..właściwa kompilacja sprowadza się tylko do jednego polecenia:

    $ make [opcje]

    Warto wspomnieć o opcji -jN (gdzie N to liczba procesorów + 1). Definiuje ona maksymalną ilość operacji wykonywanych jednocześnie.
    Jeśli zdefiniowaliśmy własne flagi kompilatora i eksportujemy je globalnie (np. w
    /etc/profile albo /etc/make.conf) lub lokalnie (np. w ~/.bashrc) wystarczy nam samo polecenie make. W przeciwnym wypadku właśnie w tej chwili możemy podać nasze flagi kompilatora. Przykład:

    $ CFLAGS="-march=athlon-xp -O2 -fomit-frame-pointer -DNDEBUG" CXXFLAGS=$CFLAGS LDFLAGS="-s -z combreloc" make -j2

    Jeśli otrzymamy komunikat informujący o 'braku celu do wykonania' oznacza to, że pliki makefile, z których korzysta make nie zostały utworzone. Prawdopodobnie przeoczyliśmy, że ./configure zakończyło się niepowodzeniem.

    Ostatnim krokiem jest instalacja. Służy do tego proste polecenie:

    # make install

    Prosze zwrócić uwagę na znak zachęty - jest to #, ponieważ tę operację wykonujemy z root'a (tzn. wykonujemy ją z poziomu tego użytkownika, który ma prawo zapisu w katalogu podanym jako prefiks. Jeśli instalujemy oprogramowanie w naszym katalogu domowym, możemy ten krok wykonać z poziomu zwykłego użytkownika).

    Co prawda mamy możliwość odinstalowania programu poprzez wywołanie polecenia make uninstall w katalogu, jednak nie jest to najwygodniejsze rozwiązanie ponieważ:

    • w przypadku instalacji kilku wersji, z tym samym prefiksem, może dojść do usunięcia plików, których nie chcielibyśmy stracić
    • musimy trzymać katalog 'roboczy', lub pamiętać jakich opcji/prefiksów używaliśmy aby w celu usunięcia programu z systemu wypakować źródła, uruchomić ./configure jeszcze raz, a zaraz po nim make uninstall

    Lepsze metody? Tworzenie pakietów! I wcale nie trzeba studiować dokumentacji, a potem wklepywać poleceń jedno po drugim - istnieje automat, zastępujący polecenie make install. Ten automat to checkinstall

    Jego użycie nie powino sprawiać większych problemów, można tworzyć zarówno pakiety TGZ (Slackware, Zenwalk i pochodne), DEB (Debian, Ubuntu i pochodne) oraz RPM (Red Hat, CentOS, Fedora Core i pochodne).

    Mimo wszystko jeśli chce się zostać developerem "pełną gębą" (dokładniej opiekunem kilku pakietów) jakiejś dystrybucji, założyć własne repozytorium, czy 'paczkować' programy z poza repozytorium i umieszczać np. na linuxpackages.net, wypada poznać natywne (klasyczne) metody tworzenia pakietów. Checkinstall jest świetnym narzędziem, ale nie oferuje 100% kontroli nad tym co się dzieje. Jeśli tworzymy pakiety binarne tylko dla siebie, będzie niezastąpiony.

    W następnej części cyklu opiszę klasyczną metodę tworzenia pakietów TGZ dla Slackware. Podstawy już są ;) Zapraszam do komentowania.

    22 października 2008

    Maple12 i Wolne Oprogramowanie

    W trakcie wykładu z Metod Obliczeniowych prowadzący ogłosił mały konkurs polegający na opisaniu i ew. prezentacji sposobu eksportu animowanych 'plotów' wygenerowanych w programie Maple (został napisany w Javie i jest w pełni przenośny między wszystkimi platformami, na których działa JRE) do dowolnego formatu (animowana grafika, wideo). Postanowiłem podjąć się wyzwania i przy okazji pokazać jakie możliwości niesie ze sobą wolne oprogramowanie.

    Pierwszym pomysłem było zastosowanie pętli for w której przy każdym wykonaniu bloku instrukcji rysowany byłby plot dla konkretnej klatki a następnie eksportowany do formatu gif. W trakcie prac zupełnie przypadkowo odkryłem, że Maple w wersji 12 ma zaimplementowany eksport do animowaych gif'ów. Nie było sensu dalszych prac nad wynajdowaniem koła od nowa. Pierwszy próg pokonany.

    Poniżej prezentuję małe HOWTO które stworzyłem przy okazji zabawy:

    1. Eksport do GIF'a (animowana grafika):
      Klikamy prawym przyciskiem myszy na danym plocie, wybieramy export -> Graphics Interchange Format, definiujemy ścieżkę do której ma nastąpić eksport i zapisujemy. Dla ułatwienia następnych kroków zalecam eksportować do pustego katalogu.

    2. Eksport do MPEG (video):
      a) Korzystając z instrukcji zawartych w punkcie 1, eksportujemy animacje w Maple'u do formatu gif, do pustego katalogu (aby ułatwić sobie dalsze kroki).

      b) Otwieramy okno terminalu i przechodzimy do katalogu gdzie zapisalismy naszą animację w formacie gif. Konwertujemy animowanego gif'a na pliki w formacie jpg, gdzie każdy z nich zawiera 1 klatkę animacji. Ilość plików jest zależna od ilości klatek. Do tego celu używamy narzędzia convert dostępnego w pakiecie ImageMagick:

      $ convert nazwa.gif nazwa_%05d.jpg

      W wyniku otrzymamy serie plików graficznych w formacie jpg zawierajacych numer klatki w nazwie (nazwa_00001.jpg, nazwa_00002.jpg itd.)

      c) Za pomocą narzędzia ffmpeg sklejamy pliki jpg w film mpg:

      $ ffmpeg -r `ls -l *.jpg | wc -l` -i nazwa_%05d.jpg -y -an nazwa.mpg

      (`ls -l *.jpg | wc -l` zwraca nam ilosc plików z rozsz. jpg w danym katalogu)

    3. Eksport do innych formatów video sprowadza sie do encodingu przy pomocy np. mencodera (kuzyn mplayer'a) filmu w formacie mpg.
      Bardzo interesującym rozwiązaniem są nowoczesne kontenery audio/video, dzięki którym możemy np. stworzyć 1 plik video z zaimplementowanymi kilkoma ścieżkami dzwiękowymi/napisami (np. tłumaczenia w przypadku międzynarodowej konferencji naukowej - każdy otrzymuje ten sam plik z filmem i samodzielnie decyduje w jakim języku chce go oglądać).

    20 października 2008

    Zlecenie dla Politechniki Śląskiej wykonane.

    Jakiś czas temu dostałem propozycję stworzenia skórki dla Plone (systemu zarządzania treścią (CMS) stworzonym w języku Python) dla pewnego instytutu Politechniki Śląskiej. Zlecenie w głównej mierze polegało na stworzeniu nowego kaskadowego arkuszu styli (CSS) oraz przygotowaniu odpowiednich elementów graficznych. Ponieważ dłubanie w samym silniku systemu nie należało do moich kompetencji musiałem kombinowac w jaki sposób wpleść specjalnie przygotowane elementy graficzne w określony układ. Nieocenionym narzędziem w pracy okazała się wtyczka dla Firefoxa i pochodnych - Firebug. Cała oprawa graficzna została stworzona w wolnym i darmowym (licencja GNU GPL) GIMPie. Poznałem kilka nowych sztuczek i wzbogaciłem swoje portfolio o kolejne zlecenie dla PŚ - skromna inwestycja w przyszłość.
    Jeśli zleceniodawca również wyrazi zgodę - opublikuje motyw graficzny na jednej z wolnych licencji.

    Link do strony wkrótce.

    18 października 2008

    Slax i tworzenie własnych modułów

    Swego czasu zastanawiałem się nad stworzeniem swojej dystrybucji LiveCD lub modyfikacją istniejącej, tak aby odpowiadała moim wymaganiom - tzn. posiadało to co jest mi niezbędne i tylko to. Całkiem niedawno na jednym z for linuksowych napotkałem na pytanie początkującego użytkownika o sposób tworzenia własnych modułów w postaci archiwum LZM dla dystrybucji SLAX 6.x. Postanowiłem poszerzyć swoje horyzonty i poszperać za dobrym manualem i udało mi się spłodzić małe howto. Z góry zaznaczam, że bardzo przydatna (niezbędna?) przy tworzeniu własnych modułów jest wiedza i doświadczenie nt. budowy pakietów *.tgz wykorzystywanych w Slackware (o tym może kiedyś napiszę).

    Tyle słowem wstępu, przejdźmy do właściwej części wpisu.
    Mamy do wyboru kilka dróg:
    • od zera:

      1. tworzymy paczkę *.tgz z plikami konfiguracyjnymi i dodatkowym oprogramowaniem - wszystko wrzucamy w 1 pakiet
      2. konwertujemy paczkę na archiwum lzma:

        tgz2lzm pakiet.tgz moduł.lzm



    • łączymy różne pakiety tgz i ew. dołączamy własne pliki konfiguracyjne:

      1. rozpakowujemy paczki *.tgz do wcześniej utworzonego katalogu, np. /tmp/my_lzm_package/

        installpkg -root /tmp/my_lzm_package pakiet.tgz

        W ten sposób otrzymujemy drzewko katalogów w /tmp/my_lzm_package zawierające binarki, biblioteki itp. składniki danego pakietu.
      2. Jeśli trzeba to wprowadzamy własne modyfikacje
      3. konwertujemy drzewko katalogów na archiwum (moduł) lzma:

        dir2lzm /tmp/my_lzm_package paczka.lzm



    • modyfikacja istniejącego modułu (*.lzm):

      1. Rozpakowujemy archiwum lzm

        lzm2dir modul.lzm /tmp/my_lzm_package


      2. Postępujemy jak przy sposobie wyżej, z tym że 1 punkt mamy już z głowy. Możemy np. podmienić splashscreen wyświtlany podczas uruchamiania gimpa/xine lub dodać jakiś soft.

    • Przeglądanie zawartości modułów lzm pod dowolną dystrybucją (Uwaga! wymaga obsługi systemu plików squashfs w jądrze):

      1. Archiwa lzm możemy montować, tak jak obrazy *.iso, pendrive, czy płytki CD/DVD. Tworzymy katalog gdzie zamontujemy moduł:

        mkdir /mnt/moduly


      2. ... i montujemy:

        >mount -t squashfs -o loop /sciezka/do/modulu.lzm /mnt/moduly


      3. Pamiętajmy, że gdy skończymy przeglądanie zawartości i/lub będziemy chcieli podmontować inny moduł, należy najpierw odmontować dotychczas zamontowane archiwum lzm:

        umount /mnt/moduly

    Jeśli masz doświadczenie z tworzeniem pakietów binarnych dla slackware to pewnie już się domyślasz w jaki sposób kompilować soft ze źródeł i od razu tworzyć z niego moduły. Jeśli nie - to w przyszłości zamierzam napisać co nieco na ten temat.


    Jako wychowanemu na Slackware bardzo podoba mi się Slax oraz sposób tworzenia modułów. Myślę, ze to dobra alternatywa dla tworzenia własnego przenośnego distro od zera. Wystarczy utworzyć odpowiedni moduł zawierający certyfikat sieci eduroam i bez własnego komputera można cieszyć się uczelnianym WiFi, wykorzystując swoje ulubione narzędzia ;)

    Hello World!

    Witam,
    Jakis czas temu zdarzyło mi się popełnić kilka komentarzy, o charakterze uzupełniającym treść wpisu na pewnym blogu, a raczej stronie domowej.. Pomyślałem, że może warto zacząć spisywać na bieżąco swoje doświadczenia oraz przemyslenia zwiazane z systemem operacyjnym czy realizają przeróżnych projektów.
    Co z tego wyjdzie? Zobaczymy..