Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00068 007039 13267290 na godz. na dobę w sumie
Jądro Linuksa. Przewodnik programisty - książka
Jądro Linuksa. Przewodnik programisty - książka
Autor: Liczba stron: 504
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-4273-1 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> systemy operacyjne >> linux
Porównaj ceny (książka, ebook, audiobook).

Wnieś swój wkład w rozwój Linuksa!

Jądro systemu Linux to jedno z największych osiągnięć otwartej społeczności programistów. Projekt ten, zainicjowany przez Linusa Torvaldsa, światło dzienne ujrzał w 1991 roku. Od tamtego czasu coraz więcej ochotników wspiera jego doskonalenie. Pozwoliło to na wprowadzenie do jądra wielu nowatorskich funkcji i wyznaczenie trendów w rozwoju współczesnego oprogramowania oraz systemów operacyjnych. Prace nad tym gigantycznym projektem przyczyniły się też do powstania mnóstwa innych produktów - w tym zdobywającego ogromną popularność rozproszonego systemu kontroli wersji Git.

Tak dynamiczny rozwój ma jeden niedobry skutek uboczny. Początkujący programiści mają problem z ogarnięciem ogromu projektu i poznaniem jego architektury. Ten długotrwały proces zdecydowanie skróci przewodnik, który właśnie trzymasz w rękach. Przeprowadzi Cię on przez tajemnice systemu. Dowiesz się, jak pobrać kod źródłowy jądra, jak go skonfigurować oraz skompilować. W kolejnych rozdziałach poznasz kluczowe mechanizmy: zarządzania procesami, szeregowania zadań, wywołań systemowych oraz przerwań. Ponadto nauczysz się korzystać z urządzeń blokowych, pamięci podręcznej, sterowników i modułów. Ta książka jest obowiązkową lekturą dla wszystkich programistów, którzy chcą mieć swój wkład w rozwój projektu Torvaldsa. Sprawdzi się ona również w rękach osób, które po prostu chcą zrozumieć, jak działa ten niezwykły system.

Dzięki tej książce:

