Pytanie do speców od C/assemblera o kernel, stack, heap, BSS, data, text

1

Witam !

Nie wiem czy taki wątek nadaje się bardziej do algorytmów/struktur danych czy tutaj - na wszelki wypadek publikuję i tu (oraz z góry przepraszam moderatorów za powielenie - w razie czego proszę o przepięcie we właściwe miejsce.)

Próbuję zrozumieć anatomię pamięci w systemach ale wszystkie opisy jakie zawierają przykłady dla programistów (i wszystkie są w C). Ja nigdy nie byłem programistą i te przykłady nie są dla mnie do końca jasne. Wszędzie jest opis, że jak aplikacja jest ładowana do pamięci to jest tworzona struktura mapowania stron wirtualnej pamięci i fizycznej pamięci.
Odpuszczam już sobie kwestię fizyczna-->wirtualna (zdaję sobie sprawę, że jest to potrzebne by program miał jednolitą/ciągłą przestrzeń adresową).

Chciałbym się skupić na strukturze - i może jakimś prostym przykładzie jak notepad.exe czy nano :

Kernel
Stack
Heap
BSS
Data
Text.

Wiem, że do sekcji Kernel użytkownik nie powinien się odwołać w żaden sposób (ani czytać ani pisać) - ale nie wiem czy to znaczy, że tam jest załadowane całe jądro OSa ??? Czy tam są też wszystkie biblioteki systemowe etc ???? Czy to się powiela dla każdej aplikacji ładowanej do pamięci ??? Czy tam znajdują się wszystkie polecenie systemowe (np.: dir, ls, whoami, etc.)
Po co ta przestrzeń aplikacji użytkownika ???
Co z tej części jest potrzebne windowsowemu notatnikowy czy nano spod linuksa ?

Tym razem od dołu - Text.
Wiem, że tu ładowany jest kod aplikacji czyli wykonywalne instrukcje dla procesora co ma robić. Ale w przykładach jakie znalazłem były podane polecenia np.: /bin/ls. Przecież to jest część systemu więc nie rozumiem, czemu to się nie zalicza do sekcji Kernel.
Rozumiem, że z mojego przykładu tu znajdzie się notatnik czy nano - ale czy w całej okazałości czy tylko jakaś część ???

Data - segment przewidziany dla "statycznych zainicjowanych danych".
Czytałem, że tutaj znajdują się globalnie zdefiniowane wartości - czyli (jeśli dobrze zrozumiałem) tutaj znalazłyby się zdefiniowane napisy/opcje z programu notatnik np.: "Plik", "Zapisz jako", "Zamień" etc.
Czy tu też mogłyby się znajdować domyślne wartości jak np. szerokość czy wysokość okna edycji ???

BSS - "segment niezainicjalizowanych danych", które na początku nie mają wartości (wypełnione są zerami)
Z tego co zrozumiałem to to tu znajdowałaby się np. definicja zmiennej całkowitej i gdzie nie podajemy wartości (przykłady jakie znalazłem to: static int i; )
Pytanie - co tutaj z takiego notatnika czy nano mogłoby się znaleźć ????

Stack - przestrzeń dla zmiennych lokalnych z punktu widzenia funkcji.
Jest tu podawany również jakiś "return adress" ??? - ale powrót do czego ??? po co jakiś return adress ???
Np. co w takim notatniku może być "return adrese" ???
Co z takiego notatnika znajdzie się w sekcji stak / stos ????

Heap - segment z dynamiczną alokacją pamięci.
Tu znalazłem opisy, że ładowane są współdzielone biblioteki i moduły potrzebne procesowi.
Co z takiego notatnika się tutaj znajdzie ???

No i na koniec - jak użytkownik wpisuje coś do notatnika - to w której części zostają wprowadzone te dane ??? Do stack ???

Z góry wielkie dzięki za podpowiedzi
pozdrawiam
Dominik.

0

Najlepsze wytłumaczenie jakie znalazłem jest tutaj :
Jednak tłumaczenie jest na podstawie kodu C.
Będę wdzięczny jeśli ktoś byłby w stanie odnieść się do tematu bez wnikania w kod a raczej przedstawiając analogię z notatnikiem / nano.

3

Zależy od konkretnego systemu. Tak w wielkim skrócie odpowiedzi na parę twoich pytań.

@domino_1:

domino_1 napisał(a):

Wiem, że do sekcji Kernel użytkownik nie powinien się odwołać w żaden sposób (ani czytać ani pisać) - ale nie wiem czy to znaczy, że tam jest załadowane całe jądro OSa ??? Czy tam są też wszystkie biblioteki systemowe etc ???? Czy to się powiela dla każdej aplikacji ładowanej do pamięci ??? Czy tam znajdują się wszystkie polecenie systemowe (np.: dir, ls, whoami, etc.)
Po co ta przestrzeń aplikacji użytkownika ???
Co z tej części jest potrzebne windowsowemu notatnikowy czy nano spod linuksa ?

  • W Linuxch jądro systemu jest zmapowane do każdego procesu, ale niedostępne z poziomu procesu użytkownika.
  • Biblioteki systemowe nie są ładowane do jadra. Każda aplikacja ładuje je sama. Fizycznie biblioteka współdzielona będzie załadowana jeden raz, ale każdy proces, który z niej korzysta, będzie miał ją zamapowaną do swojej przestrzeni wirtualnej osobno.
  • Przestrzeń pamięci użytkownika, to sposób ochrony jądra systemu przed procesami, którym jądro nie może ufać.
  • Polecenia systemowe to binarki żyjące na dysku. Te podstawowe polecenia mogą być spakowane do minimalnego obrazu dysku, który rozpakuje bootloader. Nie są częścią jądra systemu.

Tym razem od dołu - Text.
Wiem, że tu ładowany jest kod aplikacji czyli wykonywalne instrukcje dla procesora co ma robić. Ale w przykładach jakie znalazłem były podane polecenia np.: /bin/ls. Przecież to jest część systemu więc nie rozumiem, czemu to się nie zalicza do sekcji Kernel.

ls to normalny program wykonywalny, który żyje na dysku.

Rozumiem, że z mojego przykładu tu znajdzie się notatnik czy nano - ale czy w całej okazałości czy tylko jakaś część ???

Tutaj znajdzie się kod programu. Czy w całości, czy tylko w część, to zależy. Zazwyczaj w całości. Ale może się zdarzyć, że nieużywane strony kodu wylecą z pamięci, albo w ogóle nie zostaną fizycznie załadowane (będą jedynie zmapowane wirtualnie, dopóki program nie spróbuje się do nich dostać).

BSS - "segment niezainicjalizowanych danych", które na początku nie mają wartości (wypełnione są zerami)
Z tego co zrozumiałem to to tu znajdowałaby się np. definicja zmiennej całkowitej i gdzie nie podajemy wartości (przykłady jakie znalazłem to: static int i; )
Pytanie - co tutaj z takiego notatnika czy nano mogłoby się znaleźć ????

Definicje to są w pliku źródłowym. BSS w przypadku uruchomionego już programu to sekcja pamięci, w której loader, według tego co wygenerował kompilator, zarezerwował miejsce na dane, które domyślnie są inicjalizowane zerami.

Stack - przestrzeń dla zmiennych lokalnych z punktu widzenia funkcji.
Jest tu podawany również jakiś "return adress" ??? - ale powrót do czego ??? po co jakiś return adress ???
Np. co w takim notatniku może być "return adrese" ???
Co z takiego notatnika znajdzie się w sekcji stak / stos ????

Zazwyczaj to jest tak, że gdy jest wołana funkcja, to na stosie odkładana jest ramka (rekord aktywacji) związana z tą funkcją. Wywołanie funkcji oznacza przeskok w inną część kodu, czyli zmianę wartości wskaźnika instrukcji (program counter). W ramce stosu zapisywany jest adres powrotny, czyli miejsce na jaki powinien zostać ustawiony wskaźnik instrukcji po wyjściu z funkcji.

Heap - segment z dynamiczną alokacją pamięci.
Tu znalazłem opisy, że ładowane są współdzielone biblioteki i moduły potrzebne procesowi.
Co z takiego notatnika się tutaj znajdzie ???

Cokolwiek było potrzebne programiście. To tylko pamięć.

No i na koniec - jak użytkownik wpisuje coś do notatnika - to w której części zostają wprowadzone te dane ??? Do stack ???

Zależy jak został zaalkowany bufor.

0

@nalik: Wielkie dzięki.

0

Nalik ci ładnie odpisał, ja jeszcze dorzucę:

zdaję sobie sprawę, że jest to potrzebne by program miał jednolitą/ciągłą przestrzeń adresową

Nie stresuj Linuxiarzy, oni wszystko mmap'ują nawet Heap'a. Wątpię by zaalokowna pamięć był ciągła.

Czy to się powiela dla każdej aplikacji ładowanej do pamięci ???

Tak, ale chyba mapa na tę samą pamięć fizyczną jest dziedziczona od procesu nadrzędnego, więc nie ma zbędnego kopiowania.

Po co ta przestrzeń aplikacji użytkownika ???

Kernel w przestrzeni użytkownika jest, bo Linus tak chciał. Zapewne po to, aby wywołania systemowe były realizowane szybciej. Wtedy nie widziano w tym nic złego. Po Meltdown/Spectre widziałem sugestie, że należy z tym skończyć.

Tym razem od dołu - Text.

Oryginalnie to było jakoś tak, że Text był segmentem read-only i były tam rzeczy read-only. Ósmego dnia, kiedy to bóg stworzył programowanie, były tam stringi z tekstem wyświetlanym użytkownikom, kod zaś był read-write bo skoki warunkowe realizowało się m.in. poprzez zapisywanie docelowego adresu skoku w następnym rozkazie. Dziś, rzeczywiście, siedzi tam kod.

/bin/ls. Przecież to jest część systemu więc nie rozumiem, czemu to się nie zalicza do sekcji Kernel.

Ten system nazywa się "GNU/Linux". Polecenia systemowe i w ogóle wszystko poza jądrem pochodzi z projektu Gnu. Linus Torvalds napisał Kernela. Spakowane razem Kernel, wypociny z Gnu i jeszcze jakieś bonusy nazywa się dystrybucją. Dystrybucji jest wiele, bo wielu ludzi ma własne zdanie co do tego, co powinno być dostarczane razem z jądrem by stworzyć "idealnego Linuxa". wiki

1 użytkowników online, w tym zalogowanych: 0, gości: 1