Jaka jest różnica między przestrzenią jądra a przestrzenią użytkownika?

Odpowiedzi:

117

Bardzo uproszczona odpowiedź jest taka, że jądro działa w przestrzeni jądra, a normalne programy działają w przestrzeni użytkownika. Przestrzeń użytkownika jest w zasadzie formą piaskownicy - ogranicza programy użytkownika, aby nie mogły zepsuć pamięci (i innych zasobów) należących do innych programów lub jądra systemu operacyjnego. Ogranicza to (ale zwykle nie całkowicie eliminuje) ich zdolność do robienia złych rzeczy, takich jak awarie maszyny.

Jądro jest rdzeniem systemu operacyjnego. Zwykle ma pełny dostęp do całej pamięci i sprzętu maszyny (i wszystkiego innego na komputerze). Aby maszyna była jak najbardziej stabilna, zwykle chcesz, aby tylko najbardziej zaufany, dobrze przetestowany kod działał w trybie jądra / w przestrzeni jądra.

Stos jest po prostu kolejną częścią pamięci, więc naturalnie jest on oddzielony wraz z resztą pamięci.

Jerry Coffin
źródło
4
Więc powiedz, jeśli mam około 10 procesów w moim systemie. Czy każdy proces ma swój własny stos, który jest podzielony na stos użytkownika i stos jądra, CZY wszystkie procesy mają jeden stos jądra?
kc3
10
@ kc3: to przynajmniej częściowo zależy od systemu operacyjnego, ale uważam, że większość ma stos trybu jądra dla każdego procesu, który jest używany, gdy jądro wykonuje pewne czynności w imieniu procesu (np. I / O) i co najmniej jeszcze jeden stos jądra, który jest przeznaczony wyłącznie do użytku wewnętrznego przez jądro (np. do planowania).
Jerry Coffin
2
Czy istnieją procesy jądra i jaki jest związek lub różnice między procesami w przestrzeni użytkownika, o których mowa w pytaniu?
Victor Choy,
Czyli per se, aby uruchomić proces przestrzeni użytkownika , musi on zostać zmapowany do przestrzeni jądra ?
roottraveller
@roottraveller: Nie jestem pewien, skąd wziął się ten pomysł, ale nie, wcale. W tym samym czasie proces przestrzeni użytkownika będzie normalnie mieć pewną (mniej lub bardziej ukrytą) pamięć w przestrzeni jądra, więc (na przykład) twój proces będzie miał stos przestrzeni użytkownika i stos przestrzeni jądra, który jest używany, gdy wykonuje wywołania systemu operacyjnego, które muszą działać w trybie jądra.
Jerry Coffin
64

Random Access Memory (RAM) może być logicznie podzielone na dwa odrębne regiony tj. - w przestrzeni jądra i przestrzeni użytkownika ( The fizyczne adresy pamięci RAM nie są faktycznie podzielone tylko wirtualne adresy , wszystko to realizowane przez MMU )

Jądro działa w uprawnionej do tego części pamięci. Ta część pamięci nie może być dostępna bezpośrednio przez procesy zwykłych użytkowników, podczas gdy jądro może uzyskać dostęp do wszystkich części pamięci. Aby uzyskać dostęp do niektórych części jądra, procesy użytkownik musiał użyć predefiniowany układ połączeń tj open, read, writeitd. Ponadto, Cfunkcje biblioteczne, takie jak printfwezwanie wywołania systemowego writez kolei.

Wywołania systemowe działają jako interfejs między procesami użytkownika a procesami jądra. Prawa dostępu są umieszczane w przestrzeni jądra, aby uniemożliwić użytkownikom nieświadome manipulowanie jądrem.

Tak więc, gdy pojawia się wywołanie systemowe, do jądra wysyłane jest przerwanie programowe. CPU może tymczasowo przekazać sterowanie do powiązanej procedury obsługi przerwań. Proces jądra, który został zatrzymany przez przerwanie, zostaje wznowiony po zakończeniu działania procedury obsługi przerwań.

Aquarius_Girl
źródło
2
Pierwsza część tej odpowiedzi jest nieprawidłowa. Pamięć RAM nie jest dzielona na jądro i przestrzeń użytkownika. Pamięć wirtualna jest. Próbowałem edytować odpowiedź, ale kolejka edycji była pełna od kilku dni. Proszę napraw. Spójrz na odpowiedź Varuna poniżej, aby uzyskać więcej informacji.
MeLikeyCode
1
@MeLikeyCode Czy nie jest to uzasadnione uproszczenie w kontekście próby udzielenia szeroko zrozumiałej odpowiedzi?
oficer problemowy
2
@problemofficer, myślę, że duże uproszczenie może zapewnić błędne podstawowe zrozumienie. Każdy powinien dowiedzieć się, że pamięć fizyczna nie jest podzielona na przestrzeń użytkownika i przestrzeń jądra, ale jądro zapewnia abstrakcję pamięci wirtualnej, która jest podzielona na jądro i przestrzeń użytkownika, a następnie jest mapowana na pamięć fizyczną.
dshil
22

