2013-06-20 15 views
7

Jestem zdezorientowany tym, jak dokładnie struktura jądra i przestrzeń użytkownika są uporządkowane i jakie części pamięci są zajmowane. Mój obecny (prawdopodobnie błędne) zrozumienie to:Przestrzeń jądra systemu Linux i przestrzeń użytkownika

  1. Proces jest tworzony i pamięci wirtualnej Ta procesów jest podzielona na przestrzeni użytkownika i regionu kernel-space, gdzie jako obszar przestrzeni użytkownika zawiera dane, kod, stos, stertę itp. procesu i region przestrzeni jądra zawiera rzeczy takie jak tabela stron dla procesu i kod jądra. Nie jestem pewien, jaki byłby kod jądra ... kod sterownika lub podobne rzeczy?

  2. Co więcej, czy tabela wywołań systemowych jest zawsze odwzorowywana na ten sam region w przestrzeni jądra procesu? (Czy można powiedzieć "przestrzeń jądra procesu"?

  3. Jeśli napiszę własny sterownik/moduł i wstawię go, czy ten kod sterownika zostanie automatycznie skopiowany do przestrzeni jądra każdego nowego procesu który jest tworzony? Jeśli nie ... jak dokładnie to działa?

Dzięki z góry za każdym wejściem, literatura/linki, które mogą pomóc wyjaśnić moje pytania są w porządku, jak również.

Wiwaty, Cegła

Odpowiedz

27

Generalnie masz rację, ale dokonaj tego: jest tylko jedna "przestrzeń jądra" dla całej maszyny, a wszystkie procesy ją udostępniają.

Gdy proces jest aktywny, może działać w "trybie użytkownika" lub "trybie jądra".

W trybie użytkownika instrukcje wykonywane przez procesor znajdują się w przestrzeni pamięci mapy obszaru użytkownika. Program uruchamia własny kod lub kod z biblioteki przestrzeni użytkownika. W trybie użytkownika proces ma ograniczone możliwości. W CPU znajduje się flaga, która mówi, żeby nie pozwalała na używanie uprzywilejowanych instrukcji, a pamięć jądra, mimo że istnieje w mapie pamięci procesu, jest niedostępna. (Nie chciałbyś pozwolić, aby jakikolwiek program właśnie przeczytał i zapisał pamięć jądra - znikłoby całe bezpieczeństwo.)

Gdy proces chce zrobić coś innego niż przenoszenie danych w swojej własnej (przestrzeni użytkownika) pamięci wirtualnej, np. Otwórz plik na przykład, musi zrobić syscall. Każda architektura procesora ma własną, unikalną, dziwaczną metodę tworzenia systemu, ale wszystko to sprowadza się do: wykonanie magicznej instrukcji, procesor włącza flagę "trybu uprzywilejowanego" i przeskakuje do specjalnego adresu w przestrzeni jądra, "syscall" Punkt wejścia".

Teraz proces działa w trybie jądra.Wykonywane instrukcje znajdują się w pamięci jądra i mogą odczytywać i zapisywać dowolną pamięć, którą chcą. Jądro analizuje żądanie, które właśnie wykonał proces i decyduje, co z nim zrobić.

W przykładzie open jądro otrzymuje 2 lub 3 parametry odpowiadające argumentom int open(const char *filename, int flags[, int mode]). Pierwszy argument podaje przykład, kiedy kernelspace potrzebuje dostępu do przestrzeni użytkownika. Powiedziałeś open("foo", O_RDONLY), więc ciąg "foo" jest częścią twojego programu w przestrzeni użytkownika. Mechanizm syscall przekazał jedynie wskaźnik, a nie ciąg znaków, więc jądro musi odczytać ciąg z pamięci użytkownika.

Aby znaleźć żądany plik, jądro może skonsultować się ze sterownikami systemu plików (aby dowiedzieć się, gdzie plik jest) i zablokować sterowniki urządzeń (aby załadować niezbędne bloki z dysku) lub sterowniki i protokoły urządzeń sieciowych (aby załadować plik ze zdalnego źródła). Wszystkie te rzeczy są częścią jądra, tj. W przestrzeni jądra, niezależnie od tego, czy są one wbudowane czy zostały załadowane jako moduły.

Jeśli żądanie nie może zostać spełnione natychmiast, jądro może uśpić proces. Oznacza to, że proces zostanie usunięty z procesora, aż do otrzymania odpowiedzi z dysku lub sieci. Inny proces może mieć teraz szansę uruchomienia. Później, kiedy przychodzi odpowiedź, twój proces zaczyna działać ponownie (nadal w trybie jądra). Po znalezieniu pliku można ukończyć syscall open (sprawdź uprawnienia, utwórz deskryptor pliku) i powróć do przestrzeni użytkownika.

Powrót do przestrzeni użytkownika to prosta sprawa przywrócenia procesora do trybu bez uprzywilejowania i przywrócenia rejestrów do stanu sprzed przejścia użytkownika-> jądra, ze wskaźnikiem instrukcji wskazującym na instrukcję po magicznej instrukcji syscall .

Poza syscalli, istnieją inne rzeczy, które mogą spowodować przejście z trybu użytkownika do trybu jądra, w tym:

  1. stronie usterek - jeśli proces uzyskuje dostęp do wirtualnego adresu pamięci, że nie ma adresu fizycznego przypisany do niego, CPU wchodzi w tryb jądra i przeskakuje do procedury obsługi błędów strony. Jądro następnie decyduje, czy adres wirtualny jest prawidłowy czy nie, i tworzy fizyczną stronę i wznawia proces w przestrzeni użytkownika, w której zostało przerwane, lub wysyła SIGSEGV.
  2. przerwania - niektóre urządzenia (sieć, dysk, port szeregowy itp.) Powiadamiają procesor, który wymaga uwagi. CPU wchodzi w tryb jądra i przeskakuje do modułu obsługi, jądro reaguje na niego, a następnie wznawia proces przestrzeni użytkownika, który był uruchomiony przed przerwaniem.

Ładowanie modułu odbywa się za pomocą systemu operacyjnego, który prosi jądro o skopiowanie kodu modułu i danych do jądra i uruchomienie kodu inicjalizacyjnego w trybie jądra.

To dość długo, więc zatrzymuję się. Mam nadzieję, że przejście koncentrujące się na zmianach w jądrze użytkownika dostarczyło wystarczających przykładów, aby zestroić ten pomysł.

2

Nie ma region jądra w mapie wirtualnej pamięci procesu. Mapa pamięci wirtualnej zawiera: tekst, bss, dane, stertę, stos załadowanego programu i udostępnione biblioteki. W Linuksie możesz sprawdzić/proc/$ PID/mapy dowolnego procesu przestrzeni użytkownika dla przykładu.

Gdy proces przestrzeni użytkownika uzyskuje dostęp do kodu domeny jądra za pośrednictwem wywołania systemowego, kod jądra jest wykonywany w imieniu procesu w jego stosie. Oczywiście, po powrocie z wywołania systemowego, cały kod jądra/sterownika będzie poza stosem. Aby wyjaśnić więcej, jeśli w pewnym momencie jakaś część kodu jądra nie zostanie użyta przez żaden proces, nie będzie ona częścią mapy pamięci wirtualnej dowolnego procesu.

Jeśli korzystasz z Linuksa, poleciłabym książkę "Linux kernel development" Roberta Love'a.

Powiązane problemy