- Jaka jest różnica między stosem jądra a stosem użytkownika?
Krótko mówiąc, nic - poza wykorzystaniem innej lokalizacji w pamięci (a co za tym idzie innej wartości dla rejestru stackpointer) i zwykle różnych zabezpieczeń dostępu do pamięci. Oznacza to, że podczas wykonywania w trybie użytkownika pamięć jądra (której częścią jest stos jądra) nie będzie dostępna, nawet jeśli zostanie zmapowana. I odwrotnie, bez wyraźnego żądania przez kod jądra (w Linuksie poprzez funkcje takie jak copy_from_user()
), pamięć użytkownika (w tym stos użytkownika) zwykle nie jest bezpośrednio dostępna.
- Dlaczego używany jest [oddzielny] stos jądra?
Rozdział uprawnień i bezpieczeństwa. Po pierwsze, programy działające w przestrzeni użytkownika mogą dowolnie zmieniać stos (wskaźnik) i zwykle nie ma wymagań architektonicznych, aby mieć nawet poprawny. W związku z tym jądro nie może ufać, że wskaźnik stosu w przestrzeni użytkownika jest prawidłowy ani użyteczny, a zatem będzie wymagał jednego zestawu pod własną kontrolą. Różne architektury procesorów implementują to na różne sposoby; Procesory x86 automatycznie przełączają punkty stosu, gdy występują przełączenia trybu uprzywilejowania, a wartości, które mają być używane dla różnych poziomów uprawnień, są konfigurowalne - za pomocą kodu uprzywilejowanego (tj. tylko jądra).
- Jeśli zmienna lokalna jest zadeklarowana w ISR, gdzie będzie przechowywana?
Na stosie jądra. Jądro (Linux kernel, to jest) ma nie zahaczyć ISR bezpośrednio do X86 Architecture przerwań bram ale zamiast delegaci przerwanie wysyłka do wspólnego jądra przerwania mechanizmu wejścia / wyjścia, która oszczędza sprzed przerwania Państwowego Rejestru przed wywołaniem zarejestrowaną obsługę (s) . Procesor sam podczas wysyłania przerwania może wykonać przywilej i / lub przełącznik stosu, a to jest używane / ustawiane przez jądro tak, że wspólny kod wejściowy przerwania może już polegać na obecnym stosie jądra.
To powiedziawszy, przerwania, które występują podczas wykonywania kodu jądra, po prostu (nadal będą) używały stosu jądra na miejscu w tym momencie. Może to, jeśli procedury obsługi przerwań mają głęboko zagnieżdżone ścieżki wywołań, prowadzić do przepełnienia stosu (jeśli głęboka ścieżka wywołania jądra zostanie przerwana, a program obsługi spowoduje inną głęboką ścieżkę; w Linuksie kod RAID systemu plików / oprogramowania jest przerywany przez kod sieciowy z aktywnym iptables jest wiadomo, że wyzwala takie w niestrojonych starszych jądrach ... rozwiązaniem jest zwiększenie rozmiaru stosu jądra dla takich obciążeń).
- Czy każdy proces ma własny stos jądra?
Nie tylko każdy proces - każdy wątek ma swój własny stos jądra (i właściwie również swój własny stos użytkowników). Pamiętaj, że jedyną różnicą między procesami i wątkami (do Linuksa) jest fakt, że wiele wątków może współdzielić przestrzeń adresową (tworząc proces).
- Jak koordynuje się proces między tymi dwoma stosami?
Wcale nie - nie musi. Planowanie (jak / kiedy są uruchamiane różne wątki, jak ich stan jest zapisywany i przywracany) jest zadaniem systemu operacyjnego i procesy nie muszą się tym przejmować. W miarę tworzenia wątków (a każdy proces musi mieć co najmniej jeden wątek), jądro tworzy dla nich stosy jądra, podczas gdy stosy przestrzeni użytkownika są albo jawnie tworzone / dostarczane przez dowolny mechanizm używany do tworzenia wątku (funkcje takie jak makecontext()
lub pthread_create()
pozwalają wywołującemu określ region pamięci, który ma być używany dla stosu wątku „potomnego”) lub dziedziczony (przez klonowanie pamięci przy dostępie, zwykle nazywane „kopiuj przy zapisie” / COW, podczas tworzenia nowego procesu).
To mówi,(między innymi stan stosu wątku). Istnieje wiele sposobów na to: sygnały UNIX setcontext()
, pthread_yield()
/ pthread_cancel()
... - ale to jest disgressing nieco od pierwotnego pytania.
Moja odpowiedź jest zbierana z innych pytań SO dotyczących moich rzeczy.
Jako programista jądra wiesz, że jądro powinno być ograniczone do błędnych programów użytkownika. Załóżmy, że masz ten sam stos zarówno dla jądra, jak i przestrzeni użytkownika, a następnie prosty błąd w aplikacji użytkownika powoduje awarię jądra i wymaga ponownego uruchomienia.
Istnieje jeden „stos jądra” na procesor, taki jak stos ISR i jeden „stos jądra” na proces. Dla każdego procesu istnieje jeden „stos użytkownika”, chociaż każdy wątek ma swój własny stos, obejmujący zarówno wątki użytkownika, jak i wątki jądra.
http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html
Więc kiedy jesteśmy w trybie jądra, mechanizm stosu jest niezbędny do obsługi wywołań funkcji, zmiennych lokalnych podobnych do przestrzeni użytkownika.
http://www.kernel.org/doc/Documentation/x86/kernel-stacks
Będzie przechowywany w stosie ISR (IRQSTACKSIZE). ISR działa na oddzielnym stosie przerwań tylko wtedy, gdy obsługuje go sprzęt. W przeciwnym razie ramki stosu ISR są wpychane na stos przerywanego wątku.
Przestrzeń użytkownika nie wie i szczerze mówiąc nie dba o to, czy przerwanie jest obsługiwane w stosie jądra bieżącego procesu, czy w oddzielnym stosie ISR. Ponieważ przerwania przypadają na procesor, stos ISR musi być przypisany do procesora.
Tak. Każdy proces ma własny stos jądra.
@ Odpowiedź FrankH wygląda świetnie.
źródło
Biorąc pod uwagę rozwój jądra Linuksa Roberta Love'a, główną różnicą jest rozmiar:
Również stos jądra zawiera wskaźnik do struktury thread_info przechowującej informacje o wątku.
źródło