Przestrzeń jądra i przestrzeń wirtualna to pojęcia pamięci wirtualnej… nie oznacza to, że Ram (twoja rzeczywista pamięć) jest podzielony na jądro i przestrzeń użytkownika. Każdy proces otrzymuje pamięć wirtualną, która jest podzielona na jądro i przestrzeń użytkownika.

Mówiąc to: „Pamięć o dostępie swobodnym (RAM) można podzielić na dwa odrębne obszary, a mianowicie - przestrzeń jądra i przestrzeń użytkownika”. jest źle.

& odnośnie kwestii "przestrzeń jądra a przestrzeń użytkownika"

Kiedy proces jest tworzony, a jego pamięć wirtualna jest podzielona na przestrzeń użytkownika i przestrzeń jądra, gdzie obszar przestrzeni użytkownika zawiera dane, kod, stos, stertę procesu, a przestrzeń jądra zawiera takie rzeczy, jak tablica stron procesu , struktury danych jądra i kod jądra itp. Aby uruchomić kod przestrzeni jądra, sterowanie musi przejść do trybu jądra (używając przerwania programowego 0x80 dla wywołań systemowych), a stos jądra jest zasadniczo współdzielony między wszystkimi procesami aktualnie wykonywanymi w przestrzeni jądra.

Varun Sharma
źródło
1
Wspólny proces ma własną przestrzeń jądra i przestrzeń użytkownika?
Victor Choy,
@VictorChoy, proces jest wykonywany w dwóch trybach: użytkownika i jądra. Pamięć, którą widzi proces, jest dla niego unikalna. Ale dla każdego procesu działającego w trybie jądra (wykonującego kod jądra) jest tylko jedna spacja - przestrzeń jądra.
dshil
Zauważ też, że kiedy tworzony jest proces, jego pamięć wirtualna jest podzielona na 2 części (użytkownika i jądro), gdzie część adresów wirtualnych jest zarezerwowana dla trybu użytkownika, a druga dla trybu jądra.
dshil
19

Pierścienie procesora są najbardziej wyraźnym rozróżnieniem

W trybie chronionym x86 procesor jest zawsze w jednym z 4 pierścieni. Jądro Linuksa używa tylko 0 i 3:

  • 0 dla jądra
  • 3 dla użytkowników

Jest to najtrudniejsza i najszybsza definicja jądra i przestrzeni użytkownika.

Dlaczego Linux nie używa pierścieni 1 i 2: Pierścienie uprawnień procesora: Dlaczego pierścienie 1 i 2 nie są używane?

Jak jest określany obecny pierścień?

Aktualny dzwonek jest wybierany przez kombinację:

  • globalna tablica deskryptorów: tablica wpisów GDT w pamięci, a każdy wpis ma pole, Privlktóre koduje pierścień.

    Instrukcja LGDT ustawia adres na bieżącą tablicę deskryptorów.

    Zobacz także: http://wiki.osdev.org/Global_Descriptor_Table

  • rejestry segmentu CS, DS itp., które wskazują indeks wpisu w GDT.

    Na przykład CS = 0oznacza, że ​​pierwszy wpis GDT jest obecnie aktywny dla kodu wykonawczego.

Co może zrobić każdy pierścionek?

Układ procesora jest fizycznie zbudowany tak, że:

  • ring 0 może zrobić wszystko

  • pierścień 3 nie może uruchomić kilku instrukcji i zapisać do kilku rejestrów, w szczególności:

    • nie może zmienić własnego pierścienia! W przeciwnym razie może ustawić się na dzwonek 0, a pierścienie byłyby bezużyteczne.

      Innymi słowy, nie może modyfikować deskryptora bieżącego segmentu , który określa bieżący pierścień.

    • nie można modyfikować tabel stron: Jak działa stronicowanie x86?

      Innymi słowy, nie może modyfikować rejestru CR3, a samo stronicowanie zapobiega modyfikowaniu tabel stron.

      Dzięki temu jeden proces nie widzi pamięci innych procesów ze względów bezpieczeństwa / łatwości programowania.

    • nie można zarejestrować programów obsługi przerwań. Są one konfigurowane przez zapisywanie w lokalizacjach pamięci, czemu zapobiega również stronicowanie.

      Programy obsługi działają w pierścieniu 0 i złamałyby model zabezpieczeń.

      Innymi słowy, nie może używać instrukcji LGDT i LIDT.

    • nie mogą wykonywać instrukcji IO, takich jak ini out, a zatem mają arbitralny dostęp do sprzętu.

      W przeciwnym razie, na przykład, uprawnienia do plików byłyby bezużyteczne, gdyby jakikolwiek program mógł bezpośrednio czytać z dysku.

      Dokładniej dzięki Michaelowi Petchowi : w rzeczywistości system operacyjny może zezwolić na instrukcje IO na pierścieniu 3, jest to w rzeczywistości kontrolowane przez segment stanu zadania .

      Nie jest możliwe, aby pierścień 3 udzielił sobie na to pozwolenia, jeśli w ogóle go nie miał.

      Linux zawsze tego zabrania. Zobacz też: Dlaczego Linux nie używa sprzętowego przełączania kontekstu za pośrednictwem TSS?

W jaki sposób programy i systemy operacyjne przechodzą między pierścieniami?

  • kiedy procesor jest włączony, zaczyna uruchamiać program początkowy w pierścieniu 0 (no cóż, ale jest to dobre przybliżenie). Możesz myśleć, że ten program początkowy jest jądrem (ale zwykle jest to program ładujący, który następnie wywołuje jądro nadal w pierścieniu 0 ).

  • kiedy proces użytkownika chce, aby jądro zrobiło coś dla niego, na przykład zapis do pliku, używa instrukcji, która generuje przerwanie, takie jak int 0x80lub,syscall aby zasygnalizować jądro. x86-64 Linux syscall hello world przykład:

    .data
    hello_world:
        .ascii "hello world\n"
        hello_world_len = . - hello_world
    .text
    .global _start
    _start:
        /* write */
        mov $1, %rax
        mov $1, %rdi
        mov $hello_world, %rsi
        mov $hello_world_len, %rdx
        syscall
    
        /* exit */
        mov $60, %rax
        mov $0, %rdi
        syscall
    

    skompiluj i uruchom:

    as -o hello_world.o hello_world.S
    ld -o hello_world.out hello_world.o
    ./hello_world.out
    

    GitHub upstream .

    Kiedy tak się dzieje, CPU wywołuje procedurę obsługi wywołania zwrotnego przerwania, którą jądro zarejestrowało podczas uruchamiania. Oto konkretny przykład baremetalu, który rejestruje program obsługi i używa go .

    Ten program obsługi działa w pierścieniu 0, który decyduje, czy jądro zezwoli na to działanie, wykona akcję i zrestartuje program przestrzeni użytkownika w pierścieniu 3. x86_64

  • gdy execużywane jest wywołanie systemowe (lub gdy jądro się uruchamia/init ), jądro przygotowuje rejestry i pamięć nowego procesu użytkownika, a następnie przeskakuje do punktu wejścia i przełącza procesor na pierścień 3

  • Jeśli program próbuje zrobić coś niegrzecznego, jak zapis do zabronionego rejestru lub adresu pamięci (z powodu stronicowania), procesor wywołuje również program obsługi wywołań zwrotnych jądra w pierścieniu 0.

    Ale ponieważ obszar użytkownika był niegrzeczny, jądro może tym razem zabić proces lub dać mu ostrzeżenie za pomocą sygnału.

  • Kiedy jądro uruchamia się, ustawia zegar sprzętowy z pewną stałą częstotliwością, która okresowo generuje przerwania.

    Ten zegar sprzętowy generuje przerwania, które uruchamiają pierścień 0 i pozwalają mu zaplanować, które procesy użytkownika mają się wybudzić.

    W ten sposób planowanie może się odbywać nawet wtedy, gdy procesy nie wykonują żadnych wywołań systemowych.

Jaki jest sens posiadania wielu dzwonków?

Istnieją dwie główne zalety oddzielenia jądra od obszaru użytkownika:

  • tworzenie programów jest łatwiejsze, ponieważ masz większą pewność, że jeden nie będzie kolidował z drugim. Np. Jeden proces w przestrzeni użytkownika nie musi martwić się o nadpisanie pamięci innego programu z powodu stronicowania ani o wprowadzenie sprzętu w stan nieprawidłowy dla innego procesu.
  • jest bezpieczniejszy. Na przykład uprawnienia do plików i separacja pamięci mogą uniemożliwić aplikacji hakerskiej odczyt danych bankowych. To oczywiście zakłada, że ​​ufasz jądru.

Jak się tym bawić?

Stworzyłem konfigurację gołego metalu, która powinna być dobrym sposobem na bezpośrednie manipulowanie pierścieniami: https://github.com/cirosantilli/x86-bare-metal-examples

Niestety nie miałem cierpliwości, aby stworzyć przykład przestrzeni użytkownika, ale posunąłem się do konfiguracji stronicowania, więc przestrzeń użytkownika powinna być wykonalna. Bardzo chciałbym zobaczyć prośbę o wycofanie.

Alternatywnie, moduły jądra Linuksa działają w pierścieniu 0, więc możesz ich użyć do wypróbowania uprzywilejowanych operacji, np. Odczytu rejestrów kontrolnych: Jak uzyskać dostęp do rejestrów kontrolnych cr0, cr2, cr3 z programu? Uzyskanie błędu segmentacji

Oto wygodna konfiguracja QEMU + Buildroot, aby wypróbować ją bez zabijania hosta.

Wadą modułów jądra jest to, że inne kthreads działają i mogą przeszkadzać w twoich eksperymentach. Ale teoretycznie możesz przejąć wszystkie programy obsługi przerwań swoim modułem jądra i posiadać system, to byłby właściwie interesujący projekt.

Pierścienie ujemne

Chociaż w podręczniku Intela nie ma odniesień do pierścieni ujemnych, w rzeczywistości istnieją tryby procesora, które mają większe możliwości niż sam pierścień 0, więc dobrze pasują do nazwy „pierścień ujemny”.

Jednym z przykładów jest tryb hiperwizora używany w wirtualizacji.

Aby uzyskać więcej informacji, patrz:

RAMIĘ

W ARM pierścienie nazywane są zamiast tego poziomami wyjątków, ale główne pomysły pozostają takie same.

Istnieją 4 poziomy wyjątków w ARMv8, powszechnie używane jako:

  • EL0: obszar użytkownika

  • EL1: jądro („nadzorca” w terminologii ARM).

    Wprowadzono z svcinstrukcją (wywołanie SuperVisor), wcześniej znaną jako swi przed ujednoliconym asemblacją , która jest instrukcją używaną do wykonywania wywołań systemu Linux. Witaj, świecie, przykład ARMv8:

    przywitania

    .text
    .global _start
    _start:
        /* write */
        mov x0, 1
        ldr x1, =msg
        ldr x2, =len
        mov x8, 64
        svc 0
    
        /* exit */
        mov x0, 0
        mov x8, 93
        svc 0
    msg:
        .ascii "hello syscall v8\n"
    len = . - msg
    

    GitHub upstream .

    Przetestuj z QEMU na Ubuntu 16.04:

    sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
    arm-linux-gnueabihf-as -o hello.o hello.S
    arm-linux-gnueabihf-ld -o hello hello.o
    qemu-arm hello
    

    Oto konkretny przykład baremetalu, który rejestruje program obsługi SVC i wywołuje SVC .

  • EL2: hiperwizory , na przykład Xen .

    Wprowadzono z hvcinstrukcją (połączenie HyperVisor).

    Hiperwizor jest dla systemu operacyjnego, czym system operacyjny dla obszaru użytkownika.

    Na przykład Xen pozwala na jednoczesne uruchamianie wielu systemów operacyjnych, takich jak Linux lub Windows w tym samym systemie, i izoluje systemy operacyjne od siebie w celu zapewnienia bezpieczeństwa i łatwości debugowania, tak jak Linux robi to w przypadku programów w przestrzeni użytkownika.

    Hiperwizory są kluczową częścią dzisiejszej infrastruktury chmurowej: pozwalają wielu serwerom działać na jednym sprzęcie, utrzymując zużycie sprzętu na poziomie bliskim 100% i oszczędzając dużo pieniędzy.

    Na przykład AWS używał Xen do 2017 roku, kiedy jego przejście na KVM pojawiło się w wiadomościach .

  • EL3: kolejny poziom. Przykład TODO.

    Wprowadzono z smcinstrukcją (połączenie w trybie bezpiecznym)

ARMv8 Architektura Model referencyjny DDI 0487C.a - Rozdział D1 - na poziomie systemu AArch64 programisty Model - Rysunek D1-1 ilustruje to pięknie:

wprowadź opis obrazu tutaj

Sytuacja ARM zmieniła się nieco wraz z pojawieniem się rozszerzeń hosta wirtualizacji ARMv8.1 (VHE) . To rozszerzenie umożliwia wydajne działanie jądra w EL2:

wprowadź opis obrazu tutaj

VHE zostało stworzone, ponieważ rozwiązania wirtualizacji w jądrze Linuksa, takie jak KVM, zyskały przewagę nad Xen (patrz np. Przejście AWS na KVM wspomniane powyżej), ponieważ większość klientów potrzebuje tylko maszyn wirtualnych z systemem Linux i, jak możesz sobie wyobrazić, wszystko w jednym projekt KVM jest prostszy i potencjalnie bardziej wydajny niż Xen. Więc teraz jądro Linuksa-hosta działa w takich przypadkach jako hiperwizor.

Zwróć uwagę, że ARM, być może z perspektywy czasu, ma lepszą konwencję nazewnictwa poziomów uprawnień niż x86, bez potrzeby stosowania poziomów ujemnych: 0 oznacza niższy, a 3 najwyższy. Wyższe poziomy są zwykle tworzone częściej niż niższe.

Bieżący EL można zapytać za pomocą MRSinstrukcji: jaki jest bieżący tryb wykonywania / poziom wyjątku itp.?

ARM nie wymaga obecności wszystkich poziomów wyjątków, aby umożliwić implementacje, które nie wymagają funkcji oszczędzania obszaru chipa. ARMv8 „Poziomy wyjątków” mówi:

Implementacja może nie obejmować wszystkich poziomów wyjątków. Wszystkie implementacje muszą zawierać EL0 i EL1. EL2 i EL3 są opcjonalne.

Na przykład QEMU domyślnie ustawia się na EL1, ale EL2 i EL3 można włączyć za pomocą opcji wiersza poleceń: qemu-system-aarch64 wpisuje el1 podczas emulacji zasilania a53

Fragmenty kodu przetestowane na Ubuntu 18.10.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
źródło
11

Przestrzeń jądra i przestrzeń użytkownika to oddzielenie uprzywilejowanych funkcji systemu operacyjnego i zastrzeżonych aplikacji użytkownika. Oddzielenie jest konieczne, aby uniemożliwić aplikacjom użytkownika przeszukiwanie komputera. Byłoby źle, gdyby jakikolwiek stary program użytkownika mógł zacząć zapisywać losowe dane na dysku twardym lub czytać pamięć z przestrzeni pamięci innego programu użytkownika.

Programy w przestrzeni użytkownika nie mają bezpośredniego dostępu do zasobów systemowych, więc dostęp jest obsługiwany w imieniu programu przez jądro systemu operacyjnego. Programy przestrzeni użytkownika zazwyczaj wysyłają takie żądania do systemu operacyjnego za pośrednictwem wywołań systemowych.

Wątki jądra, procesy, stos nie oznaczają tego samego. Są analogicznymi konstrukcjami dla przestrzeni jądra, jak ich odpowiedniki w przestrzeni użytkownika.

Dave Rager
źródło
8

Każdy proces ma własne 4 GB pamięci wirtualnej, która jest mapowana na pamięć fizyczną za pomocą tabel stron. Pamięć wirtualna jest w większości podzielona na dwie części: 3 GB na potrzeby procesu i 1 GB na potrzeby jądra. Większość tworzonych zmiennych znajduje się w pierwszej części przestrzeni adresowej. Ta część nazywa się przestrzenią użytkownika. Ostatnia część to miejsce, w którym znajduje się jądro i jest ono wspólne dla wszystkich procesów. Nazywa się to przestrzenią jądra i większość tej przestrzeni jest odwzorowywana na początkowe lokalizacje pamięci fizycznej, w których obraz jądra jest ładowany podczas rozruchu.

pflz
źródło
1
twoja odpowiedź dotyczy systemu Windows; powinieneś to wyjaśnić.
Matthew
1
Mówisz, że na każdy proces z 4 GB pamięci wirtualnej 1 GB to przestrzeń jądra, która jest taka sama dla każdego procesu i po prostu przechowuje mapowanie. Nie rozumiem, dlaczego !!, dlaczego 1 GB jest wymagane tylko do mapowania do lokalizacji początkowej?
VISHAL DAGA
5

Maksymalny rozmiar przestrzeni adresowej zależy od długości rejestru adresowego w CPU.

W systemach z 32-bitowymi rejestrami adresowymi maksymalny rozmiar przestrzeni adresowej wynosi 2 32 bajty lub 4 GiB. Podobnie w systemach 64-bitowych można zaadresować 2 64 bajty.

Taka przestrzeń adresowa nazywana jest pamięcią wirtualną lub wirtualną przestrzenią adresową . W rzeczywistości nie jest to związane z fizycznym rozmiarem pamięci RAM.

Na platformach Linux wirtualna przestrzeń adresowa jest podzielona na przestrzeń jądra i przestrzeń użytkownika.

Stała specyficzna dla architektury zwana limitem rozmiaru zadania lub TASK_SIZEoznacza miejsce, w którym następuje podział:

  • zakres adresów od 0 do TASK_SIZE-1 jest przydzielany do przestrzeni użytkownika;

  • reszta z TASK_SIZEmaksymalnie 2 32 -1 (lub 2 64 -1) jest przydzielana do przestrzeni jądra.

Na przykład w konkretnym systemie 32-bitowym 3 GiB może być zajęte na przestrzeń użytkownika i 1 GiB na przestrzeń jądra.

Każda aplikacja / program w uniksopodobnym systemie operacyjnym jest procesem; każdy z nich ma unikalny identyfikator zwany identyfikatorem procesu (lub po prostu identyfikatorem procesu , tj. PID). Linux zapewnia dwa mechanizmy tworzenia procesu: 1. fork()wywołanie systemowe lub 2. exec()wywołanie.