Przekonaj się, jak działa jądro Linuksa!

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Tytuł oryginału: Linux Kernel Development (3rd Edition) Tłumaczenie: Przemysław Szeremiota ISBN: 978-83-246-4273-1 Authorized translation from the English edition, entitled: LINUX KERNEL DEVELOPMENT, Third Edition; ISBN 0672329468; by Robert Love; published by Pearson Education, Inc, publishing as Addison Wesley. Copyright © 2010 by Pearson Education, Inc. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. Polish language edition published by HELION S.A., Copyright © 2014. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie bierze jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Wydawnictwo HELION nie ponosi również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/jadlin Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treści Przedmowa ........................................................................17 Wst(cid:246)p ...............................................................................19 Rozdzia(cid:228) 1. J(cid:241)dro systemu Linux — wprowadzenie ................................25 Historia Uniksa .............................................................................25 Wprowadzenie do systemu Linux ....................................................27 Przegl(cid:241)d systemów operacyjnych ....................................................29 J(cid:241)dro Linuksa a j(cid:241)dro klasycznego systemu uniksowego ..................31 Oznaczenia wersji j(cid:241)dra Linuksa .....................................................34 Spo(cid:228)eczno(cid:264)(cid:232) programistów j(cid:241)dra Linuksa ........................................35 Zanim zaczniemy ...........................................................................36 Rozdzia(cid:228) 2. Linux — zaczynamy ............................................................37 Kod (cid:274)ród(cid:228)owy j(cid:241)dra ........................................................................37 Git ..........................................................................................37 Instalowanie (cid:274)róde(cid:228) j(cid:241)dra z archiwum .........................................38 Aplikowanie (cid:228)at ........................................................................39 Struktura katalogów kodu (cid:274)ród(cid:228)owego j(cid:241)dra .....................................39 Kompilowanie j(cid:241)dra .......................................................................40 Konfigurowanie j(cid:241)dra ................................................................41 Minimalizacja szumu podczas kompilacji ...................................43 Kompilacja na wielu frontach ....................................................43 Instalowanie nowego j(cid:241)dra .......................................................44 Odmienno(cid:264)(cid:232) j(cid:241)dra .........................................................................45 Brak implementacji i nag(cid:228)ówków biblioteki standardowej C ..........45 GNU C ....................................................................................47 Brak mechanizmu ochrony pami(cid:246)ci ............................................49 Niemo(cid:276)no(cid:264)(cid:232) ((cid:228)atwego) korzystania z operacji zmiennoprzecinkowych ............................................50 Ograniczony co do rozmiaru (i sta(cid:228)y) stos ...................................50 Synchronizacja i wspó(cid:228)bie(cid:276)no(cid:264)(cid:232) .................................................50 Znaczenie przeno(cid:264)no(cid:264)ci ...........................................................51 Podsumowanie .............................................................................51 Kup książkęPoleć książkę 6 J(cid:241)dro Linuksa. Przewodnik programisty Rozdzia(cid:228) 3. Zarz(cid:241)dzanie procesami .......................................................53 Proces .........................................................................................53 Deskryptor procesu i struktura zadania ...........................................55 Przydzia(cid:228) deskryptora procesu ...................................................55 Przechowywanie deskryptora procesu ........................................57 Stan procesu ...........................................................................58 Manipulowanie bie(cid:276)(cid:241)cym stanem procesu .................................59 Kontekst procesu ....................................................................60 Drzewo procesów .....................................................................60 Tworzenie procesu ........................................................................62 Kopiowanie przy zapisie ............................................................62 Rozwidlanie procesu ................................................................63 Wywo(cid:228)anie vfork() .....................................................................64 W(cid:241)tki w systemie Linux .................................................................65 Tworzenie w(cid:241)tków ....................................................................66 W(cid:241)tki j(cid:241)dra ..............................................................................67 Zako(cid:254)czenie procesu .....................................................................68 Usuwanie deskryptora procesu .................................................70 Problem zada(cid:254) osieroconych .....................................................71 Podsumowanie .............................................................................73 Rozdzia(cid:228) 4. Szeregowanie zada(cid:254) ...........................................................75 Wielozadaniowo(cid:264)(cid:232) .........................................................................75 Planista zada(cid:254) w Linuksie ..............................................................77 Strategia post(cid:246)powania .................................................................77 Procesy ograniczone wej(cid:264)ciem-wyj(cid:264)ciem a procesy ograniczone procesorem .........................................78 Priorytet procesu .....................................................................79 Kwant czasu procesora ............................................................80 Strategia szeregowania w dzia(cid:228)aniu ...........................................81 Algorytm szeregowania zada(cid:254) w Linuksie ........................................82 Klasy szeregowania ..................................................................82 Szeregowanie procesów w systemach klasy Unix ........................82 Sprawiedliwe szeregowanie zada(cid:254) .............................................85 Implementacja szeregowania zada(cid:254) w Linuksie ...............................87 Zliczanie czasu wykonania ........................................................87 Wybór procesu .........................................................................89 Punkt wej(cid:264)cia do planisty CFS ...................................................94 Zawieszanie i wybudzanie procesów ..........................................95 Wyw(cid:228)aszczanie i prze(cid:228)(cid:241)czanie kontekstu ..........................................99 Wyw(cid:228)aszczanie procesu u(cid:276)ytkownika ........................................100 Wyw(cid:228)aszczenie j(cid:241)dra ..............................................................101 Szeregowanie czasu rzeczywistego ...............................................102 Kup książkęPoleć książkę Spis tre(cid:264)ci 7 Wywo(cid:228)ania systemowe zwi(cid:241)zane z szeregowaniem .........................103 Wywo(cid:228)ania wp(cid:228)ywaj(cid:241)ce na strategi(cid:246) szeregowania i warto(cid:264)ci priorytetów ...........................................................104 Wywo(cid:228)ania systemowe steruj(cid:241)ce kojarzeniem procesów z procesorami .....................................................................105 Odst(cid:241)pienie procesora ...........................................................105 Podsumowanie ...........................................................................106 Rozdzia(cid:228) 5. Wywo(cid:228)ania systemowe .....................................................107 Komunikacja z j(cid:241)drem systemu ....................................................107 API, POSIX i biblioteka C ..............................................................108 Wywo(cid:228)ania systemowe .................................................................109 Numery wywo(cid:228)a(cid:254) systemowych ................................................111 Wydajno(cid:264)(cid:232) wywo(cid:228)ania systemowego ........................................111 Procedura obs(cid:228)ugi wywo(cid:228)a(cid:254) systemowych .....................................111 Oznaczanie w(cid:228)a(cid:264)ciwego wywo(cid:228)ania systemowego ......................112 Przekazywanie argumentów ....................................................113 Implementacja wywo(cid:228)ania systemowego ........................................113 Implementowanie wywo(cid:228)a(cid:254) systemowych .................................114 Weryfikacja argumentów .........................................................114 Kontekst wywo(cid:228)ania systemowego ................................................118 Wi(cid:241)zanie wywo(cid:228)ania systemowego ...........................................119 Inicjowanie wywo(cid:228)ania systemowego z przestrzeni u(cid:276)ytkownika .....................................................120 Sze(cid:264)(cid:232) powodów, aby nie implementowa(cid:232) wywo(cid:228)a(cid:254) systemowych ......................121 Podsumowanie ...........................................................................122 Rozdzia(cid:228) 6. Struktury danych j(cid:241)dra .....................................................123 Listy ...........................................................................................123 Listy jedno- i dwukierunkowe ...................................................124 Listy cykliczne .......................................................................124 Implementacja list w j(cid:241)drze Linuksa ........................................126 Operacje na listach ................................................................128 Przegl(cid:241)danie list ....................................................................131 Inne operacje na listach .........................................................134 Kolejki ........................................................................................135 kfifo ......................................................................................135 Tworzenie kolejki ...................................................................136 Zakolejkowanie ......................................................................137 Wyci(cid:241)ganie danych .................................................................137 Okre(cid:264)lanie rozmiaru kolejki .....................................................137 Zerowanie i usuwanie kolejki ..................................................138 Przyk(cid:228)ad u(cid:276)ycia kolejki kfifo .....................................................138 Kup książkęPoleć książkę 8 J(cid:241)dro Linuksa. Przewodnik programisty Mapy ..........................................................................................139 Inicjalizowanie mapy idr ..........................................................140 Przydzia(cid:228) nowego identyfikatora UID .........................................140 Odwzorowanie UID na wska(cid:274)nik ..............................................141 Usuwanie UID ........................................................................142 Usuwanie idr .........................................................................142 Drzewa binarne ...........................................................................143 Drzewa BST ...........................................................................143 Zrównowa(cid:276)one drzewa BST .....................................................144 Drzewa czerwono-czarne .........................................................145 rbtree ...................................................................................146 Kiedy i jakiej struktury u(cid:276)y(cid:232)? ........................................................148 Z(cid:228)o(cid:276)ono(cid:264)(cid:232) obliczeniowa ...............................................................149 Algorytmy ..............................................................................149 Notacja O ..............................................................................149 Notacja theta ........................................................................150 Z(cid:228)o(cid:276)ono(cid:264)(cid:232) czasowa ................................................................150 Podsumowanie ...........................................................................151 Rozdzia(cid:228) 7. Przerwania i procedury obs(cid:228)ugi przerwa(cid:254) ...........................153 Przerwania ..................................................................................154 Procedury obs(cid:228)ugi przerwa(cid:254) ..........................................................155 Po(cid:228)ówki górne i dolne ..................................................................156 Rejestrowanie procedury obs(cid:228)ugi przerwania ..................................157 Znaczniki procedury obs(cid:228)ugi przerwa(cid:254) ......................................158 Przyk(cid:228)adowe przerwanie ..........................................................159 Zwalnianie procedury obs(cid:228)ugi przerwania ..................................160 Tworzenie procedury obs(cid:228)ugi przerwa(cid:254) ..........................................160 Procedury obs(cid:228)ugi przerwa(cid:254) wspó(cid:228)u(cid:276)ytkowanych .......................162 Prawdziwa procedura obs(cid:228)ugi przerwania ..................................163 Kontekst przerwania ....................................................................165 Implementacja obs(cid:228)ugi przerwa(cid:254) ...................................................166 /proc/interrupts ..........................................................................168 Kontrola przerwa(cid:254) .......................................................................169 Wy(cid:228)(cid:241)czanie i w(cid:228)(cid:241)czanie przerwa(cid:254) .............................................170 Blokowanie konkretnej linii przerwania .....................................172 Stan systemu przerwa(cid:254) ..........................................................173 Podsumowanie ...........................................................................174 Rozdzia(cid:228) 8. Dolne po(cid:228)ówki i czynno(cid:264)ci odroczone ................................175 Po(cid:228)ówki dolne .............................................................................176 Po co dolne po(cid:228)ówki? .............................................................177 (cid:263)wiat dolnych po(cid:228)ówek ...........................................................178 Kup książkęPoleć książkę Spis tre(cid:264)ci 9 Przerwania programowe ...............................................................181 Implementacja przerwa(cid:254) programowych ...................................181 Korzystanie z przerwa(cid:254) programowych .....................................183 Tasklety .....................................................................................186 Implementacja taskletów ........................................................186 Korzystanie z taskletów ..........................................................189 W(cid:241)tek j(cid:241)dra ksoftirqd .............................................................191 Dawny mechanizm BH ............................................................193 Kolejki prac ................................................................................194 Implementacja kolejek prac ....................................................195 Korzystanie z kolejek prac ......................................................199 Dawny mechanizm kolejkowania zada(cid:254) ....................................201 Jak wybra(cid:232) implementacj(cid:246) dolnej po(cid:228)ówki? ....................................202 Blokowanie pomi(cid:246)dzy dolnymi po(cid:228)ówkami ......................................204 Wy(cid:228)(cid:241)czanie dolnych po(cid:228)ówek ........................................................204 Podsumowanie ...........................................................................206 Rozdzia(cid:228) 9. Wprowadzenie do synchronizacji j(cid:241)dra ..............................207 Sekcje krytyczne i przeplot operacji ...............................................208 Po co ta ochrona? ..................................................................208 Zmienna globalna ..................................................................210 Blokowanie .................................................................................211 (cid:273)ród(cid:228)a wspó(cid:228)bie(cid:276)no(cid:264)ci ............................................................213 Co wymaga zabezpieczania? ...................................................215 Zakleszczenia .............................................................................216 Rywalizacja a skalowalno(cid:264)(cid:232) ..........................................................218 Podsumowanie ...........................................................................220 Rozdzia(cid:228) 10. Metody synchronizacji j(cid:241)dra .............................................221 Operacje niepodzielne .................................................................221 Niepodzielne operacje na liczbach ca(cid:228)kowitych .........................222 64-bitowe operacje niepodzielne .............................................226 Niepodzielne operacje bitowe ..................................................228 Rygle p(cid:246)tlowe .............................................................................230 Interfejs rygli p(cid:246)tlowych ..........................................................231 Inne metody blokowania ryglami p(cid:246)tlowymi ..............................234 Rygle p(cid:246)tlowe a dolne po(cid:228)ówki ................................................234 Rygle p(cid:246)tlowe R-W .......................................................................235 Semafory ....................................................................................238 Semafory binarne i zliczaj(cid:241)ce ..................................................239 Tworzenie i inicjalizowanie semaforów .....................................240 Korzystanie z semaforów ........................................................240 Semafory R-W .............................................................................241 Kup książkęPoleć książkę 10 J(cid:241)dro Linuksa. Przewodnik programisty Muteksy .....................................................................................243 Muteksy czy semafory? ..........................................................245 Muteksy czy rygle p(cid:246)tlowe? .....................................................245 Zmienne sygna(cid:228)owe .....................................................................245 Blokada BKL (Big Kernel Lock) .....................................................246 Blokady sekwencyjne ...................................................................247 Blokowanie wyw(cid:228)aszczania ...........................................................249 Bariery pami(cid:246)ciowe .....................................................................251 Podsumowanie ...........................................................................255 Rozdzia(cid:228) 11. Liczniki i zarz(cid:241)dzanie czasem ............................................257 Czas z punktu widzenia j(cid:241)dra .......................................................258 Cz(cid:246)stotliwo(cid:264)(cid:232) taktowania — HZ ...................................................259 Optymalna warto(cid:264)(cid:232) HZ ...........................................................260 Zalety wysokich warto(cid:264)ci HZ ...................................................261 Wady wysokich warto(cid:264)ci HZ ....................................................262 Chwilki .......................................................................................263 Wewn(cid:246)trzna reprezentacja zmiennej jiffies ...............................264 Zawijanie zmiennej jiffies ........................................................266 HZ a przestrze(cid:254) u(cid:276)ytkownika ...................................................267 Zegary i liczniki sprz(cid:246)towe ............................................................268 Zegar czasu rzeczywistego ......................................................268 Zegar systemowy ...................................................................269 Procedura obs(cid:228)ugi przerwania zegarowego .....................................269 Data i godzina .............................................................................272 Liczniki .......................................................................................274 Korzystanie z liczników ...........................................................275 Liczniki i sytuacje hazardowe ..................................................277 Implementacja licznika ...........................................................277 Opó(cid:274)nianie wykonania .................................................................278 Oczekiwanie w p(cid:246)tli aktywnej ..................................................278 Krótkie opó(cid:274)nienia .................................................................280 Funkcja schedule_timeout() ....................................................281 Implementacja funkcji schedule_timeout() ...............................282 Podsumowanie ...........................................................................284 Rozdzia(cid:228) 12. Zarz(cid:241)dzanie pami(cid:246)ci(cid:241) .......................................................285 Strony ........................................................................................285 Strefy .........................................................................................287 Pozyskiwanie stron pami(cid:246)ci .........................................................290 Pozyskiwanie czystych stron pami(cid:246)ci .......................................291 Zwalnianie stron ....................................................................291 Funkcja kmalloc() ........................................................................292 Znaczniki gfp_mask ...............................................................293 Funkcja kfree() .......................................................................298 Kup książkęPoleć książkę Spis tre(cid:264)ci 11 Funkcja vmalloc() ........................................................................299 Alokator plastrowy .......................................................................301 Zadania alokatora plastrowego ...............................................302 Interfejs alokatora plastrowego ...............................................305 Przydzia(cid:228) z pami(cid:246)ci podr(cid:246)cznej ................................................307 Statyczne przydzia(cid:228)y na stosie ......................................................309 Jednostronicowy stos procesów j(cid:241)dra ......................................309 Ostro(cid:276)nie ze stosem ..............................................................310 Odwzorowanie pami(cid:246)ci wysokiej ...................................................310 Odwzorowanie trwa(cid:228)e ..............................................................311 Odwzorowania czasowe ..........................................................311 Przydzia(cid:228)y lokalne wzgl(cid:246)dem procesora .........................................312 Interfejs percpu ...........................................................................313 Statyczne dane lokalne wzgl(cid:246)dem procesora ............................313 Dynamiczne dane lokalne wzgl(cid:246)dem procesora ........................314 Przydatno(cid:264)(cid:232) danych lokalnych wzgl(cid:246)dem procesora ........................315 Wybór metody przydzia(cid:228)u pami(cid:246)ci w kodzie j(cid:241)dra ............................316 Podsumowanie ...........................................................................317 Rozdzia(cid:228) 13. Wirtualny system plików ..................................................319 Wspólny interfejs systemu plików .................................................320 Warstwa abstrakcji systemu plików ..............................................320 Uniksowy system plików ..............................................................322 Obiekty VFS i ich struktury danych ................................................323 Obiekt bloku g(cid:228)ównego ................................................................325 Operacje bloku g(cid:228)ównego .............................................................326 Obiekt i-w(cid:246)z(cid:228)a .............................................................................329 Operacje i-w(cid:246)z(cid:228)a ..........................................................................331 Obiekt wpisu katalogowego ..........................................................334 Stan wpisu katalogowego .......................................................335 Bufor wpisów katalogowych ....................................................336 Operacje na wpisach katalogowych ...............................................337 Obiekt pliku ................................................................................339 Operacje na plikach .....................................................................340 Struktury danych systemu plików ..................................................343 Struktury danych procesu ............................................................345 Podsumowanie ...........................................................................347 Rozdzia(cid:228) 14. Blokowe urz(cid:241)dzenia wej(cid:264)cia-wyj(cid:264)cia .................................349 Anatomia urz(cid:241)dzenia blokowego ...................................................350 Bufory i nag(cid:228)ówki buforów ............................................................351 Struktura bio ..............................................................................354 Wektory wej(cid:264)cia-wyj(cid:264)cia ..........................................................355 Stare a nowe .........................................................................357 Kup książkęPoleć książkę 12 J(cid:241)dro Linuksa. Przewodnik programisty Kolejki zlece(cid:254) .............................................................................357 Zawiadywanie operacjami wej(cid:264)cia-wyj(cid:264)cia ......................................358 Zadania planisty operacji wej(cid:264)cia-wyj(cid:264)cia .................................359 Winda Linusa ........................................................................360 Terminowy planista operacji wej(cid:264)cia-wyj(cid:264)cia .............................361 Przewiduj(cid:241)cy planista operacji wej(cid:264)cia-wyj(cid:264)cia ..........................363 Sprawiedliwy planista kolejkowania operacji wej(cid:264)cia-wyj(cid:264)cia ....364 Nieingeruj(cid:241)cy planista operacji wej(cid:264)cia-wyj(cid:264)cia .........................365 Wybór planisty operacji wej(cid:264)cia-wyj(cid:264)cia ....................................366 Podsumowanie ...........................................................................366 Rozdzia(cid:228) 15. Przestrze(cid:254) adresowa procesu ...........................................367 Przestrzenie adresowe .................................................................367 Deskryptor pami(cid:246)ci .....................................................................369 Przydzia(cid:228) deskryptora pami(cid:246)ci .................................................371 Zwalnianie deskryptora pami(cid:246)ci ..............................................371 Struktura mm_struct i w(cid:241)tki j(cid:241)dra ............................................372 Obszary pami(cid:246)ci wirtualnej ...........................................................372 Znaczniki VMA .......................................................................374 Operacje VMA ........................................................................375 Obszary pami(cid:246)ci na listach i w drzewach ..................................376 Obszary pami(cid:246)ci w praktyce ....................................................377 Manipulowanie obszarami pami(cid:246)ci ...............................................379 Funkcja find_vma() .................................................................379 Funkcja find_vma_prev() .........................................................381 Funkcja find_vma_intersection() ..............................................381 Tworzenie interwa(cid:228)u adresów — wywo(cid:228)ania mmap() i do_mmap() .............................................381 Usuwanie interwa(cid:228)u adresów — wywo(cid:228)ania munmap() i do_munmap() ......................................383 Tablice stron ...............................................................................384 Podsumowanie ...........................................................................386 Rozdzia(cid:228) 16. Pami(cid:246)(cid:232) podr(cid:246)czna stron i opó(cid:274)niony zapis stron w tle .......387 Modele pami(cid:246)ci podr(cid:246)cznych .......................................................387 Buforowanie zapisów ..............................................................388 Eksmisja z pami(cid:246)ci podr(cid:246)cznej ................................................389 Pami(cid:246)(cid:232) podr(cid:246)czna stron w Linuksie ..............................................391 Obiekt address_space ............................................................391 Operacje na obiektach address_space ....................................392 Drzewo pozycyjne ...................................................................395 Tablica skrótów stron .............................................................395 Pami(cid:246)(cid:232) podr(cid:246)czna buforów ..........................................................396 Kup książkęPoleć książkę Spis tre(cid:264)ci 13 W(cid:241)tki zapisu w tle .......................................................................396 Tryb laptopowy .......................................................................398 Rys historyczny — bdflush, kupdated i pdflush .........................399 Eliminowanie obci(cid:241)(cid:276)enia operacjami wej(cid:264)cia-wyj(cid:264)cia .................400 Podsumowanie ...........................................................................401 Rozdzia(cid:228) 17. Sterowniki i modu(cid:228)y .........................................................403 Typy urz(cid:241)dze(cid:254) .............................................................................403 Modu(cid:228)y .......................................................................................404 Hello, world! ..........................................................................405 Kompilowanie modu(cid:228)ów ..........................................................406 Instalowanie modu(cid:228)ów ............................................................409 Generowanie zale(cid:276)no(cid:264)ci mi(cid:246)dzymodu(cid:228)owych .............................409 (cid:227)adowanie modu(cid:228)ów ...............................................................410 Zarz(cid:241)dzanie opcjami konfiguracji j(cid:241)dra .....................................411 Parametry modu(cid:228)ów ...............................................................413 Symbole eksportowane ..........................................................415 Model sterowników .....................................................................416 Obiekty j(cid:241)dra .........................................................................417 Typy obiektów j(cid:241)dra ................................................................418 Grupy obiektów j(cid:241)dra ..............................................................419 Powi(cid:241)zania pomi(cid:246)dzy obiektami, typami i grupami obiektów j(cid:241)dra ......................................................419 Zarz(cid:241)dzanie i operowanie obiektami j(cid:241)dra ................................420 Zliczanie odwo(cid:228)a(cid:254) ..................................................................421 System plików sysfs ....................................................................423 Dodawanie i usuwanie obiektów j(cid:241)dra w sysfs ..........................426 Dodawanie plików do sysfs .....................................................427 Kernel Event Layer .................................................................430 Podsumowanie ...........................................................................431 Rozdzia(cid:228) 18. Diagnostyka b(cid:228)(cid:246)dów j(cid:241)dra ................................................433 Od czego zacz(cid:241)(cid:232)? ........................................................................433 B(cid:228)(cid:246)dy w j(cid:241)drze .............................................................................434 Diagnostyka komunikatami ..........................................................435 Niezawodno(cid:264)(cid:232) printk() ............................................................435 Poziomy diagnostyczne ...........................................................436 Bufor komunikatów ................................................................437 Demony syslogd i klogd ..........................................................438 printf(), printk() — (cid:228)atwo o pomy(cid:228)k(cid:246) .........................................438 B(cid:228)(cid:241)d oops ...................................................................................438 Polecenie ksymoops ..............................................................440 kallsyms ...............................................................................441 Opcje diagnostyczne j(cid:241)dra ...........................................................441 Kup książkęPoleć książkę 14 J(cid:241)dro Linuksa. Przewodnik programisty Asercje i wypisywanie informacji o b(cid:228)(cid:246)dach ....................................442 Funkcja Magic SysRq Key ............................................................443 Saga debugera j(cid:241)dra ...................................................................444 gdb .......................................................................................445 kgdb .....................................................................................446 Stymulowanie i sondowanie systemu ............................................446 Uzale(cid:276)nianie wykonania kodu od identyfikatora UID ..................446 Korzystanie ze zmiennych warunkowych ...................................447 Korzystanie ze statystyk .........................................................447 Ograniczanie cz(cid:246)stotliwo(cid:264)ci i liczby komunikatów diagnostycznych ....................................448 Szukanie winowajcy — wyszukiwanie binarne ................................449 Binarne wyszukiwanie wersji za pomoc(cid:241) Gita .................................450 Koledzy — kiedy wszystko inne zawiedzie .....................................451 Podsumowanie ...........................................................................451 Rozdzia(cid:228) 19. Przeno(cid:264)no(cid:264)(cid:232) ....................................................................453 Przeno(cid:264)ne systemy operacyjne .....................................................453 Historia przeno(cid:264)no(cid:264)ci systemu Linux ............................................455 Rozmiar s(cid:228)owa i typy danych .........................................................456 Typy nieprzejrzyste .................................................................459 Typy specjalne .......................................................................459 Typy o zadanych rozmiarach ....................................................460 Znak typu char .......................................................................461 Wyrównanie danych .....................................................................462 Unikanie problemów wyrównywania .........................................462 Wyrównanie typów niestandardowych ......................................463 Dope(cid:228)nienie struktury .............................................................463 Wzajemny porz(cid:241)dek bajtów ..........................................................465 Pomiar up(cid:228)ywu czasu ...................................................................467 Rozmiar strony ............................................................................468 Kolejno(cid:264)(cid:232) wykonywania instrukcji .................................................469 Tryb SMP, wyw(cid:228)aszczanie j(cid:241)dra i pami(cid:246)(cid:232) wysoka ............................469 Podsumowanie ...........................................................................470 Rozdzia(cid:228) 20. Kodowanie, (cid:228)aty i spo(cid:228)eczno(cid:264)(cid:232) ..........................................471 Spo(cid:228)eczno(cid:264)(cid:232) ...............................................................................471 Obowi(cid:241)zuj(cid:241)cy styl kodowania .......................................................472 Wci(cid:246)cia .................................................................................472 Instrukcje switch ....................................................................473 Odst(cid:246)py ................................................................................473 Nawiasy klamrowe .................................................................475 D(cid:228)ugo(cid:264)(cid:232) wiersza kodu ............................................................476 Nazewnictwo .........................................................................476 Kup książkęPoleć książkę Spis tre(cid:264)ci 15 Funkcje .................................................................................477 Komentarze ...........................................................................477 Definicje typów ......................................................................478 Korzystanie z gotowców ..........................................................478 Unikanie definicji ifdef w ciele funkcji ......................................478 Inicjalizacja struktur ...............................................................479 Poprawianie z(cid:228)ego stylu ..........................................................479 (cid:227)a(cid:254)cuch polece(cid:254) .........................................................................480 Przesy(cid:228)anie raportów o b(cid:228)(cid:246)dach ....................................................480 (cid:227)aty ...........................................................................................481 Generowanie (cid:228)at ....................................................................481 Generowanie (cid:228)at za pomoc(cid:241) Gita .............................................482 Rozsy(cid:228)anie (cid:228)at ........................................................................483 Podsumowanie ...........................................................................484 Dodatek A Bibliografia ......................................................................485 Ksi(cid:241)(cid:276)ki o projektowaniu systemów operacyjnych ............................485 Ksi(cid:241)(cid:276)ki o j(cid:241)drze systemu Unix ......................................................486 Ksi(cid:241)(cid:276)ki o j(cid:241)drze systemu Linux .....................................................486 Ksi(cid:241)(cid:276)ki o j(cid:241)drach innych systemów operacyjnych ...........................487 Ksi(cid:241)(cid:276)ki o interfejsie programowym Uniksa .....................................487 Ksi(cid:241)(cid:276)ki o programowaniu w j(cid:246)zyku C .............................................487 Inne ksi(cid:241)(cid:276)ki ................................................................................488 Witryny WWW ..............................................................................488 Skorowidz.........................................................................489 Kup książkęPoleć książkę 16 J(cid:241)dro Linuksa. Przewodnik programisty Kup książkęPoleć książkę 18 Diagnostyka błędów jądra J edną z podstawowych miar odróżniających programowanie jądra od programowania przestrzeni użytkownika jest stopień trudności diagnostyki błędów. Diagnostyka jądra nie jest łatwa, zwłaszcza w porównaniu z przestrzenią użytkownika. Problem komplikuje jeszcze wysokość stawki — błąd w jądrze może załamać cały system komputerowy. Rosnąca umiejętność diagnozowania błędów w jądrze — a co za tym idzie, coraz większa swoboda programowania jądra — jest w dużej mierze funkcją doświadczenia i stopnia zrozumienia systemu operacyjnego. Podziałać mogą zapewne również zaklęcia i czary, ale do udanej diagnostyki jądra konieczna jest jego pełna znajomość. Niniejszy rozdział poświęcony będzie właśnie zagadnieniom związanym z diagnostyką błędów jądra. Od czego zacz(cid:241)(cid:232)? Diagnostyka błędów w jądrze bywa uciążliwym i żmudnym procesem. Niektóre z błędów całymi miesiącami myliły tropy, choć śledzone były przez wielu programistów. Na szczęście na dosłownie każdy tak pracochłonny błąd przypada wiele błędów bardziej oczywistych, z równie oczywistymi poprawkami. Przy odrobinie szczęścia wszystkie błędy, jakie popełnimy, będą błędami prostymi. Tego jednak przed rozpoczęciem poszukiwań nie będzie wiadomo na pewno. Dlatego warto zaopatrzyć się w: (cid:132) Błąd. To może brzmi śmiesznie, ale potrzebny będzie dobrze zdefiniowany i bardzo konkretny błąd. Dobrze, jeżeli jest to błąd powtarzalny, który można sprowokować w określonych warunkach. Niestety, błędy rzadko bywają stabilne i powtarzalne. (cid:132) Wersję jądra, w której występuje rzeczony błąd (na przykład najnowszą wersję, bo inaczej nikt nie zawracałby sobie głowy błędem). Najlepiej, jeżeli uda się wytypować najwcześniejszą wersję jądra, w której pojawił się błąd. W rozdziale będzie omawiana technika polowania na popsutą wersję jądra. (cid:132) Znajomość odpowiedniej części jądra albo szczęście. Diagnozowanie błędów jądra jest śledztwem, które daje tym lepsze wyniki, im lepsza jest znajomość otoczenia. Kup książkęPoleć książkę 434 Rozdzia(cid:228) 18. Diagnostyka b(cid:228)(cid:246)dów j(cid:241)dra Większość bieżącego rozdziału będzie poświęcona technikom reprodukcji błędów. Skuteczność w ich poprawianiu jest bowiem wypadkową umiejętności prowokowania wystąpienia błędu. Niemożność sprowokowania błędu ogranicza możliwości jego usunięcia, zmuszając do jedynie koncepcyjnego określenia problemu i odnalezienia odpowiadającej mu luki w kodzie źródłowym. Często zdarza się zresztą i tak, ale szansa powodzenia jest znacznie większa przy możliwości obserwacji błędu. Istnienie błędu, którego wpływu na system nie da się ujawnić, może być nieco wątpliwe. W programach przestrzeni użytkownika błędy są najczęściej bardziej dokuczliwe — na przykład „wywołanie funkcji bla() w takim a takim kroku pętli powoduje awaryjne zamknięcie programu”. W kodzie jądra sprawy są zazwyczaj znacznie bardziej zagmatwane. Interakcje pomiędzy jądrem, przestrzenią użytkownika i sprzętem potrafią być bardzo delikatne. Niekiedy będące przyczyną błędu sytuacje hazardowe pojawiają się raz na milion iteracji jakiegoś algorytmu. Słabo zaprojektowany albo nawet źle skompilowany kod może dawać w niektórych systemach oczekiwane rezultaty, pogarszając wydajność systemów o innych konfiguracjach. Niejednokrotnie zdarza się wywołać błąd jedynie w określonej konfiguracji jądra, na pewnej przypadkowej maszynie, przy obciążeniu systemu nietypowymi operacjami itd. Dlatego kluczowe znaczenie ma ilość informacji o środowisku, w jakim wystąpił błąd. Zazwyczaj jednak możliwość powtórnego sprowokowania błędu to więcej niż połowa sukcesu. B(cid:228)(cid:246)dy w j(cid:241)drze Błędy w jądrze bywają bardzo różnorodne. Zdarzają się one z niezliczonych powodów i objawiają się w równie niezliczonych formach. Błędy od jawnie błędnego kodu (na przykład niezachowania poprawnej wartości w odpowiednim miejscu), przez błędy synchronizacji (wynikające z braku właściwego blokowania dostępu do współdzielonej zmiennej), po nieprawidłowe zarządzanie sprzętem (wysyłanie nieprawidłowej wartości do nieodpowiedniego rejestru sterującego) objawiają się pod wszelkimi postaciami, od niezadowalającej wydajności systemu po jego niewłaściwe działanie w skrajnych przypadkach powodujące utratę danych albo zawieszanie systemu. Błąd w postaci objawiającej się użytkownikowi nieraz może dzielić od jego przyczyny tkwiącej w kodzie jądra długi łańcuch zdarzeń. Na przykład współużytkowana struktura pozbawiona licznika odwołań może prowokować sytuacje hazardowe. Wobec braku poprawnego zliczania odwołań może dojść do zwolnienia przez jeden proces struktury używanej jeszcze przez inny proces. Ów inny proces może próbować odwołać się do zwolnionej już struktury za pośrednictwem przetrzymywanego lokalnie, nieprawidłowego już wskaźnika. Może to zaowocować wyłuskaniem wskaźnika pustego, odczytem „śmieci” czy też czymś zupełnie niewinnym (kiedy obszar zwolnionej struktury nie został jeszcze niczym nadpisany). Wyłuskanie wskaźnika pustego daje w efekcie błąd „oops”, podczas gdy odwołanie do przypadkowych danych („śmieci”) w pamięci może prowadzić do naruszenia spójności danych (a w jej wyniku do niewłaściwego zachowania Kup książkęPoleć książkę Diagnostyka komunikatami 435 programu, a w dalekiej konsekwencji do błędu „oops”). Użytkownik zgłasza więc albo błąd „oops”, albo wyłącznie niepoprawne działanie systemu. Programista jądra musi wyśledzić przyczynę błędu, wykryć, że nastąpił dostęp do zwolnionych wcześniej danych, że wcześniej niewłaściwie współużytkowana była zawierająca te dane struktura i wreszcie zaaplikować łatę w postaci poprawnego zliczania odwołań do współużytkowanej struktury (i być może jakiegoś rygla chroniącego ją przed współbieżnym dostępem). Diagnostyka błędów jądra może sprawiać wrażenie zadania dla magików, ale w rzeczywistości jądro systemu nie różni się niczym od innych dużych projektów programowych. Co prawda w jądrze należy brać pod uwagę elementy specyficzne, takie jak ograniczenia czasowe wykonania kodu czy sytuacje hazardowe będące konsekwencją działania wielu wątków w ramach jądra. Diagnostyka komunikatami Funkcja jądra printk() działa niemal identycznie jak podobnie nazwana funkcja biblioteczna języka C, printf(). Podobieństwo działania jest tak duże, że jak na razie w książce nie wystąpiło zastosowanie funkcji printk() znacząco odbiegające od zastosowań printf(). Tak więc printk() to nazwa funkcji jądra generującej sformatowany wydruk znakowy. Nie jest to jednak tak do końca zwykła funkcja formatująca. Niezawodno(cid:264)(cid:232) printk() Jedną z tych właściwości wywołania printk(), które szybko przyjmuje się za oczywistość, jest jej niezawodność i wszechstronność. Funkcja printk() daje się wywołać z dowolnego miejsca jądra w dowolnym momencie jego wykonania. Można ją wywołać z kontekstu procesu i kontekstu przerwania. Można ją wywoływać, przetrzymując równocześnie blokadę dowolnego rodzaju. Można też wywoływać ją współbieżnie na wielu procesorach, przy czym wywołujący nie musi pozyskiwać żadnej blokady. To funkcja naprawdę nie do zdarcia. To bardzo ważne, ponieważ przydatność funkcji printk() wynika w dużej mierze właśnie z możliwości jej wywołania dosłownie zewsząd i z gwarancji jej działania w każdych warunkach. Istnieje jednak luka we wszechstronności wywołania printk(). Nie da się jej bowiem zastosować przed określonym momentem rozruchu jądra, a ściśle mówiąc, przed momentem zainicjowania konsoli. To oczywiste, bo gdzie niby miałyby być wcześniej kierowane komunikaty? Zwykle nie jest to problemem, chyba że chodzi o diagnozowanie bardzo wczesnej fazy rozruchu (na przykład diagnostykę błędów działania funkcji setup_arch() odpowiedzialnej za operacje inicjalizacji zależne od architektury systemu). Taka diagnostyka to prawdziwe wyzwanie — a brak jakichkolwiek narzędzi wyprowadzania komunikatów dodatkowo je komplikuje. Nawet diagnostyka wczesnych faz rozruchu daje jednak pewne możliwości. Niektórzy programiści wykorzystują do wyprowadzania komunikatów sprzęt, który działa zawsze, Kup książkęPoleć książkę 436 Rozdzia(cid:228) 18. Diagnostyka b(cid:228)(cid:246)dów j(cid:241)dra na przykład port szeregowy. Nie jest to jednak przyjemna zabawa. Rozwiązaniem jest wariant wywołania printk() przystosowany do wyprowadzania komunikatów na konsolę we wczesnych fazach rozruchu — early_printk(). Działa ona identycznie jak printk() — funkcje te różnią się wyłącznie nazwami i możliwością operowania w pierwszych fazach rozruchu. Nie jest to jednak rozwiązanie przenośne, gdyż funkcja early_printk() nie jest implementowana we wszystkich architekturach. Dobrze, żeby diagnozowana architektura ją posiadała — a większość (z architekturą x86 na czele) posiada. Podsumowując, o ile nie zachodzi potrzeba sygnalizacji na bardzo wczesnym etapie rozruchu, można polegać na wszechstronności i niezawodności funkcji printk(). Poziomy diagnostyczne Główna różnica pomiędzy wywołaniami printk() i printf() tkwi w zdolności tej pierwszej do określania tak zwanego poziomu diagnostycznego (ang. loglevel). Jądro określa poziom diagnostyczny, decydując tym samym, czy komunikat powinien zostać wyświetlony na konsoli czy też przekierowany gdzieś indziej. Jądro wyświetla na konsoli wszystkie komunikaty o poziomie diagnostycznym ustalonym na poziomie niższym od pewnego progu. Poziom diagnostyczny określa się następująco: printk(KERN_WARNING To jest ostrzezenie! ); printk(KERN_DEBUG To jest komunikat diagnostyczny! ); printk( Brak okreslenia poziomu diagnostycznego! ); Ciągi KERN_WARNING i KERN_DEBUG to po prostu definicje występujące w pliku linux/printk.h . Rozwijane są one odpowiednio do ciągów 4 i 7 i dołączane na początek komunikatu przekazywanego do printk(). Jądro na podstawie tych przedrostków decyduje o tym, które z komunikatów powinny być wyświetlane na konsoli, porównując określony poziom diagnostyczny z bieżącym poziomem diagnostycznym konsoli określonym parametrem console_loglevel. Pełny wykaz dostępnych poziomów diagnostycznych funkcji printk() został przedstawiony w tabeli 18.1. Tabela 18.1. Poziomy diagnostyczne funkcji printk() Poziom diagnostyczny KERN_EMERG KERN_ALERT KERN_CRIT KERN_ERR KERN_WARNING KERN_NOTICE KERN_INFO KERN_DEBUG Opis Sytuacja awaryjna. Problem wymagający natychmiastowej interwencji. Sytuacja krytyczna. Błąd. Ostrzeżenie. Sytuacja normalna, ale warta odnotowania. Komunikat informacyjny. Komunikat diagnostyczny — najprawdopodobniej zbyteczny. Kup książkęPoleć książkę Diagnostyka komunikatami 437 W przypadku nieokreślenia poziomu rejestrowania jego wartość jest przyjmowana przez domniemanie jako DEFAULT_MESSAGE_LOGLEVEL, która to stała jest z kolei rozwijana do stałej KERN_WARNING. Jednak z uwagi na to, że ustawienie domyślne może w kolejnych wersjach jądra ulec zmianie, warto jawnie opatrywać komunikaty stałymi poziomów rejestrowania. Najwyższy poziom rejestrowania definiuje stała KERN_EMERG rozwijana do literału znakowego 0 . Poziom najniższy określa zaś stała KERN_DEBUG rozwijana do ciągu 7 . Na przykład po zakończenia fazy przetwarzania pliku kodu źródłowego przez preprocesor zamieszczone wcześniej wywołania będą miały postać: printk( 4 To jest ostrzezenie! ); printk( 7 To jest komunikat diagnostyczny! ); printk( 4 Brak okreslenia poziomu diagnostycznego! ); Strategia przyjmowania poziomów rejestrowania w różnych sytuacjach leży całkowicie w gestii programisty. Rzecz jasna, zwykłe komunikaty należałoby opatrywać odpowiednim dla nich poziomem rejestrowania. Ale już komunikaty, którymi szpikuje się kod w poszukiwaniu źródła problemu — wypada się do tego przyznać, wszyscy tak robią — można opatrywać dowolnym poziomem rejestrowania. Jedną z możliwości jest pozostawienie w spokoju domyślnego poziomu rejestrowania konsoli i generowania wszystkich komunikatów diagnostycznych z poziomem KERN_CRIT lub wyższym. Można też generować komunikaty na poziomie KERN_DEBUG i w zamian zmodyfikować poziom rejestrowania konsoli, tak aby komunikaty były widoczne. Każda z metod ma swoje wady i zalety. Decyzję pozostawiam Czytelnikowi. Bufor komunikatów Komunikaty jądra umieszczane są w cyklicznym buforze o rozmiarze LOG_BUF_LEN. Rozmiar ten daje się konfigurować na etapie kompilacji przez ustawienie opcji CONFIG_LOG_BUF_SHIFT. Domyślny rozmiar bufora dla komputerów jednoprocesorowych to 16 kB. Innymi słowy, jądro może przechowywać do 16 kB komunikatów jądra. Jeżeli kolejka komunikatów jest zapełniona i dojdzie do kolejnego wywołania printk(), nowy komunikat nadpisze najstarszy z komunikatów w buforze. Bufor komunikatów nosi nazwę cyklicznego, ponieważ jego zapis i odczyt następują w sposób cykliczny. Korzystanie z bufora cyklicznego ma szereg zalet. Z racji dużej łatwości równoczesnego zapisywania i odczytywania z takiego bufora funkcja printk() może być wywoływana nawet z poziomu kontekstu. Co więcej, cykliczność upraszcza zarządzanie buforem. W obliczu zbyt dużej liczby komunikatów najstarsze komunikaty są po prostu zastępowane nowymi. Jeżeli zdarzy się problem, w wyniku którego wygenerowana zostanie większa liczba komunikatów, cykliczność obsługi bufora wyeliminuje część z nich, nie dopuszczając do zwiększenia zapotrzebowania na pamięć. Jedyną wadą takiego rozwiązania jest prawdopodobieństwo utraty komunikatów, ale jest to niewielka cena za wszechstronność bufora. Kup książkęPoleć książkę 438 Rozdzia(cid:228) 18. Diagnostyka b(cid:228)(cid:246)dów j(cid:241)dra Demony syslogd i klogd W klasycznym systemie Linux za pobieranie komunikatów jądra z bufora odpowiedzialny jest demon przestrzeni użytkownika o nazwie klogd — demon ten wypełnia pobieranymi komunikatami systemowy plik dziennika, korzystając przy tym z pomocy demona syslogd. W celu odczytu rejestru komunikatów klogd może odczytywać plik /proc/kmsg bądź korzystać z wywołania systemowego syslog(). Domyślnie wykorzystuje jednak system plików /proc. Niezależnie od sposobu odczytywania komunikatów klogd ulega zawieszeniu aż do momentu pojawienia się nowych komunikatów. W obliczu zgłoszenia nowych komunikatów demon jest pobudzany, odczytuje nowe komunikaty i przetwarza je. Domyślnie przetwarzanie to polega na przekazaniu ich do demona syslogd. Demon syslogd dołącza otrzymywane komunikaty do pliku, którym przez domniemanie jest plik /var/log/messages. Działanie demona da się konfigurować za pośrednictwem pliku /etc/syslog.conf. Za pośrednictwem demona klogd można zmieniać poziom rejestrowania konsoli — wystarczy w wywołaniu demona określić argument -c. printf(), printk() — (cid:228)atwo o pomy(cid:228)k(cid:246) Każdemu początkującemu programiście jądra zdarza się mylić wywołania printk() z wywołaniami printf(). To całkiem naturalne, ponieważ nie sposób zignorować lata doświadczeń i nawyku wykorzystywania funkcji printf() w programach przestrzeni użytkownika. Na szczęście takie pomyłki są szybko wychwytywane, jako że powodują przy kompilacji zalew komunikatami z protestami ze strony konsolidatora. Pewnego dnia być może zdarzy się Czytelnikowi zastosować w wyniku wyniesionych z programowania jądra nawyków wywołanie printk() w programie przestrzeni użytkownika. Wtedy będzie on mógł o sobie powiedzieć, że jest prawdziwym hakerem jądra. B(cid:228)(cid:241)d oops Błąd oops to normalny sposób powiadamiania użytkownika o nieprawidłowościach działania jądra. Jako że jądro to nadzorca całego systemu, nie ma możliwości samodzielnego usunięcia usterki czy wykonania samounicestwienia, tak jak unicestwia się błędne procesy przestrzeni użytkownika. Jądro w takich sytuacjach zgłasza błąd oops. Polega to na wyświetleniu na konsoli komunikatu o błędzie wraz z zawartością rejestrów i śladem wykonania (ang. back trace). Błąd jądra jest trudny do obejścia, więc jądro w celu obsłużenia błędu musi się nieźle napracować. Niekiedy po zakończeniu obsługi pojawia się niespójność jądra. Jądro w momencie pojawienia się błędu mogło być na przykład w trakcie przetwarzania istotnych danych. Mogło przetrzymywać blokadę albo prowadzić komunikację ze sprzętem. W obliczu błędu konieczne jest natomiast ostrożne wycofanie się od poprzedniego kontekstu i w miarę możliwości przywrócenie kontroli nad systemem. W wielu przypadkach powrót taki jest niemożliwy. Jeżeli błąd wystąpi w kontekście przerwania, jądro nie może Kup książkęPoleć książkę B(cid:228)(cid:241)d oops 439 kontynuować działania i „panikuje”. Błąd „paniczny” (ang. panic error) powoduje zaś trwałe unieruchomienie systemu. Również pojawienie się błędu oops w trakcie wykonywania zadania jałowego (o numerze pid równym zero) bądź zadania init (pid równy jeden) oznacza błąd paniczny — jądro nie może kontynuować działania bez tych dwóch ważnych procesów. Jedynie wystąpienie błędu oops w kontekście jednego ze zwykłych procesów użytkownika daje możliwość unicestwienia tego procesu i kontynuowania działania reszty systemu. Przyczyny błędu oops mogą być rozmaite, z nieuprawnionym dostępem do pamięci bądź próbą wykonania niedozwolonej instrukcji włącznie. Programista jądra jest skazany na diagnostykę takich błędów (nie mówiąc o tym, że sam przyczynia się do ich powstawania). Poniższy wydruk to komunikat towarzyszący błędowi oops zaobserwowanemu w komputerze PPC w procedurze obsługi zegara karty sieciowej: Oops: Exception in kernel mode, sig: 4 Unable to handle kernel NULL pointer dereference at virtual address 00000001 NIP: C013A7F0 LR: C013A7F0 SP: C0685E00 REGS: c0905d10 TRAP: 0700 Not tained MSR: 00089037 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11 TASK = c0712530[0] swapper Last syscall: 120 GPR00: C013A7C0 C0295E00 C0231530 0000002F 00000001 C0380CB8 C0291B80 C02D0000 GPR08: 000012A0 00000000 00000000 C0292AA0 4020A088 00000000 00000000 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 GPR24: 00000000 00000005 00000000 00001032 C3F70000 00000032 FFFFFFFF C3F7C1C0 Call trace: [c013ab30] tulip_timer+0x128/0x1c4 [c0020744] run_timer_softirq+0x10c/0x164 [c001b864] do_softirq+0x88/0x104 [c0007e80] timer_interrupt+0x284/0x298 [c00033c4] ret_from_except+0x0/0x34 [c0007b84] default_idle+0x20/0x60 [c0007bf8] cpu_idle+0x34/0x38 [c0003ae8] rest_init+0x24/0x34 Użytkownicy komputerów klasy PC mogą dziwić się znaczną liczbą rejestrów (aż 32!). Błędy oops w znacznie popularniejszych systemach klasy x86-32 generują dużo krótszy wydruk zawartości rejestrów. Najważniejsze informacje są jednak w obu architekturach identyczne — liczy się zawartość rejestrów i ślad wykonania. Ślad wykonania to łańcuch wywołania funkcji prowadzący do błędu. W prezentowanym przypadku ślad zdradza dokładnie przebieg wykonania aż do momentu wystąpienia błędu — system realizował proces jałowy w pętli cpu_idle(), w której wywoływana jest funkcja default_idle(). Zgłoszenie przerwania zegarowego spowodowało zainicjowanie obsługi liczników. Uruchomiona wtedy procedura obsługi takiego licznika dla karty sieciowej tulip_timer() wykonała w ramach przetwarzania wyłuskanie wskaźnika o wartości NULL. Na podstawie podanych na wydruku offsetów (tutaj 0x128/0x1c4) można wręcz wytypować konkretny wiersz programu, którego wykonanie spowodowało błąd. Kup książkęPoleć książkę 440 Rozdzia(cid:228) 18. Diagnostyka b(cid:228)(cid:246)dów j(cid:241)dra Równie przydatna jak ślad wykonania może być zawartość rejestrów. Dysponując kopią problematycznej funkcji w postaci kodu asemblerowego, można na podstawie zawartości rejestrów odtworzyć dokładnie stan jej wykonania w momencie wystąpienia błędu. Obecność w jednym z rejestrów nieoczekiwanej wartości może często rzucić światło na przyczynę błędu. W analizowanym przypadku widać, które z rejestrów zawierają wartości NULL (zera), i na tej podstawie można wytypować argument wywołania bądź zmienną lokalną funkcji, która przyjęła niewłaściwą wartość. Dla sytuacji podobnych do analizowanej typowym źródłem błędu jest sytuacja hazardowa — w tym konkretnym przypadku chodzi o rywalizację w dostępie do zasobu pomiędzy obsługą licznika a resztą kodu obsługi karty sieciowej. Diagnostyka sytuacji hazardowych jest zresztą zawsze problematyczna. Polecenie ksymoops Prezentowany wcześniej wydruk generowany w ramach obsługi błędu oops nosi nazwę zdekodowanego, ponieważ adresy pamięci zostały na wydruku przetłumaczone na nazwy funkcji rezydujących pod tymi adresami. Wersja niezdekodowana tego samego błędu wyglądałaby następująco: NIP: C013A7F0 LR: C013A7F0 SP: C0685E00 REGS: c0905d10 TRAP: 0700 Not tained MSR: 00089037 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11 TASK = c0712530[0] swapper Last syscall: 120 GPR00: C013A7C0 C0295E00 C0231530 0000002F 00000001 C0380CB8 C0291B80 C02D0000 GPR08: 000012A0 00000000 00000000 C0292AA0 4020A088 00000000 00000000 000000
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Jądro Linuksa. Przewodnik programisty
Autor:

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: