Arhiva kategorija: Programiranje upravljačkih programa. Pisanje jednostavnog Linux kernel modula. Struktura kernel modula i metode za njegovo kompiliranje

Linux: Kompletan vodič Kolisničenko Denis Nikolajevič

28.2. Sastavljanje modula

28.2. Sastavljanje modula

Mi ćemo kompajlirati file module.c. Da biste to učinili, trebat će vam instaliran gcc kompajler, datoteke zaglavlja i izvori kernela. Ako ste pročitali knjigu do ovog poglavlja, trebali biste već imati instalirane sljedeće pakete:

1. cpp - cpp predprocesor;

2. binutils - skup raznih pomoćnih programa (as, gprof, ld);

3. glibc-kerheaders - datoteke zaglavlja kernela;

4. glibc-devel - pomoćne datoteke za razvoj aplikacija korištenjem standardne C biblioteke;

5. gcc - gcc kompajler.

Ostaje samo instalirati kernel-source paket - izvorni kod za Linux kernel. Osim toga, morate biti sigurni da vaš kernel podržava dinamički učitavane module (odjeljak 20.3.2.3). Ako opcija Podrška za Omogući učitavanje modula je onemogućena, trebate ga omogućiti, spremiti konfiguracijsku datoteku kernela i ponovno kompajlirati kernel.

Gcc kompajler treba pozvati s mnogo opcija, tako da ćemo si olakšati rad, napisati ćemo makefile (odjeljak 21.2):

Listing 28.5. Makefile za izgradnju modula

PATH=/usr/include /usr/src/linux-2.4/include

MODFLAGS:= -O3 -Wall -DLINUX -D__KERNEL__ -I$(PATH)

modul.o: modul.c

$(CC) $(MODFLAGS) -c modul.c

Opcije kompilatora znače sljedeće:

O3: koristit će se treća razina optimizacije (što je to, saznat ćete u sustavu pomoći gcc: man gcc);

Zid: omogući sva upozorenja;

DLINUX: generiranje koda za Linux;

I$(PATH): odredi put pretraživanja za datoteke zaglavlja. Prema zadanim postavkama, kompajler traži datoteke zaglavlja u direktoriju /usr/include, ali možda ih neće biti potrebne datoteke. Na primjer, za ALT Linux distribuciju (kernel 2.4.21), datoteke zaglavlja nalaze se u direktoriju /usr/include/linux-2.4.21rel-std-up.

Smjestite makefile u isti direktorij kao module.c i pokrenite make naredbu. Nakon što ga izvršite, dobit ćete datoteku module.o koja će se nalaziti u istom direktoriju.

# insmod modul.o

Vidjet ćete poruku Moj modul: Pokreće se... Ista poruka bit će zapisana u log datoteku /var/log/messages .

Iz knjige C++ autora Hill Murray

1.1.2 Kompilacija Odakle su došli izlazni tok cout i kod koji implementira izlaznu operaciju ““? C++ program mora biti kompajliran da proizvede izvršni kod. U svojoj jezgri, proces kompilacije je isti kao za C, i uključuje većinu unosa

Iz knjige Fedora 8 User Guide Autor

3.4.3. Kompilacija U pravilu se izvorni kodovi programa distribuiraju u obliku arhive s "dvostrukim nastavkom" - .tar.gz. Izvorni kod se obično raspakira u /usr/src direktorij. Stoga, za raspakiranje arhive morate pokrenuti sljedeće naredbe: sucd /usr/srcgunzip archive.tar.gztar xvf

Iz knjige Linux za korisnika Autor Kostromin Viktor Aleksejevič

Iz knjige 200 najboljih programa za Linux Autor Jaremčuk Sergej Akimovič

17.5.6. Kompajliranje modula Ako ste konfigurirali neke upravljačke programe kao zasebne module (odabrali ste opciju “m” kada ste odgovarali na neka pitanja tijekom konfiguracije), tada morate također pokrenuti naredbu make modules, a zatim naredbu make modules_install. U datoteci Documentation/modules.txt možete

Iz knjige Programski jezik C# 2005 i platforma .NET 2.0. autor Troelsen Andrew

Prevođenje programa Čak i nakon pojave paketa, koji su već bili prevedeni programi, prevođenje je dugo ostalo i za neke ostaje glavni način instalacije. Napomena Prvi predkompilirani skupovi pojavili su se u

Iz knjige Asterisk™: Budućnost telefonije, drugo izdanje Autor Meggelen Jim Wang