Wątek jądra to lekki proces, a także program w trakcie wykonywania. Pojedynczy proces może składać się z kilku wątków udostępniających te same dane i zasoby, ale przebiegających różnymi ścieżkami przez kod programu. Linux udostępnia clone()wywołanie systemowe do generowania wątków.

Przykładowe zastosowania wątków jądra to: synchronizacja danych w pamięci RAM, pomoc harmonogramowi w dystrybucji procesów między procesorami itp.

RajKumar Rampelli
źródło
4

W skrócie: jądro działa w przestrzeni jądra, przestrzeń jądra ma pełny dostęp do całej pamięci i zasobów, można powiedzieć, że pamięć jest podzielona na dwie części, część dla jądra i część dla własnego procesu użytkownika, (przestrzeń użytkownika) uruchamia normalne programy, użytkownik space nie może uzyskać bezpośredniego dostępu do przestrzeni jądra, więc żąda od jądra użycia zasobów. przez syscall (predefiniowane wywołanie systemowe w glibc)

jest stwierdzenie, które upraszcza różne „ Przestrzeń użytkownika to tylko testowe obciążenie jądra ” ...

Dla jasności: architektura procesora pozwala procesorowi działać w dwóch trybach, trybie jądra i trybie użytkownika , instrukcja sprzętowa umożliwia przełączanie z jednego trybu do drugiego.

pamięć może być oznaczona jako część przestrzeni użytkownika lub jądra.

Kiedy procesor działa w trybie użytkownika, procesor może uzyskać dostęp tylko do pamięci znajdującej się w przestrzeni użytkownika, podczas gdy procesor próbuje uzyskać dostęp do pamięci w przestrzeni jądra, wynikiem jest „wyjątek sprzętowy”, gdy procesor działa w trybie jądra, procesor ma bezpośredni dostęp do przestrzeni jądra i przestrzeni użytkownika ...

Yassine Abdul-Rahman
źródło
2

Przestrzeń jądra oznacza, że ​​przestrzeń pamięci może zostać dotknięta tylko przez jądro. W 32-bitowym Linuksie jest to 1G (od 0xC0000000 do 0xffffffff jako adres pamięci wirtualnej) Każdy proces tworzony przez jądro jest również wątkiem jądra, więc dla jednego procesu są dwa stosy: jeden stos w przestrzeni użytkownika dla tego procesu i drugi w jądrze miejsce na wątek jądra.

stos jądra zajmował 2 strony (8k w 32-bitowym Linuksie), zawiera task_struct (około 1k) i prawdziwy stos (około 7k). Ta ostatnia jest używana do przechowywania niektórych zmiennych automatycznych lub parametrów wywołań funkcji lub adresu funkcji w funkcjach jądra. Oto kod (Processor.h (linux \ include \ asm-i386)):

#define THREAD_SIZE (2*PAGE_SIZE)
#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
#define free_task_struct(p) free_pages((unsigned long) (p), 1)

__get_free_pages (GFP_KERNEL, 1)) oznacza alokację pamięci jako 2 ^ 1 = 2 strony.

Ale stos procesu to inna sprawa, jego adres jest poniżej 0xC0000000 (32-bitowy linux), jego rozmiar może być znacznie większy, używany do wywołań funkcji przestrzeni użytkownika.

Więc tutaj pojawia się pytanie do wywołania systemowego, działa w przestrzeni jądra, ale został wywołany przez proces w przestrzeni użytkownika, jak to działa? Czy linux umieści swoje parametry i adres funkcji w stosie jądra lub stosie procesów? Rozwiązanie Linuksa: wszystkie wywołania systemowe są wyzwalane przez przerwanie oprogramowania INT 0x80. Zdefiniowano we wpisie S (linux \ arch \ i386 \ kernel), oto kilka linii, na przykład:

ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall)   /* 0  -  old "setup()" system call*/
.long SYMBOL_NAME(sys_exit)
.long SYMBOL_NAME(sys_fork)
.long SYMBOL_NAME(sys_read)
.long SYMBOL_NAME(sys_write)
.long SYMBOL_NAME(sys_open)     /* 5 */
.long SYMBOL_NAME(sys_close)
user991800
źródło
Ostatnie pytanie jest bardzo dobre. Ale tylko przerwa w oprogramowaniu INT 0x80 , a potem? To nie jest dla mnie dobre wytłumaczenie. Czy mógłbyś szczegółowo wyjaśnić, jak działa rozwiązanie na zadane przez Ciebie pytanie?
Victor Choy,
2

Przez Sunil Yadav, na Quora:

