Do przełączania procesów służą instrukcje JMP, CALL, RET oraz IRET (czyli standardowe
instrukcje wykonujące jakiegoś rodzaju skoki – by zmienić wykonywany proces trzeba zmienić licznik
instrukcji).
Instrukcje te muszą być wywoływane w imieniu procesu aktualnie wykonywanego, ale ponieważ
zaufanie programiście w kwestii dzielenia się czasem z innymi programami było by gargantuicznych
rozmiarów pomyłką, stosuje się mechanizmy sprzętowe, które „wymuszają” na procesie wykonanie w/w
instrukcji.
Zegar taktowany wolniej niż procesor, wyzwala (regularnie lub nie, zależnie od ustawień procesora
oraz systemu operacyjnego) sprzętowe przerwanie, które (mimo wykonywania jakiegoś procesu) musi zostać
obsłużone. Do jego obsługi wykorzystywany jest kod systemu operacyjnego odpowiedzialny za
przekazywanie czasu procesora do poszczególnych procesów. Zapamiętuje on dotychczasowy kontekst
(licznik instrukcji, stan procesora itp.), ustala któremu procesowi przyznać czas na obliczenia, po czym
przywraca zapisany wcześniej kontekst wybranego procesu i wykonuje instrukcję kategorii RET, po której
zaczyna być wykonywany kod rzeczywistego procesu.
Przerwanie sterujące zmianą procesu wykonywanego nie zawsze pochodzi od sprzętowego zegara,
niekiedy np. przerwanie wysłane przez dysk gdy ów będzie gotowy do odczytu danych, powoduje
przełączenie na proces, który na te dane oczekiwał.
Błąd podwójny to przerwanie, które nastąpi podczas sprzętowej obsługi innego przerwania.
Przykładem może być np. sytuacja wyjątkowa klasy przepełnienie stosu, podczas wykonywania sprzętowych
operacji obsługi innego przerwania. W wielu przypadkach błąd podwójny jest niemożliwy do opanowania
przez system i powoduje jego nieprawidłową pracę (np. BSOD w windowsie).
Rejest GDT może zawierać deskryptor programu, deskryptor TSS (Task State Segment), deskryptory
lokalnej tablicy deskryptorów (LDT) oraz deskryptory bramek.
Rejestr TR zawiera trzy wartości – selektor tablicy deskryptorów segmentu stanu zadania (TSS), który jest
widoczny dla programisty, adres bazowy aktualnego zadania oraz dostępną mu wielkość stosu. Dwie ostatnie
rzeczy są niewidoczne dla programisty i są pobierane z deskryptora TSS. Zawartość rejestru TR jest
zmieniana przy zmianie aktualnie wykonywanego procesu. TR może być zmieniony przez programistę
instrukcją LTR (Load Task Register).
Adres wirtualny, który chcemy zamienić na adres liniowy, składa się z selektora oraz przesunięcia. Selektor
określa adres tabeli deskryptorów, w której zapisany jest między innymi adres bazowy. Ten adres bazowy
sumujemy z przesunięciem zawartym w adresie wirtualnym i tak otrzymujemy adres liniowy. Adres liniowy
≡ adres fizyczny.
O procesie obsługi sytuacji wyjątkowej mówimy wtedy kiedy ta sytuacja jest obsługiwana przez inny proces
do którego odwołujemy się przez bramkę zadania umieszczona w IDT. Procedura jest odesłaniem do obszaru
kodu w segmencie kodu obsługi sytuacji wyjątkowej z pomocą bramki przerwania lub pułapki również
umieszczonej w IDG.
Wektor przerwań to adres obsługi przerwania lub indeks tablicy IDT (Interrupt Descriptor Table). Są
trzy różne realizacje tego wektora – MIPS-owska, SPARC-owska i Intel-owska. W MIPS-ie wektor przerwań
to trzy adresy obsługi wyjątków, z czego jeden to RESET. W SPARC-u mamy 256 procedur obsługi
wyjątków, a wektorem przerwań jest TBR (Trap Base Address), czyli adres który wskazuje miejsce w
pamięci na jedną z tych 256 procedur. Każda procedura to 16 bajtów. W Intelu to jest po prostu adres lub
indeks (zamienne) tabeli deskryptorów przerwań (IDT), w którym znajduje się deskryptor, prowadzący do
procesu lub procedury obsługi wyjątku.
5. Jaka jest maksymalna pojemność bezpośrednio-indeksowanej kieszeni pierwszego poziomu, przy której
translacja może odbyć się wcześniej lub w tym samym momencie co indeksacja kieszeni, jeśli adres wirtualny
kodowany jest na 32 bitach, a strony mają rozmiar 8kB? Odpowiedź uzasadnić
Biała grupa:
1. Jak duża jest tablica IDT w procesorze Intel? (2ptky ??) Dlaczego właśnie taka? Jakie
typy deskryptorów sie w niej znajdują?
W intelu IDT składa się z 256 wektorów przerwań. Pierwsze 32 wektory są zarezerwowane dla
wewnętrznych wyjątków procesora. Przerwania sprzętowe mogą być przypisane do pozostałych wektorów.
IDT (Interrupts Descriptor Table - Tablica Deskryptorów Przerwań) zawiera adresy wywoływanych
przerwań. Dla każdego przerwania istnieje osobny deskryptor którego rozmiar wynosi 8 bajtów. W każdym
deskryptorze IDT istnieje odniesienie do deskryptora w GDT lub LDT opisującego segment w którym
znajduje się wykonywany kod przerwania. Rodzaje deskryptorów: bramka przerwania (Interrupt Gate),
bramka pułapki (Trap Gate), bramka zadania (Task Gate).
2. Jakimi komendami można uzyskać dostęp do urządzeń wejścia/wyjścia? Czy
przestrzeń adresowa jest zawsze rozłączna dla pamięci i urządzeń wejścia/wyjścia?
Za pomocą komend IN/OUT. Pozwalają one na dostęp do portów wejścia/wyjścia. Odczyt tych
portów i zapis do nich odbywa się za pośrednictwem rejestrów akumulatora AL i AX.
2. Jak duża może być kieszeń zbiorowo-asocjacyjna, żeby możliwa była jednoczesna translacja i
indeksowanie, jeśli strony mają rozmiar 4kB, a adres wirtualny jest kodowany na 32 bitach? (2 pkt)Odpowiedź
uzasadnić
Dwa, inaczej nie miałoby to sensu, gdyż wszystko byłoby tak samo uprzywilejowane i program użytkownika
mógłby manipulować np. rejestrem GDT.
W intelu są 4 poziomy uprzywilejowania:
Poziom 0-jądro systemu operacyjnego
Poziom 1-system operacyjny
Poziom 2-procesy zaufane (np. sterowniki)
Poziom 3-procesy aplikacyjne
4. Co znajduje się w rejestrze bazy lokalnej tablicy deskryptorów (LDTR) Kiedy ten
rejestr może ulec modyfikacji?
Adres do lokalnej tablicy deskryptorów. Zmienia się gdy przełączane są procesy (ponieważ każdy ma własną
lokalną tablicę deskryptorów). LDTR do LDT ma się jak TR do TSS (lub przynajmniej tak mi się wydaje).
5. Jak rozwiązany jest problem segmentu rozszerzającego się w dół (stosu). Dlaczego nie można go po
prostu przenieść w inne miejsce?
Wykonywany w danej chwili proces charakteryzuje się aktualnym poziomem ochrony CPL (ang. Current
Privilege Level) uzyskiwanym z pola RPL selektora segmentu w którym zawarty jest kod bieżącego procesu.
Każdy segment pamięci ma przyporządkowany poziom ochrony zapamiętany w polu DPL (ang. Descriptor
Privilege Level) deskryptora segmentu do którego odnosi się żądanie.
Procesor ocenia prawa dostępu do segmentu poprzez porównanie obecnego poziomu uprzywilejowania CPL
do poziomu uprzywilejowania jaki ma deskryptor segmentu do którego przyznany ma być dostęp.
Przyznawany jest dostęp do danych o tym samym lub niższym poziomie ochrony (mniej ważnych).
Dopuszczane jest wywoływanie procedur o tym samym lub wyższym poziomie ochrony (bardziej godnych
zaufania)
Argumenty, tak jak prawie wszędzie w Intelu, są przekazywane przez stos.
7. Opisz w jaki sposób adres wirtualny jest zamieniany na liniowy?
Patrz wyżej
8. Opisz dlaczego różne stopnie uprzywilejowania mają rozdzielne stosy? Jakie są zalety
takiego rozwiązania?
W celu ochrony pamięci. Pozwala to na normalne pracę innych programów, w tym także systemu
operacyjnego, gdy np. program użytkownika spowoduje błąd. Ponadto program dostając dostęp do stosu
systemu operacyjnego mógłby próbować modyfikować jego działanie, co jest zwykle niepożądane.