Uvjetno prevođenje Drugi skup direktiva pretprocesora (#if, #elif, #else, #endif) omogućuje vam prevođenje bloka programskog koda uvjetno, na temelju unaprijed definiranih simbola. Klasičan slučaj upotrebe ovih direktiva je identifikacija bloka

Iz knjige Linux mrežni alati autor Smith Roderick W.

Iz knjige Programski jezik C za osobno računalo autor Bočkov S. O.

Kompajliranje libpri Biblioteke libpri ne koriste program autoconf za postavljanje okoline izgradnje ili prozora odabira komponente izgradnje jer nisu potrebni; stoga je instalacija pojednostavljena. libpri koriste različiti proizvođači hardvera

Iz knjige Linux: Potpuni vodič Autor Kolisničenko Denis Nikolajevič

Prevođenje Asterisk-a Nakon prevođenja i instaliranja zaptel i libpri paketa (ako je potrebno), možete nastaviti s instaliranjem Asterisk-a. Ovaj odjeljak pokriva standardnu ​​instalaciju i uvodi neke alternativne make argumente koji se mogu koristiti

Iz knjige Linux programiranje s primjerima Autor Robbins Arnold

Kompajliranje kernela Nakon što ste konfigurirali kernel sustava pokretanjem make xconfig ili druge naredbe dane na početku ovog poglavlja, morate kompajlirati kernel i instalirati njegove module. Da biste to učinili, trebate pokrenuti sljedeće naredbe:# make dep# make bzImage# make modules# make

Iz knjige Jezik C - Vodič za početnike autor: Prata Steven

Uvjetno prevođenje Ovaj odjeljak opisuje direktive koje kontroliraju uvjetno prevođenje. Ove vam upute dopuštaju isključivanje bilo kojeg dijela iz procesa kompilacije izvorna datoteka provjerom uvjeta (konstanta

Iz knjige Linux očima hakera Autor Flenov Mihail Evgenijevič

20.5. Kompajliranje kernela 20.5.1. Zašto ažurirati kernel? Linux se razvija brže od bilo kojeg drugog operativnog sustava. Redovito se pojavljuju nove verzije kernela, implementirajući nove funkcije. Na primjer, distribucija Fedora Core 4 na kernelu 2.6.11 jedva je uspjela izaći, a već postoji stabilna verzija na www.kernel.org

Iz knjige operacijski sustav UNIX Autor Robačevski Andrej M.

15.2. Kompajliranje za ispravljanje pogrešaka Za korištenje programa za ispravljanje pogrešaka izvornog koda, program za ispravljanje pogrešaka izvršna datoteka mora se prevesti s opcijom prevodioca -g. Ova opcija uzrokuje da prevoditelj ugradi dodatne identifikatore za ispravljanje pogrešaka u objektni kod; to je

Iz autorove knjige

Zašto kompilacija? Čitatelji koji su koristili jezik BASIC mogli bi se zapitati zašto postoji toliko mnogo koraka za izvođenje programa. Čini se da ovaj način kompilacije traje duže (au nekim slučajevima to doista može biti slučaj). Ali, budući da je u

Iz autorove knjige

3.8.3. Prevođenje jezgre Kada se instalira iz RPM paketa, dobivamo modularnu jezgru u kojoj se upravljački programi uređaja mogu ili prevesti u jezgru ili učitati zasebno. Ovaj kernel radi sporije, ali vam omogućuje ažuriranje upravljačkih programa jednostavnom zamjenom

Iz autorove knjige

Kompilacija Postupak za izradu većine aplikacija je opći i prikazan je na sl. 2.2. Riža. 2.2. Shema kompilacije programa Prva faza je faza kompilacije, kada kompajler obrađuje izvorne datoteke programa, uključujući datoteke zaglavlja.

Kada se pojavi potreba za stvaranjem moćnog i pouzdan sustav na Temeljen na Linuxu(bilo da se radi o servisiranju tehnoloških procesa, web hostingu i sl.), tada je vrlo često potrebno konfigurirati jezgru sustava na način da cijeli sustav radi učinkovitije i pouzdanije. Iako je Linux kernel univerzalan, postoje situacije kada ga je iz objektivnih razloga potrebno "podešavati". I sama arhitektura kernela to sugerira zbog svoje otvorenosti. Stoga su administratori Linux sustava oni ljudi kojima je važno znati i razumjeti neke općenite aspekte konfiguriranja Linux kernela.

Metode konfiguracije jezgre Linuxa

Tijekom razvoja Linuxa postupno su se pojavila četiri glavna načina za konfiguriranje njegove jezgre:

  • izmjena prilagođenih parametara jezgre;
  • sastavljanje kernela iz izvornih kodova uz unošenje potrebnih izmjena i/ili dopuna u tekstove izvornih kodova kernela;
  • dinamičko povezivanje novih komponenti (funkcionalnih modula, upravljačkih programa) na postojeći sklop jezgre;
  • prosljeđivanje posebnih uputa jezgri tijekom bootstrap i/ili pomoću bootloadera (npr. GRUB).

Ovisno o konkretnoj situaciji, treba koristiti jednu ili drugu metodu. Ali odmah treba napomenuti da je zapravo najjednostavniji prvi - postavljanje parametara kernela. Najteže je kompajlirati kernel iz izvornog koda.

Podesivi parametri kernela

Jezgra sustava Linux razvijena je na takav način da je uvijek bilo moguće biti što fleksibilniji (međutim, kao i sve ostalo u UNIX sustavi i Linux) konfigurirati, prilagođavajući ga potrebnim radnim uvjetima i hardverskom okruženju. I to na takav način da bi to bilo moguće dinamički na već gotovu sklopu kernela. Drugim riječima, administratori sustava mogu u svakom trenutku napraviti prilagodbe koje utječu na rad same jezgre i njenih pojedinačnih komponenti.

Za provedbu ovog zadatka postoji posebno sučelje između jezgre i programa na korisničkoj razini temeljeno na informacijskim kanalima. Upute koje postavljaju vrijednosti za parametre jezgre šalju se kroz ove kanale.

Ali kao i sve u UNIX i Linux sustavima, postavljanje parametara jezgre putem informacijskih kanala vezano je za datotečni sustav. Za pregled i upravljanje konfiguracijom jezgre postoje posebne datoteke. To su obične datoteke, ali igraju ulogu posrednika u pružanju sučelja za dinamičku interakciju s jezgrom. Međutim, dokumentacija o ovom aspektu, posebice o opisu specifičnih parametara i njihovih vrijednosti, prilično je oskudna. Jedno mjesto gdje možete dobiti neke informacije o ovoj temi je poddirektorij Documentation/sysent u izvornom direktoriju kernela.

Radi jasnoće, vrijedi razmotriti mali primjer koji pokazuje kako konfigurirati najveći broj istodobnih brojeva pomoću parametra jezgre otvorene datoteke u sustavu:

$ cat /proc/sys/fs/file-max 34916 $ sudo sh -c "echo 32768 > /proc/sys/fs/file-max"

Kao što vidite, na ovu se tehniku ​​možete brzo naviknuti i neće vam se činiti da je nešto teško. Iako je ova metoda prikladna, promjene se ne spremaju nakon ponovnog pokretanja sustava.

Također možete koristiti specijalizirani uslužni program sysctl. Omogućuje vam dobivanje varijabilnih vrijednosti izravno iz naredbeni redak, ili popis parova oblika varijabla=vrijednost iz datoteke. U početnoj fazi učitavanja, uslužni program čita početne vrijednosti nekih parametara koji su navedeni u datoteci /etc/sysctl.conf. Više detaljne informacije o korisnosti sysctl možete pronaći na stranicama.

Sljedeća tablica navodi neke konfigurabilne parametre jezgre:

Katalog Datoteka/parametar Svrha
S automatsko izbacivanje Automatsko otvaranje ladice za CD kada je CD-ROM jedinica isključena
F file-maks najveći broj otvorenih datoteka. Za sustave koji moraju raditi s velikim brojem datoteka, ovu vrijednost možete povećati na 16384
F inode-max Maksimalan broj otvorenih inodova u jednom procesu. Korisno za aplikacije koje otvaraju desetke tisuća datoteka
DO
DO printk ratelimit Minimalni interval između poruka kernela, u sekundama
DO printk_ratelimi_burst Broj poruka koje se moraju primiti prije nego što printk minimalna vrijednost intervala poruka postane aktivna
DO shmmax Maksimalna veličina zajedničke memorije
N conf/default/rp_filter Omogućuje mehanizam za provjeru rute do izvorne datoteke
N icmp_echo_ Zanemari ICMP zahtjeve ako je vrijednost 1
N icmp_echo_ Zanemari ICMP zahtjeve za emitiranje ako je vrijednost 1.
N ip_naprijed Proslijedi IP pakete ako je vrijednost 1. Na primjer, kada se Linux stroj koristi kao usmjerivač, ta bi vrijednost trebala biti postavljena na 1
N ip_local_port_ Raspon lokalnih priključaka dodijeljenih prilikom konfiguriranja veza. Kako bi se poboljšala izvedba poslužitelja koji pokreću mnogo odlaznih veza, ovaj bi se parametar trebao proširiti na 1024-65000
N tcp_fin_timeout Interval čekanja (u sekundama) za konačni RN paket. Kako biste poboljšali performanse poslužitelja koji prolaze velike količine prometa, morate postaviti niže vrijednosti (oko 20)
N tcp_syncookies Zaštita od napada propagacijom SYN paketa. Mora biti uključeno ako postoji mogućnost DOS napada

Legenda: F - /proc/sys/fs, N - /proc/sys/net/ipv4, K - /proc/sys/kernel, C - /proc/sys/dev/cdrom.

$ sudo sysctl net.ipv4.ip_forward=0

Pokretanje ove naredbe onemogućit će prosljeđivanje IP paketa. Postoji jedna mana u sintaksi ove naredbe: znakovi točke u "net.ipv4.ip_forward" zamjenjuju znakove kose crte u putanji datoteke ip_forward.

Kada trebam izgraditi novu verziju kernela?

Trenutno se Linux kernel razvija vrlo brzo i brzo. Često proizvođači distribucija nemaju vremena implementirati nove verzije kernela u svoje sustave. U pravilu će svi novopridošli “trikovi” biti potrebniji ljubiteljima egzotike, entuzijastima, vlasnicima novih uređaja i opreme te jednostavno znatiželjnicima – dakle, uglavnom onima koji na raspolaganju imaju računalo običnog korisnika.

Za poslužiteljske strojeve, međutim, malo je vjerojatno da će moda imati neki značaj, a nove tehnologije uvode se tek nakon što su u praksi dokazale svoju pouzdanost i učinkovitost. ispitne klupe ili čak platforme. Svi su iskusni Administrator sustava zna da je mnogo pouzdanije jednom konfigurirati nešto što može i treba raditi dobro i pouzdano nego pokušavati beskrajno nadograđivati ​​sustav. Uostalom, to zahtijeva mnogo sati rada (na kraju krajeva, morate sastaviti kernel iz izvornih kodova, što je prilično teško) i održavanja, što je prilično skup zadatak, jer uz sve ostalo zahtijeva duboku redundanciju - poslužitelji ne bi trebali stati bez organiziranja "vruće" (a još više bez "hladne") rezerve.

Stoga uvijek vrijedi odvagnuti sve faktore i procijeniti isplati li se uopće ažurirati manje zakrpe koje ne utječu na rad sustava ili uvođenje novih upravljačkih programa za uređaje, od kojih ovaj trenutak nije u sustavu i ne očekuje se uskoro.

Ako odlučite ažurirati verziju kernela tako da ga sami sastavite, tada morate saznati je li ova verzija stabilna. Prethodno je sustav numeriranja verzija jezgre Linuxa bio organiziran na takav način da su parni brojevi verzija značili stabilno izdanje, neparni brojevi značili su još uvijek "sirovo". Trenutno se ovo načelo ne poštuje uvijek i ovu točku treba razjasniti iz informacija na službenoj web stranici kernel.org.

Konfiguriranje parametara jezgre

Konfiguracija za buduću izgradnju Linux kernela pohranjena je u .config datoteci. Malo ljudi se bavi ručnim stvaranjem i uređivanjem ove datoteke, jer, prvo: to je složena sintaksa koja je daleko od one "najčitljivije ljudima", i drugo: postoje načini za automatsko generiranje konfiguracije izgradnje jezgre s prikladnim grafičkim (ili pseudo-grafičko) sučelje. Popis glavne naredbe za konfiguriranje izgradnje kernela:

  • make xconfig - preporučuje se ako koristite KDE grafičko okruženje. Vrlo zgodan alat;
  • napravi gconfig - najbolja opcija za upotrebu u grafičko okruženje GNOME;
  • napraviti konfiguraciju izbornika - ovaj uslužni program treba koristiti u pseudografskom načinu rada. Nije tako zgodan kao prethodna dva, ali se adekvatno nosi sa svojim funkcijama;
  • make config je najnezgodnija opcija "konzole", koja prikazuje zahtjeve za postavljanje vrijednosti svakog parametra jezgre. Ne dopušta promjenu već navedenih parametara.

Gotovo sve opcije (osim posljednje) omogućuju brzu pomoć za svaki parametar, traženje željenog parametra (ili konfiguracijskog odjeljka), dodavanje dodatnih komponenti i upravljačkih programa u konfiguraciju, a također pokazuju kako se određena komponenta može konfigurirati - kao ugrađenu komponentu u kernel ili kao modul koji se može učitavati, te podržava li uopće opciju kompajliranja kao modula koji se može učitavati.

Naredba make oldconfig može biti vrlo korisna, dizajnirana za prijenos postojeće konfiguracije iz druge verzije (build) kernela u novu verziju. Ova naredba čita konfiguraciju iz migrirane .config datoteke sa starom verzijom, utvrđuje koje su nove opcije dostupne za trenutnu verziju i nudi ih omogućiti ili ostaviti kakve jesu.

Da biste konfigurirali izgradnju Linux kernela, trebate otići u direktorij izvornog koda i pokrenuti jednu od naredbi za generiranje konfiguracije.

Kao rezultat gornjih naredbi, .conf datoteka će biti generirana, fragment sadržaja koji može biti sljedeći:

# # Automatski generirana datoteka; NEMOJTE UREĐIVATI. # Linux/x86 4.20.7 Konfiguracija kernela # # # Kompajler: gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0 # CONFIG_CC_IS_GCC=y CONFIG_GCC_VERSION=70300 CONFIG_CLANG_VERSION=0 CONFIG_IRQ_WORK=y CONFIG_BUILDTIME _EXT ABLE_SORT=y CONFIG_THREAD_INFO_IN_TASK=y # # Opće postavke # CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_COMPILE_TEST nije postavljen CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO nije postavljen CONFIG_BUILD_SALT="" CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_ KERNEL_LZMA =y CONFIG_HAVE_KERNEL_XZ=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_HAVE_KERNEL_LZ4=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 nije postavljen # CONFIG_KERNEL_LZMA nije postavljen # CONFIG_KERNEL_XZ nije postavljen # CONFIG_KERNEL_LZO nije postavljen # CONFIG_KERNEL_LZ4 nije postavljen CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POS IX_MQUEUE =y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_USELIB=y

Kao što vidite, u ovom kodu nema ničeg privlačnog ručno uređivanje, što se čak spominje u komentaru na početku .config datoteke. Znak "y" na kraju bilo kojeg od redaka označava da će odgovarajuća komponenta biti sastavljena kao dio kernela, "m" - kao plug-in modul. Datoteka .config ne sadrži objašnjenja ili opise svake komponente ili parametra - trebali biste proučiti odgovarajuću dokumentaciju za te probleme.

Kompajliranje kernela

Najteži dio kod kompajliranja Linux kernela je stvaranje konfiguracije za izgradnju, budući da morate znati koje komponente uključiti. Iako korištenje naredbi make xconfig, make gconfig, make menuconfig pruža standardnu ​​radnu konfiguraciju s kojom će sustav raditi na većini hardverskih platformi i konfiguracija. Jedino pitanje je pravilno konfigurirati kernel bez nepotrebnih komponenti koje zauzimaju dodatne resurse tijekom njegovog rada.

Dakle, da biste uspješno konfigurirali i kompajlirali kernel, trebate učiniti sljedeće:

  • idite u direktorij s izvornim kodovima kernela. Obično se “izvori” za Linux kernel nalaze u direktoriju /usr/src ili se mogu preuzeti s web stranice kernel.org na bilo koje prikladno mjesto;
  • pokrenite make xconfig, make gconfig ili make menuconfig;
  • pokrenite naredbu make dep (može se izostaviti za verziju kernela 2.6.x i novije);
  • pokrenite naredbu make clean (za čišćenje svega što bi moglo ometati uspješnu izgradnju);
  • pokrenuti napraviti naredbu;
  • pokrenite naredbu make modules_install;
  • kopirajte datoteku /arch/architecture_name/boot/bzImage u /boot/vmlinuz. Ovdje se direktorij /arch nalazi u direktoriju s izvornim kodovima Linux kernela, architecture_name je direktorij s nazivom odgovarajuće arhitekture (određene u fazi konfiguracije). Naziv izgrađene binarne slike jezgre bzImage može biti drugačiji;
  • kopirajte datoteku /arch/architecture_name/boot/System.map u /boot/System.map;
  • napravite promjene u konfiguracijskim datotekama pokretačkog programa sustava /etc/lilo.conf (za LILO) ili /boot/grub/grub.conf - za GRUB, te im također dodajte odgovarajuću konfiguraciju i parametre pokretanja za novi kernel.

Ako pronađete grešku, označite dio teksta i kliknite Ctrl+Enter.

Napomena: u budućnosti planiram koristiti T2 sustav za kompajliranje kernela i modula za Puppy. T2 je trenutno instaliran za kompajliranje kernela i brojnih dodatnih modula, ali ne i verzija koja se trenutno koristi u Puppyju. Namjeravam izvršiti sinkronizaciju u budućim verzijama Puppyja, tako da će se kernel kompajliran u T2 koristiti u Puppyju. Pogledajte http://www.puppyos.net/pfs/ za dodatne informacije o Puppyju i T2.

Puppy ima vrlo jednostavan način korištenja C/C++ kompilatora dodavanjem jedne datoteke, devx_xxx.sfs, gdje je xxx broj verzije. Na primjer, Puppy 2.12 bi imao datoteku za razvoj usklađenosti pod nazivom devx_212.sfs. Kada radite u LiveCD modu, postavite devx_xxx.sfs datoteku na isto mjesto kao i vaša osobna datoteka postavki pup_save.3fs, koja se obično nalazi u /mnt/home/ direktoriju. Ovo se također odnosi na druge načine instalacije koji imaju datoteku pup_save.3fs. Ako je Puppy instaliran na HDD s potpunom instalacijom "Opcije 2", tada u ovom slučaju nema osobne datoteke, pogledajte web stranice Puppy za kompajliranje s različitim opcijama konfiguracije, tako da moduli nisu kompatibilni. Ove verzije zahtijevaju samo jednu zakrpu za squashfs. Puppy 2.12 ima kernel 2.6.18.1 i ima tri popravka; squashfs, zadani loglevel konzole i popravak za isključivanje.

Ove naredbe za zakrpu kernela dane su isključivo radi vaše samoedukacije, budući da je zakrpani kernel već dostupan...

Prvo što trebate učiniti je preuzeti sam kernel. Nalazi se kako bi se pronašla poveznica do odgovarajućeg mjesta za preuzimanje. Ovo bi trebao biti "drevni" izvor dostupan na kernel.org ili njegovim zrcalima.

Spojite se na Internet, preuzmite kernel u mapu /usr/src. Zatim ga raspakirajte:

cd / usr/ src tar -jxf linux-2.6.16.7.tar.bz2 tar -zxf linux-2.6.16.7.tar.gz

Trebali biste vidjeti ovu mapu: /usr/src/linux-2.6.16.7. Zatim morate biti sigurni da ova veza pokazuje na kernel:

ln -sf linux-2.6.16.7 linux ln -sf linux-2.6.16.7 linux-2.6.9

Morate primijeniti sljedeće popravke kako biste imali potpuno isti izvor koji se koristi prilikom kompajliranja kernela za Puppy. U suprotnom, dobit ćete poruke o pogrešci "nerazriješeni simboli" kada kompajlirate upravljački program i zatim ga pokušate koristiti s Puppy kernelom. Primjena popravka za squashfs

Drugo, primijenite Squashfs patch. Squashfs popravak dodaje podršku za Squashfs rad sustav datoteka samo za čitanje.

Preuzmite zakrpu, squashfs2.1-patch-k2.6.9.gz, u mapu /usr/src. Imajte na umu da je ovaj popravak napravljen za verziju kernela 2.6.9, ali nastavlja raditi u verzijama 2.6.11.x sve dok postoji referenca na linux-2.6.9. Zatim primijenite popravak:

Cd/ usr/ src gunzip squashfs2.1-patch-k2.6.9.gz cd/ usr/ src/ linux-2.6.11.11

Napomena, p1 ima broj 1, a ne simbol l... (Sjajna šala - cca. prijevod)

patch --dry-run -p1< ../ squashfs2.1-patch patch -p1 < ../ squashfs2.1-patch

Spreman! Kernel je spreman za kompajliranje!

Kompajliranje kernela

Morate nabaviti konfiguracijsku datoteku za kernel. Njegov primjerak nalazi se u mapi /lib/modules.

Zatim slijedite ove korake:

Cd/ usr/ src/ linux-2.6.18.1

Ako postoji .config datoteka, privremeno je kopirajte negdje ili je preimenujte.

make clean učiniti mrproper

Kopirajte .config datoteku za Puppy u /usr/src/linux-2.6.18.1... Imat će drugačija imena u /lib/modules, pa preimenujte u .config... Sljedeći koraci čitaju .config datoteku i generiraju novi.

napraviti menuconfig

...napravite promjene koje želite i spremite ih. Sada ćete imati novu .config datoteku i trebali biste je kopirati negdje na sigurno. Pogledajte napomenu u nastavku

napraviti bzImage

Sada ste kompajlirali kernel.

Odlično, naći ćete Linux kernel u /usr/src/linux-2.6.18.1/arch/i386/boot/bzImage

Sastavljanje modula

Sada idite u /lib/modules i ako već postoji mapa pod nazivom 2.6.18.1, preimenujte mapu 2.6.18.1 u 2.6.18.1-old.

Sada instalirajte nove module:

Cd/ usr/ src/ linux-2.6.18.1 make modules make modules_install

...nakon ovoga trebali biste pronaći nove module instalirane u mapi /lib/modules/2.6.18.1.

Imajte na umu da zadnji korak iznad pokreće program "depmod" i to može dati poruke o pogrešci o nedostajućim simbolima za neke od modula. Ne brinite o tome - jedan od programera je zeznuo i to znači da ne možemo koristiti taj modul.

Kako koristiti novi kernel i module

Bolje je ako imate instaliran Puppy Unleashed. Zatim se tarball proširuje i postoje 2 direktorija: "boot" i "kernels".

"Boot" sadrži strukturu datoteke i skriptu za stvaranje početne virtualni disk. Tamo ćete morati staviti neke module kernela.

Direktorij "kernels" ima direktorij kernels/2.6.18.1/ i morat ćete zamijeniti module svojim ažuriranim. Ne morate ga zamijeniti ako ste ponovno kompajlirali istu verziju kernela (2.6.18.1).

Imajte na umu da u kernels/2.6.18.1 postoji datoteka pod nazivom "System.map". Trebali biste ga preimenovati i zamijeniti novim iz /usr/src/linux-2.6.18.1. Pregledajte mapu kernels/2.6.18.1/ i trebali biste znati što treba ažurirati.

Ako ste kompajlirali kernel u punoj Puppy instalaciji, možete se ponovno pokrenuti koristeći novi kernel. make modules_install je korak iznad za instaliranje novih modula u /lib/modules/2.6.18.1, ali također morate instalirati novi kernel. Pokrećem se s Grubom i samo kopiram novi kernel u /boot direktorij (i preimenujem datoteku iz bzImage u vmlinuz).

Napomena u vezi menuconfig. Koristim ga godinama pa neke stvari uzmite zdravo za gotovo, no početnik bi mogao biti zbunjen kada želi napustiti program. U izborniku najviše razine postoji izbornik za spremanje konfiguracije - zanemarite ga. Samo pritisnite tipku TAB (ili desnu strelicu) kako biste označili "gumb" Izlaz i pritisnite tipku ENTER. Zatim ćete biti upitani želite li spremiti novu konfiguraciju i vaš odgovor bi trebao biti Da.

Linux pruža snažan i opsežan API za aplikacije, ali ponekad to nije dovoljno. Za interakciju s hardverom ili izvođenje operacija s pristupom privilegiranim informacijama u sustavu potreban je upravljački program jezgre.

Modul jezgre Linuxa je kompajliran binarni kod, koji je umetnut izravno u Linux kernel, radi u prstenu 0, unutarnjem i najmanje sigurnom izvršnom prstenu u x86-64 procesoru. Ovdje se kod izvršava potpuno bez ikakvih provjera, ali nevjerojatnom brzinom i uz pristup svim resursima sustava.

Nije za obične smrtnike

Pisanje modula jezgre Linuxa nije za one sa slabim srcem. Promjenom kernela riskirate gubitak podataka. Kod kernela nema standardnu ​​zaštitu, kao u konvencionalnom Linux aplikacije. Ako pogriješite, onda spustite cijeli sustav.

Ono što situaciju čini gorom je to što se problem ne mora nužno pojaviti odmah. Ako modul prekine sustav odmah nakon učitavanja, to je najbolji scenarij kvara. Što je više koda, to je veći rizik od beskonačnih petlji i curenja memorije. Ako niste pažljivi, problemi će se postupno povećavati kako stroj radi. Na kraju se važne strukture podataka, pa čak i međuspremnici mogu prebrisati.

Tradicionalne paradigme razvoja aplikacija mogu se uglavnom zaboraviti. Osim učitavanja i pražnjenja modula, pisat ćete kod koji reagira na sistemske događaje umjesto da slijedi sekvencijalni obrazac. Kada radite s kernelom, pišete API, a ne same aplikacije.

Također nemate pristup standardna knjižnica. Iako kernel nudi neke funkcije kao što su printk (koji je zamjena za printf) i kmalloc (koji radi slično kao malloc), uglavnom ste prepušteni sami sebi. Osim toga, trebali biste potpuno počistiti za sobom nakon istovara modula. Ovdje nema odvoza smeća.

Potrebne komponente

Prije nego počnete, trebali biste provjeriti imate li sve potrebne alate za posao. Što je najvažnije, trebate Linux stroj. Znam da je ovo neočekivano! Iako će poslužiti bilo koja distribucija Linuxa, u ovom primjeru koristim Ubuntu 16.04 LTS, pa ćete možda morati malo izmijeniti instalacijske naredbe ako koristite druge distribucije.

Drugo, trebate ili zasebno fizičko računalo ili virtualno računalo. Osobno radije radim za virtualni stroj, ali izaberite sami. Ne preporučujem korištenje vašeg glavnog računala zbog gubitka podataka kada pogriješite. Kažem "kada", a ne "ako" jer ćete sigurno zakačiti automobil barem nekoliko puta tijekom procesa. Vaš posljednje promjene u kodu može još uvijek biti u međuspremniku za pisanje u vrijeme panike kernela, tako da i vaši izvori mogu biti oštećeni. Testiranje u virtualnom stroju uklanja te rizike.

Konačno, morate znati barem malo C. C++ runtime je prevelik za kernel, tako da morate pisati u čistom, golom C. Nešto znanja o asemblerskom jeziku također je korisno za interakciju s hardverom.

Instalacija razvojnog okruženja

Na Ubuntuu trebate pokrenuti:

Apt-get install build-essential linux-headers-`uname -r`
Instaliramo najvažnije razvojne alate i zaglavlja kernela potrebne za ovaj primjer.

Primjeri u nastavku pretpostavljaju da radite odozdo redoviti korisnik, ne root, već da imate sudo privilegije. Sudo je potreban za učitavanje modula kernela, ali želimo raditi izvan roota kad god je to moguće.

Početi

Počnimo pisati kod. Pripremimo naše okruženje:

Mkdir ~/src/lkm_example cd ~/src/lkm_example
Pokrenite svoj omiljeni editor (vim u mom slučaju) i kreirajte datoteku lkm_example.c sa sljedećim sadržajem:

#uključi #uključi #uključi MODULE_LICENSE("GPL"); MODULE_AUTHOR(“Robert W. Oliver II”); MODULE_DESCRIPTION(“Jednostavan primjer Linux modula.”); MODULE_VERSION(“0,01”); static int __init lkm_example_init(void) ( printk(KERN_INFO “Zdravo, svijete!\n”); return 0; ) static void __exit lkm_example_exit(void) ( printk(KERN_INFO “Zbogom, svijete!\n”); ) module_init(lkm_example_init ); izlaz_modula(lkm_primjer_izlaska);
Dizajnirali smo najjednostavniji mogući modul, pogledajmo pobliže njegove najvažnije dijelove:

  • include navodi datoteke zaglavlja potrebne za razvoj Linux kernela.
  • MODULE_LICENSE može se postaviti na različite vrijednosti ovisno o licenci modula. Pogledati puni popis trčanje:

    Grep “MODULE_LICENSE” -B 27 /usr/src/linux-headers-`uname -r`/include/linux/module.h

  • Postavili smo init (učitavanje) i exit (istovar) kao statičke funkcije koje vraćaju cijele brojeve.
  • Obratite pažnju na korištenje printk umjesto printf. Također se opcije za printk razlikuju od printf. Na primjer, oznaka KERN_INFO za deklariranje prioriteta zapisivanja za određeni red navedena je bez zareza. Kernel obrađuje te stvari unutar funkcije printk kako bi uštedio memoriju steka.
  • Na kraju datoteke možete pozvati module_init i module_exit i odrediti funkcije za učitavanje i istovar. To omogućuje proizvoljno imenovanje funkcija.
Međutim, još ne možemo kompajlirati ovu datoteku. Potreban Makefile. Ovaj osnovni primjer će biti dovoljan za sada. Imajte na umu da je make vrlo izbirljiv u pogledu razmaka i kartica, stoga svakako koristite kartice umjesto razmaka gdje je to prikladno.

Obj-m += lkm_example.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r )/build M=$(PWD) čisto
Ako pokrenemo make, on bi trebao uspješno kompilirati naš modul. Rezultat će biti datoteka lkm_example.ko. Ako se pojave pogreške, provjerite jesu li navodnici u izvornom kodu ispravno postavljeni i nisu slučajno u UTF-8 kodiranju.

Sada možete implementirati modul i testirati ga. Da bismo to učinili, pokrećemo:

Sudo insmod lkm_example.ko
Ako je sve u redu, onda nećete vidjeti ništa. Printk funkcija daje izlaz ne u konzolu, već u kernel log. Za pregled morate pokrenuti:

Sudo dmesg
Trebali biste vidjeti redak "Hello, World!" s vremenskom oznakom na početku. To znači da je naš kernel modul učitan i uspješno zapisan u kernel log. Također možemo provjeriti je li modul još uvijek u memoriji:

lsmod | grep “lkm_example”
Da biste uklonili modul, pokrenite:

Sudo rmmod lkm_example
Ako ponovno pokrenete dmesg, vidjet ćete unos "Zbogom, svijete!" Možete ponovno pokrenuti lsmod i provjeriti je li modul ispražnjen.

Kao što vidite, ovaj postupak testiranja je pomalo zamoran, ali se može automatizirati dodavanjem:

Test: sudo dmesg -C sudo insmod lkm_example.ko sudo rmmod lkm_example.ko dmesg
na kraju Makefilea i zatim izvoditi:

Napravi test
za testiranje modula i provjeru izlaza u dnevnik jezgre bez potrebe za pokretanjem zasebnih naredbi.

Sada imamo potpuno funkcionalan, iako potpuno trivijalan modul kernela!

Kopajmo malo dublje. Iako moduli jezgre mogu obavljati sve vrste zadataka, sučelje s aplikacijama jedan je od najčešćih slučajeva upotrebe.

Budući da aplikacijama nije dopušteno vidjeti memoriju u prostoru jezgre, moraju koristiti API za komunikaciju s njima. Iako tehnički postoji nekoliko načina za to, najčešći je stvaranje datoteke uređaja.

Vjerojatno ste već imali posla s datotekama uređaja. Naredbe koje spominju /dev/zero, /dev/null i slično komuniciraju s "nula" i "null" uređajima, koji vraćaju očekivane vrijednosti.

U našem primjeru vraćamo "Hello, World". Iako nije posebno korisna značajka za aplikacije još uvijek pokazuje proces interakcije s aplikacijom putem datoteke uređaja.

Evo cijelog popisa:

#uključi #uključi #uključi #uključi #uključi MODULE_LICENSE("GPL"); MODULE_AUTHOR(“Robert W. Oliver II”); MODULE_DESCRIPTION(“Jednostavan primjer Linux modula.”); MODULE_VERSION(“0,01”); #define DEVICE_NAME “lkm_example” #define EXAMPLE_MSG “Hello, World!\n” #define MSG_BUFFER_LEN 15 /* Prototipovi za funkcije uređaja */ static int device_open(struct inode *, struct file *); static int device_release(struct inode *, struct file *); static ssize_t device_read(struct file *, char *, size_t, loff_t *); static ssize_t device_write(struct file *, const char *, size_t, loff_t *); static int major_num; static int device_open_count = 0; statički char msg_buffer; statički znak *msg_ptr; /* Ova struktura ukazuje na sve funkcije uređaja */ static struct file_operations file_ops = ( .read = device_read, .write = device_write, .open = device_open, .release = device_release); /* Kada proces čita s našeg uređaja, ovo se poziva. */ static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset) ( int bytes_read = 0; /* Ako smo na kraju, vraćamo se na početak */ if (*msg_ptr = = 0) ( msg_ptr = msg_buffer; ) /* Stavite podatke u međuspremnik */ while (len && *msg_ptr) ( /* Međuspremnik je u korisničkim podacima, ne u kernelu, tako da ne možete samo referencirati * s pokazivačem. funkcija put_user obrađuje ovo za nas */ put_user(*(msg_ptr++), buffer++; return bytes_read) /* Poziva se kada proces pokuša pisati na naš uređaj */ static ssize_t device_write(struct file * flip, const char *buffer); , size_t len, loff_t *offset) ( /* Ovo je uređaj samo za čitanje */ printk(KERN_ALERT “Ova operacija nije podržana.\n”); return -EINVAL; ) /* Poziva se kada proces otvori naš uređaj * / static int device_open(struct inode *inode, struct file *file) ( /* Ako je uređaj otvoren, vrati zauzeto */ if (device_open_count) ( return -EBUSY; ) device_open_count++; try_module_get(THIS_MODULE); return 0; ) /* Poziva se kada proces zatvori naš uređaj */ static int device_release(struct inode *inode, struct file *file) ( /* Smanji otvoreni brojač i broj korištenja. Bez toga se modul ne bi ispraznio. */ device_open_count- -; module_put(THIS_MODULE); return 0; ) static int lkm_example_init(void) ( /* Ispuni međuspremnik */ strncpy(msg_buffer, EXAMPLE_MSG, MSG_BUFFER_LEN); /* Postavi msg_ptr na međuspremnik */ msg_ptr = msg_buffer ; /* Pokušajte registrirati znakovni uređaj */ major_num = register_chrdev(0, “lkm_example”, &file_ops);< 0) { printk(KERN_ALERT “Could not register device: %d\n”, major_num); return major_num; } else { printk(KERN_INFO “lkm_example module loaded with device major number %d\n”, major_num); return 0; } } static void __exit lkm_example_exit(void) { /* Remember - we have to clean up after ourselves. Unregister the character device. */ unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO “Goodbye, World!\n”); } /* Register module functions */ module_init(lkm_example_init); module_exit(lkm_example_exit);

Testiranje poboljšanog primjera

Sada naš primjer čini više od pukog ispisa poruke prilikom utovara i istovara, tako da će biti potreban manje rigorozan postupak testiranja. Promijenimo Makefile tako da učitava samo modul, bez njegovog pražnjenja.

Obj-m += lkm_example.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r )/build M=$(PWD) čisti test: # Stavili smo - ispred naredbe rmmod da kažemo make da zanemari # grešku u slučaju da modul nije učitan. -sudo rmmod lkm_example # Brisanje dnevnika kernela bez odjeka sudo dmesg -C # Umetanje modula sudo insmod lkm_example.ko # Prikaz dnevnika kernela dmesg
Sada nakon pokretanja make testa vidjet ćete izlazni broj glavnog uređaja. U našem primjeru, automatski ga dodjeljuje kernel. Međutim, ovaj je broj potreban za izradu novog uređaja.