Jądro Linuksa odnosi się do wszystkiego, co działa w trybie jądra i składa się z kilku odrębnych warstw. W najniższej warstwie jądro współdziała ze sprzętem za pośrednictwem warstwy HAL. Na średnim poziomie jądro UNIX jest podzielone na 4 odrębne obszary. Pierwszy z czterech obszarów dotyczy urządzeń znakowych, surowego i gotowanego TTY oraz obsługi terminala. Drugi obszar obsługuje sterowniki urządzeń sieciowych, protokoły routingu i gniazda. Trzeci obszar obejmuje sterowniki urządzeń dyskowych, pamięci podręczne stron i buforów, system plików, pamięć wirtualną, nazewnictwo i mapowanie plików. Czwarty i ostatni obszar zajmuje się wysyłaniem, planowaniem, tworzeniem i kończeniem procesów, a także obsługą sygnałów. Przede wszystkim mamy górną warstwę jądra, która zawiera wywołania systemowe, przerwania i pułapki. Ten poziom służy jako interfejs dla każdej z funkcji niższego poziomu. Programista używa różnych wywołań systemowych i przerwań do interakcji z funkcjami systemu operacyjnego.

Vijay Ram
źródło
2

IN krótka przestrzeń jądra to część pamięci, w której działa jądro systemu Linux (górne 1 GB przestrzeni wirtualnej w przypadku systemu Linux), a przestrzeń użytkownika to część pamięci, w której działa aplikacja użytkownika (dolne 3 GB pamięci wirtualnej w przypadku systemu Linux. chcesz dowiedzieć się więcej, zobacz link podany poniżej :)

http://learnlinuxconcepts.blogspot.in/2014/02/kernel-space-and-user-space.html

JIN007
źródło
1

Próbuję podać bardzo uproszczone wyjaśnienie

Pamięć wirtualna jest podzielona na przestrzeń jądra i przestrzeń użytkownika. Przestrzeń jądra to obszar pamięci wirtualnej, w którym będą działać procesy jądra, a przestrzeń użytkownika to obszar pamięci wirtualnej, w którym będą działać procesy użytkownika.

Podział ten jest wymagany do ochrony dostępu do pamięci.

Za każdym razem, gdy bootloader uruchamia jądro po załadowaniu go do lokalizacji w pamięci RAM (zwykle na kontrolerze opartym na ARM), musi się upewnić, że kontroler jest w trybie nadzorcy z wyłączonymi FIQ i IRQ.

Nanomózgi
źródło
1

Przestrzeń jądra i przestrzeń użytkownika to przestrzenie logiczne.

Większość nowoczesnych procesorów jest zaprojektowana do pracy w innym trybie uprzywilejowanym. Maszyny x86 mogą działać w 4 różnych trybach uprzywilejowanych. wprowadź opis obrazu tutaj

A konkretna instrukcja maszynowa może być wykonana w / powyżej określonego trybu uprzywilejowanego.

Dzięki temu projektowi zapewniasz ochronę systemu lub środowisko wykonawcze.

Jądro to fragment kodu, który zarządza sprzętem i zapewnia abstrakcję systemu. Dlatego musi mieć dostęp do wszystkich instrukcji maszyny. Jest to najbardziej zaufany program. Więc powinienem zostać stracony z najwyższym przywilejem. I poziom Pierścień 0 jest najbardziej tryb uprzywilejowany. Więc poziom pierścienia 0 jest również nazywany trybem jądra .

Aplikacje użytkownika to oprogramowanie pochodzące od dowolnego zewnętrznego dostawcy i nie można im całkowicie ufać. Ktoś ze złymi zamiarami może napisać kod powodujący awarię systemu, gdyby miał pełny dostęp do wszystkich instrukcji maszynowych. Dlatego aplikacja powinna mieć dostęp do ograniczonego zestawu instrukcji. I poziom dzwonka 3 to najmniej uprzywilejowany tryb. Więc wszystkie aplikacje działają w tym trybie. Stąd ten poziom pierścienia 3 jest również nazywany trybem użytkownika .

Uwaga: Nie otrzymuję poziomów pierścienia 1 i 2. Są to w zasadzie tryby z uprawnieniami pośrednimi. Może więc kod sterownika urządzenia jest wykonywany z tym uprawnieniem. AFAIK, linux używa tylko Ring Level 0 i 3 odpowiednio do wykonywania kodu jądra i aplikacji użytkownika.

Zatem każda operacja wykonywana w trybie jądra może być traktowana jako przestrzeń jądra. Każda operacja wykonywana w trybie użytkownika może być traktowana jako przestrzeń użytkownika.

Darshan L.
źródło
0

Prawidłowa odpowiedź brzmi: Nie ma czegoś takiego jak przestrzeń jądra i przestrzeń użytkownika. Zestaw instrukcji procesora ma specjalne uprawnienia do ustawiania destrukcyjnych elementów, takich jak katalog główny mapy tabeli stron, dostęp do pamięci urządzenia itp.

