Jądro Linuksa. Przewodnik programisty - Helion
Tytuł oryginału: Linux Kernel Development (3rd Edition)
Tłumaczenie: Przemysław Szeremiota
ISBN: 978-83-246-4273-1
stron: 504, Format: 170x230, okładka: miękka
Data wydania: 2014-02-21
Księgarnia: Helion
Cena książki: 79,00 zł
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:
- pobierzesz, skonfigurujesz i skompilujesz źródła jądra
- zrozumiesz zasady zarządzania procesami
- poznasz struktury danych jądra
- wykorzystasz wirtualne systemy plików
- zyskasz możliwość samodzielnego rozwijania jądra system Linux
Przekonaj się, jak działa jądro Linuksa!
Osoby które kupowały "Jądro Linuksa. Przewodnik programisty", wybierały także:
- Bash. Techniki zaawansowane. Kurs video. Zostań administratorem systemów IT 169,00 zł, (50,70 zł -70%)
- Administracja systemem Linux. Kurs video. Przewodnik dla początkujących 59,00 zł, (17,70 zł -70%)
- Gray Hat C#. Język C# w kontroli i łamaniu zabezpieczeń 57,74 zł, (17,90 zł -69%)
- Python dla administrator 178,97 zł, (62,64 zł -65%)
- Cybersecurity dla ka 144,86 zł, (52,15 zł -64%)
Spis treści
Jądro Linuksa. Przewodnik programisty -- spis treści
Przedmowa (17)
Wstęp (19)
Rozdział 1. Jądro systemu Linux - wprowadzenie (25)
- Historia Uniksa (25)
- Wprowadzenie do systemu Linux (27)
- Przegląd systemów operacyjnych (29)
- Jądro Linuksa a jądro klasycznego systemu uniksowego (31)
- Oznaczenia wersji jądra Linuksa (34)
- Społeczność programistów jądra Linuksa (35)
- Zanim zaczniemy (36)
Rozdział 2. Linux - zaczynamy (37)
- Kod źródłowy jądra (37)
- Git (37)
- Instalowanie źródeł jądra z archiwum (38)
- Aplikowanie łat (39)
- Struktura katalogów kodu źródłowego jądra (39)
- Kompilowanie jądra (40)
- Konfigurowanie jądra (41)
- Minimalizacja szumu podczas kompilacji (43)
- Kompilacja na wielu frontach (43)
- Instalowanie nowego jądra (44)
- Odmienność jądra (45)
- Brak implementacji i nagłówków biblioteki standardowej C (45)
- GNU C (47)
- Brak mechanizmu ochrony pamięci (49)
- Niemożność (łatwego) korzystania z operacji zmiennoprzecinkowych (50)
- Ograniczony co do rozmiaru (i stały) stos (50)
- Synchronizacja i współbieżność (50)
- Znaczenie przenośności (51)
- Podsumowanie (51)
Rozdział 3. Zarządzanie procesami (53)
- Proces (53)
- Deskryptor procesu i struktura zadania (55)
- Przydział deskryptora procesu (55)
- Przechowywanie deskryptora procesu (57)
- Stan procesu (58)
- Manipulowanie bieżącym stanem procesu (59)
- Kontekst procesu (60)
- Drzewo procesów (60)
- Tworzenie procesu (62)
- Kopiowanie przy zapisie (62)
- Rozwidlanie procesu (63)
- Wywołanie vfork() (64)
- Wątki w systemie Linux (65)
- Tworzenie wątków (66)
- Wątki jądra (67)
- Zakończenie procesu (68)
- Usuwanie deskryptora procesu (70)
- Problem zadań osieroconych (71)
- Podsumowanie (73)
Rozdział 4. Szeregowanie zadań (75)
- Wielozadaniowość (75)
- Planista zadań w Linuksie (77)
- Strategia postępowania (77)
- Procesy ograniczone wejściem-wyjściem a procesy ograniczone procesorem (78)
- Priorytet procesu (79)
- Kwant czasu procesora (80)
- Strategia szeregowania w działaniu (81)
- Algorytm szeregowania zadań w Linuksie (82)
- Klasy szeregowania (82)
- Szeregowanie procesów w systemach klasy Unix (82)
- Sprawiedliwe szeregowanie zadań (85)
- Implementacja szeregowania zadań w Linuksie (87)
- Zliczanie czasu wykonania (87)
- Wybór procesu (89)
- Punkt wejścia do planisty CFS (94)
- Zawieszanie i wybudzanie procesów (95)
- Wywłaszczanie i przełączanie kontekstu (99)
- Wywłaszczanie procesu użytkownika (100)
- Wywłaszczenie jądra (101)
- Szeregowanie czasu rzeczywistego (102)
- Wywołania systemowe związane z szeregowaniem (103)
- Wywołania wpływające na strategię szeregowania i wartości priorytetów (104)
- Wywołania systemowe sterujące kojarzeniem procesów z procesorami (105)
- Odstąpienie procesora (105)
- Podsumowanie (106)
Rozdział 5. Wywołania systemowe (107)
- Komunikacja z jądrem systemu (107)
- API, POSIX i biblioteka C (108)
- Wywołania systemowe (109)
- Numery wywołań systemowych (111)
- Wydajność wywołania systemowego (111)
- Procedura obsługi wywołań systemowych (111)
- Oznaczanie właściwego wywołania systemowego (112)
- Przekazywanie argumentów (113)
- Implementacja wywołania systemowego (113)
- Implementowanie wywołań systemowych (114)
- Weryfikacja argumentów (114)
- Kontekst wywołania systemowego (118)
- Wiązanie wywołania systemowego (119)
- Inicjowanie wywołania systemowego z przestrzeni użytkownika (120)
- Sześć powodów, aby nie implementować wywołań systemowych (121)
- Podsumowanie (122)
Rozdział 6. Struktury danych jądra (123)
- Listy (123)
- Listy jedno- i dwukierunkowe (124)
- Listy cykliczne (124)
- Implementacja list w jądrze Linuksa (126)
- Operacje na listach (128)
- Przeglądanie list (131)
- Inne operacje na listach (134)
- Kolejki (135)
- kfifo (135)
- Tworzenie kolejki (136)
- Zakolejkowanie (137)
- Wyciąganie danych (137)
- Określanie rozmiaru kolejki (137)
- Zerowanie i usuwanie kolejki (138)
- Przykład użycia kolejki kfifo (138)
- Mapy (139)
- Inicjalizowanie mapy idr (140)
- Przydział nowego identyfikatora UID (140)
- Odwzorowanie UID na wskaźnik (141)
- Usuwanie UID (142)
- Usuwanie idr (142)
- Drzewa binarne (143)
- Drzewa BST (143)
- Zrównoważone drzewa BST (144)
- Drzewa czerwono-czarne (145)
- rbtree (146)
- Kiedy i jakiej struktury użyć? (148)
- Złożoność obliczeniowa (149)
- Algorytmy (149)
- Notacja O (149)
- Notacja theta (150)
- Złożoność czasowa (150)
- Podsumowanie (151)
Rozdział 7. Przerwania i procedury obsługi przerwań (153)
- Przerwania (154)
- Procedury obsługi przerwań (155)
- Połówki górne i dolne (156)
- Rejestrowanie procedury obsługi przerwania (157)
- Znaczniki procedury obsługi przerwań (158)
- Przykładowe przerwanie (159)
- Zwalnianie procedury obsługi przerwania (160)
- Tworzenie procedury obsługi przerwań (160)
- Procedury obsługi przerwań współużytkowanych (162)
- Prawdziwa procedura obsługi przerwania (163)
- Kontekst przerwania (165)
- Implementacja obsługi przerwań (166)
- /proc/interrupts (168)
- Kontrola przerwań (169)
- Wyłączanie i włączanie przerwań (170)
- Blokowanie konkretnej linii przerwania (172)
- Stan systemu przerwań (173)
- Podsumowanie (174)
Rozdział 8. Dolne połówki i czynności odroczone (175)
- Połówki dolne (176)
- Po co dolne połówki? (177)
- Świat dolnych połówek (178)
- Przerwania programowe (181)
- Implementacja przerwań programowych (181)
- Korzystanie z przerwań programowych (183)
- Tasklety (186)
- Implementacja taskletów (186)
- Korzystanie z taskletów (189)
- Wątek jądra ksoftirqd (191)
- Dawny mechanizm BH (193)
- Kolejki prac (194)
- Implementacja kolejek prac (195)
- Korzystanie z kolejek prac (199)
- Dawny mechanizm kolejkowania zadań (201)
- Jak wybrać implementację dolnej połówki? (202)
- Blokowanie pomiędzy dolnymi połówkami (204)
- Wyłączanie dolnych połówek (204)
- Podsumowanie (206)
Rozdział 9. Wprowadzenie do synchronizacji jądra (207)
- Sekcje krytyczne i przeplot operacji (208)
- Po co ta ochrona? (208)
- Zmienna globalna (210)
- Blokowanie (211)
- Źródła współbieżności (213)
- Co wymaga zabezpieczania? (215)
- Zakleszczenia (216)
- Rywalizacja a skalowalność (218)
- Podsumowanie (220)
Rozdział 10. Metody synchronizacji jądra (221)
- Operacje niepodzielne (221)
- Niepodzielne operacje na liczbach całkowitych (222)
- 64-bitowe operacje niepodzielne (226)
- Niepodzielne operacje bitowe (228)
- Rygle pętlowe (230)
- Interfejs rygli pętlowych (231)
- Inne metody blokowania ryglami pętlowymi (234)
- Rygle pętlowe a dolne połówki (234)
- Rygle pętlowe R-W (235)
- Semafory (238)
- Semafory binarne i zliczające (239)
- Tworzenie i inicjalizowanie semaforów (240)
- Korzystanie z semaforów (240)
- Semafory R-W (241)
- Muteksy (243)
- Muteksy czy semafory? (245)
- Muteksy czy rygle pętlowe? (245)
- Zmienne sygnałowe (245)
- Blokada BKL (Big Kernel Lock) (246)
- Blokady sekwencyjne (247)
- Blokowanie wywłaszczania (249)
- Bariery pamięciowe (251)
- Podsumowanie (255)
Rozdział 11. Liczniki i zarządzanie czasem (257)
- Czas z punktu widzenia jądra (258)
- Częstotliwość taktowania - HZ (259)
- Optymalna wartość HZ (260)
- Zalety wysokich wartości HZ (261)
- Wady wysokich wartości HZ (262)
- Chwilki (263)
- Wewnętrzna reprezentacja zmiennej jiffies (264)
- Zawijanie zmiennej jiffies (266)
- HZ a przestrzeń użytkownika (267)
- Zegary i liczniki sprzętowe (268)
- Zegar czasu rzeczywistego (268)
- Zegar systemowy (269)
- Procedura obsługi przerwania zegarowego (269)
- Data i godzina (272)
- Liczniki (274)
- Korzystanie z liczników (275)
- Liczniki i sytuacje hazardowe (277)
- Implementacja licznika (277)
- Opóźnianie wykonania (278)
- Oczekiwanie w pętli aktywnej (278)
- Krótkie opóźnienia (280)
- Funkcja schedule_timeout() (281)
- Implementacja funkcji schedule_timeout() (282)
- Podsumowanie (284)
Rozdział 12. Zarządzanie pamięcią (285)
- Strony (285)
- Strefy (287)
- Pozyskiwanie stron pamięci (290)
- Pozyskiwanie czystych stron pamięci (291)
- Zwalnianie stron (291)
- Funkcja kmalloc() (292)
- Znaczniki gfp_mask (293)
- Funkcja kfree() (298)
- Funkcja vmalloc() (299)
- Alokator plastrowy (301)
- Zadania alokatora plastrowego (302)
- Interfejs alokatora plastrowego (305)
- Przydział z pamięci podręcznej (307)
- Statyczne przydziały na stosie (309)
- Jednostronicowy stos procesów jądra (309)
- Ostrożnie ze stosem (310)
- Odwzorowanie pamięci wysokiej (310)
- Odwzorowanie trwałe (311)
- Odwzorowania czasowe (311)
- Przydziały lokalne względem procesora (312)
- Interfejs percpu (313)
- Statyczne dane lokalne względem procesora (313)
- Dynamiczne dane lokalne względem procesora (314)
- Przydatność danych lokalnych względem procesora (315)
- Wybór metody przydziału pamięci w kodzie jądra (316)
- Podsumowanie (317)
Rozdział 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łównego (325)
- Operacje bloku głównego (326)
- Obiekt i-węzła (329)
- Operacje i-węzł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ł 14. Blokowe urządzenia wejścia-wyjścia (349)
- Anatomia urządzenia blokowego (350)
- Bufory i nagłówki buforów (351)
- Struktura bio (354)
- Wektory wejścia-wyjścia (355)
- Stare a nowe (357)
- Kolejki zleceń (357)
- Zawiadywanie operacjami wejścia-wyjścia (358)
- Zadania planisty operacji wejścia-wyjścia (359)
- Winda Linusa (360)
- Terminowy planista operacji wejścia-wyjścia (361)
- Przewidujący planista operacji wejścia-wyjścia (363)
- Sprawiedliwy planista kolejkowania operacji wejścia-wyjścia (364)
- Nieingerujący planista operacji wejścia-wyjścia (365)
- Wybór planisty operacji wejścia-wyjścia (366)
- Podsumowanie (366)
Rozdział 15. Przestrzeń adresowa procesu (367)
- Przestrzenie adresowe (367)
- Deskryptor pamięci (369)
- Przydział deskryptora pamięci (371)
- Zwalnianie deskryptora pamięci (371)
- Struktura mm_struct i wątki jądra (372)
- Obszary pamięci wirtualnej (372)
- Znaczniki VMA (374)
- Operacje VMA (375)
- Obszary pamięci na listach i w drzewach (376)
- Obszary pamięci w praktyce (377)
- Manipulowanie obszarami pamięci (379)
- Funkcja find_vma() (379)
- Funkcja find_vma_prev() (381)
- Funkcja find_vma_intersection() (381)
- Tworzenie interwału adresów - wywołania mmap() i do_mmap() (381)
- Usuwanie interwału adresów - wywołania munmap() i do_munmap() (383)
- Tablice stron (384)
- Podsumowanie (386)
Rozdział 16. Pamięć podręczna stron i opóźniony zapis stron w tle (387)
- Modele pamięci podręcznych (387)
- Buforowanie zapisów (388)
- Eksmisja z pamięci podręcznej (389)
- Pamięć podrę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ęć podręczna buforów (396)
- Wątki zapisu w tle (396)
- Tryb laptopowy (398)
- Rys historyczny - bdflush, kupdated i pdflush (399)
- Eliminowanie obciążenia operacjami wejścia-wyjścia (400)
- Podsumowanie (401)
Rozdział 17. Sterowniki i moduły (403)
- Typy urządzeń (403)
- Moduły (404)
- Hello, world! (405)
- Kompilowanie modułów (406)
- Instalowanie modułów (409)
- Generowanie zależności międzymodułowych (409)
- Ładowanie modułów (410)
- Zarządzanie opcjami konfiguracji jądra (411)
- Parametry modułów (413)
- Symbole eksportowane (415)
- Model sterowników (416)
- Obiekty jądra (417)
- Typy obiektów jądra (418)
- Grupy obiektów jądra (419)
- Powiązania pomiędzy obiektami, typami i grupami obiektów jądra (419)
- Zarządzanie i operowanie obiektami jądra (420)
- Zliczanie odwołań (421)
- System plików sysfs (423)
- Dodawanie i usuwanie obiektów jądra w sysfs (426)
- Dodawanie plików do sysfs (427)
- Kernel Event Layer (430)
- Podsumowanie (431)
Rozdział 18. Diagnostyka błędów jądra (433)
- Od czego zacząć? (433)
- Błędy w jądrze (434)
- Diagnostyka komunikatami (435)
- Niezawodność printk() (435)
- Poziomy diagnostyczne (436)
- Bufor komunikatów (437)
- Demony syslogd i klogd (438)
- printf(), printk() - łatwo o pomyłkę (438)
- Błąd oops (438)
- Polecenie ksymoops (440)
- kallsyms (441)
- Opcje diagnostyczne jądra (441)
- Asercje i wypisywanie informacji o błędach (442)
- Funkcja Magic SysRq Key (443)
- Saga debugera jądra (444)
- gdb (445)
- kgdb (446)
- Stymulowanie i sondowanie systemu (446)
- Uzależnianie wykonania kodu od identyfikatora UID (446)
- Korzystanie ze zmiennych warunkowych (447)
- Korzystanie ze statystyk (447)
- Ograniczanie częstotliwości i liczby komunikatów diagnostycznych (448)
- Szukanie winowajcy - wyszukiwanie binarne (449)
- Binarne wyszukiwanie wersji za pomocą Gita (450)
- Koledzy - kiedy wszystko inne zawiedzie (451)
- Podsumowanie (451)
Rozdział 19. Przenośność (453)
- Przenośne systemy operacyjne (453)
- Historia przenośności systemu Linux (455)
- Rozmiar sł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łnienie struktury (463)
- Wzajemny porządek bajtów (465)
- Pomiar upływu czasu (467)
- Rozmiar strony (468)
- Kolejność wykonywania instrukcji (469)
- Tryb SMP, wywłaszczanie jądra i pamięć wysoka (469)
- Podsumowanie (470)
Rozdział 20. Kodowanie, łaty i społeczność (471)
- Społeczność (471)
- Obowiązujący styl kodowania (472)
- Wcięcia (472)
- Instrukcje switch (473)
- Odstępy (473)
- Nawiasy klamrowe (475)
- Długość wiersza kodu (476)
- Nazewnictwo (476)
- 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łego stylu (479)
- Łańcuch poleceń (480)
- Przesyłanie raportów o błędach (480)
- Łaty (481)
- Generowanie łat (481)
- Generowanie łat za pomocą Gita (482)
- Rozsyłanie łat (483)
- Podsumowanie (484)
Dodatek A. Bibliografia (485)
- Książki o projektowaniu systemów operacyjnych (485)
- Książki o jądrze systemu Unix (486)
- Książki o jądrze systemu Linux (486)
- Książki o jądrach innych systemów operacyjnych (487)
- Książki o interfejsie programowym Uniksa (487)
- Książki o programowaniu w języku C (487)
- Inne książki (488)
- Witryny WWW (488)
Skorowidz (489)