Uzmite broj koji je generirao make test i upotrijebite ga za stvaranje datoteke uređaja kako bismo mogli komunicirati s našim kernel modulom iz korisničkog prostora.

Sudo mknod /dev/lkm_example s MAJOR 0
(u ovom primjeru zamijenite MAJOR s vrijednošću dobivenom iz make testa ili dmesg)

Opcija c u naredbi mknod govori mknod-u da moramo stvoriti datoteku znakovnog uređaja.

Sada možemo dobiti sadržaj s uređaja:

Cat /dev/lkm_example
ili čak kroz naredbu dd:

Dd if=/dev/lkm_example of=test bs=14 count=100
Ovoj datoteci također možete pristupiti iz aplikacija. To ne moraju biti kompilirane aplikacije - čak i Python, Ruby i PHP skripte imaju pristup tim podacima.

Kada smo gotovi s uređajem, uklanjamo ga i istovarujemo modul:

Sudo rm /dev/lkm_example sudo rmmod lkm_example

Zaključak

Nadam se da ste uživali u našim temeljnim svemirskim ludorijama. Iako su prikazani primjeri primitivni, ove se strukture mogu koristiti za stvaranje vlastite module obavljanje vrlo složenih zadataka.

Samo zapamtite da je u kernelu sve vaša odgovornost. Ne postoji podrška ili druga prilika za vaš kod. Ako radite projekt za klijenta, planirajte unaprijed dvostruko, ako ne i trostruko vrijeme za otklanjanje pogrešaka. Kernel kod mora biti što savršeniji kako bi se osigurao integritet i pouzdanost sustava na kojima se izvodi.