Kod jądra ma najwyższe uprawnienia, a kod użytkownika najniższe. Zapobiega to awarii systemu przez kod użytkownika, modyfikowaniem innych programów itp.

Ogólnie kod jądra jest przechowywany pod inną mapą pamięci niż kod użytkownika (tak jak przestrzenie użytkownika są przechowywane w innych mapach pamięci niż inne). Stąd pochodzą terminy „przestrzeń jądra” i „przestrzeń użytkownika”. Ale to nie jest twarda i szybka zasada. Na przykład, ponieważ x86 pośrednio wymaga, aby jego programy obsługi przerwań / pułapek były mapowane przez cały czas, część (lub wszystkie niektóre systemy operacyjne) jądra muszą być odwzorowane w przestrzeni użytkownika. Ponownie, nie oznacza to, że taki kod ma uprawnienia użytkownika.

Dlaczego konieczne jest dzielenie jądra / użytkownika? Niektórzy projektanci nie zgadzają się, że jest to w rzeczywistości konieczne. Architektura mikrojądra opiera się na założeniu, że najbardziej uprzywilejowane sekcje kodu powinny być tak małe, jak to tylko możliwe, a wszystkie istotne operacje wykonywane są w kodzie uprzywilejowanym użytkownika. Trzeba by przestudiować, dlaczego jest to dobry pomysł, nie jest to prosta koncepcja (i słynie zarówno z zalet, jak i wad).

Scott Franco
źródło
0

Pamięć podzielona jest na dwa odrębne obszary:

  • Przestrzeń użytkownika, czyli zbiór lokalizacji, w których działają normalne procesy użytkownika (tj. Wszystko inne niż jądro). Rola jądra polega na zarządzaniu aplikacjami działającymi w tej przestrzeni, tak aby nie mieszały się ze sobą oraz z maszyną.
  • Przestrzeń jądra, która jest lokalizacją, w której przechowywany jest kod jądra i jest wykonywana w ramach.

Procesy działające w przestrzeni użytkownika mają dostęp tylko do ograniczonej części pamięci, podczas gdy jądro ma dostęp do całej pamięci. Procesy działające w przestrzeni użytkownika również nie mają dostępu do przestrzeni jądra. Procesy przestrzeni użytkownika mogą uzyskać dostęp tylko do niewielkiej części jądra za pośrednictwem interfejsu udostępnionego przez jądro - wywołania systemowe.Jeśli proces wykonuje wywołanie systemowe, do jądra wysyłane jest przerwanie programowe, które następnie wysyła odpowiednią obsługę przerwań i kontynuuje jego praca po zakończeniu obsługi.

Gopika BG
źródło
-7

W Linuksie są dwie spacje, pierwsza to przestrzeń użytkownika, a druga to przestrzeń jądra. przestrzeń użytkownika składa się tylko z aplikacji użytkownika, które chcesz uruchomić. jako usługa jądra istnieje zarządzanie procesami, zarządzanie plikami, obsługa sygnałów, zarządzanie pamięcią, zarządzanie wątkami i jest tam obecnych wiele usług. Jeśli uruchamiasz aplikację z przestrzeni użytkownika, ta aplikacja współdziała tylko z usługą jądra. i ta usługa współdziała ze sterownikiem urządzenia, który jest obecny między sprzętem a jądrem. Główną zaletą oddzielenia przestrzeni jądra i przestrzeni użytkownika jest to, że możemy zapewnić ochronę przez wirus.bcaz wszystkich aplikacji użytkownika obecnych w przestrzeni użytkownika, a usługa jest obecna w przestrzeni jądra. dlatego Linux nie wpływa na wirusa.

praveen kumar
źródło
5
Pomijając fakt, że jest to „jądro”, a nie „jądro”, twoja odpowiedź nie jest całkowicie poprawna. Współczesne wirusy (i mam na myśli wszystko po Windows 98) w ogóle nie wchodzą w interakcje z „usługą jądra”, wszystko odbywa się w przestrzeni użytkownika. Fakt, że Linux nie ma zbyt wielu wirusów (są oczywiście wirusy dla Linuksa) jest taki, że ma całkiem niezłe zarządzanie uprawnieniami i - co najważniejsze - większość użytkowników Linuksa to nie tacy: „omaigosh JustinBieber.NewSong.exe! MUSZĘ to usłyszeć użytkownicy NAO !!! 1111 ", którzy klikają i instalują wszystko bez żadnej wskazówki.
alexclooze
3
Ponadto Linux nie jest tak często używany jak Windows - pisanie dla niego wirusów nie spowodowałoby takich szkód, jakie chcą osiągnąć autorzy wirusów. Aplikacje przestrzeni użytkownika nie komunikują się z usługą jądra, wywołują specjalne funkcje dostarczane przez jądro o nazwie syscalls.
alexclooze