Neke značajke modularnog programiranja i opće preporuke za konstruiranje potprograma modularne strukture.

Moduli su povezani s glavnim programom redoslijedom kojim su deklarirani USES, a istim redoslijedom su inicijalizacijski blokovi modula povezani s glavnim programom prije nego što program počne izvršavati.

Redoslijed kojim se moduli izvršavaju može utjecati na pristup podacima knjižnice i rutinski pristup.

Na primjer, ako moduli s imenima M1, M2 sadrže isti tip A, varijablu B i potprogram C, tada će nakon povezivanja ovih USES modela, pozivi prema A, B, C u ovom PU-u biti ekvivalentni pozivima prema objektima prema modulu M2 .

No, kako bi se okarakterizirala ispravnost poziva potrebnih objekata istog imena iz različitih povezanih modula, preporučljivo je prilikom pristupanja modulu najprije označiti naziv modula, nakon čega slijedi točka naziv objekta: M1. A M1.B M1.C M2.B.

Očito je vrlo lako podijeliti veliki program na dva dijela (PU), tj. glavni program + moduli.

Postavljanje svakog PU-a u vlastiti memorijski segment i u vlastitu diskovnu datoteku.

Sve deklaracije tipova, kao i one varijable koje bi trebale biti dostupne pojedinim PU (glavni program i budući moduli) treba smjestiti u poseban modul s praznim izvršnim dijelom. Međutim, ne biste trebali obraćati pozornost na činjenicu da neki PE (na primjer, modul) ne koristi sve ove deklaracije. Početni dio takvog modula može uključivati ​​operatore koji povezuju varijable datoteke s nestandardnim tekstualne datoteke(ASSIGN) i pokretanje ovih datoteka, tj. označavajući pozive za prijenos podataka za njih (RESET i REWRITE).

Prvu skupinu drugih potprograma, na primjer, nekoliko kompaktnih funkcija treba smjestiti u modul 3 (zauzvrat), druge, na primjer, procedure opće namjene - u modul 4, itd.

Kod raspodjele potprograma u module u složenom projektu Posebna pažnja treba odrediti redoslijed i mjesto njihova pisanja.

U TR okruženju postoje alati koji kontroliraju različiti putevi kompilacija modula.

Prevedi Alt+F9 RUN Cntr+F9

Memorija odredišta

Ovi se načini razlikuju samo u načinu komunikacije i glavnom programu.

Način kompajliranja

Kompajlira glavni program ili modul koji je trenutno u aktivnom prozoru uređivača. Ako ovaj PU sadrži pristup nestandardnim korisničkim modulima, tada ovaj način rada zahtijeva prisutnost diskovnih datoteka istog imena s ekstenzijom ___.tpu za svaki takav plug-in modul.



Ako je Odredište pohranjeno u memoriji, te datoteke ostaju samo u memoriji, a diskovna datoteka se ne stvara.

Međutim, puno je lakše izraditi tpu datoteke zajedno s kompajlerom cijelog programa koristeći druge načine rada koji ne zahtijevaju postavljanje Diska za odredišnu opciju.

Način rada

Prilikom prevođenja u ovom načinu, prvo se provjerava sljedeće (prije prevođenja glavnog programa) za svaki modul:

1) Postojanje tpu datoteke na disku; ako ne postoji, onda se kreira automatski kompajliranjem izvornog koda modula, tj. svoju pas datoteku

2) Podudarnost pronađene tpu datoteke s izvornim tekstom modula, gdje su izmjene mogle biti napravljene; inače se tpu datoteka ponovno automatski stvara

3) Nepromjenjivost odjeljka sučelja modula: ako se promijenio, tada se svi oni moduli (njihove izvorne pas-datoteke) u kojima je ovaj modul naveden u klauzuli USES također ponovno kompajliraju.

Ako nije bilo promjena u izvornim kodovima modula, tada kompajler stupa u interakciju s tim tpu datotekama i koristi vrijeme kompilacije.

Način izrade

Za razliku od načina Make, on nužno zahtijeva prisutnost izvornih pas datoteka; kompilira (ponovno kompajlira) svaki modul i time osigurava da su sve promjene u tekstovima pas datoteka uzete u obzir. Ovo povećava vrijeme kompilacije programa kao cjeline.

Za razliku od načina prevođenja, načini Make i Build omogućuju vam da počnete kompilirati program s modularnom strukturom iz bilo koje date pas datoteke (naziva se primarna datoteka), bez obzira koja je datoteka (ili dio programa) u aktivnom prozor urednika. Da biste to učinili, u stavci kompajliranja odaberite opciju Primarna datoteka, pritisnite Enter i zapišite naziv primarne pas-datoteke, a zatim će kompilacija započeti iz te datoteke.

Ako primarna datoteka nije navedena na ovaj način, tada je kompilacija u načinima Make, Build i RUN moguća samo ako je glavni program u aktivnom prozoru uređivača.



2024 wisemotors.ru. Kako radi. Željezo. Rudarstvo. Kriptovaluta.