Wykład 5 Przerwania – zagadnienia pokrewne Systemy operacyjne Wykład 5 Przerwania – zagadnienia pokrewne dr inż. Wojciech Bieniecki Instytut Nauk Ekonomicznych i Informatyki http://wbieniec.kis.p.lodz.pl/pwsz
Tryb rzeczywisty i chroniony Tryb rzeczywisty (real mode) – tryb pracy mikroprocesorów z rodziny procesorów x86, w którym procesor pracuje tak jak procesor Intel 8086. Tryb rzeczywisty nie zapewnia ochrony pamięci przed użyciem przez inny proces oraz obsługi wielozadaniowości. W trybie tym pracowały programy w systemie operacyjnym DOS. W trybie rzeczywistym dostępna jest 1-megabajtowa przestrzeń adresowa. Tryb chroniony (ang. protected mode) – od 80286. Umożliwia adresowanie pamięci w większym zakresie niż 1 MB. Wprowadza wiele nowych udogodnień wspierających wielozadaniowość, takich jak: sprzętowa ochrona pamięci (układ MMU), wsparcie w przełączaniu kontekstu procesora i wiele innych. Linux, Windows w wersji 3.0 i wyższych, systemy z rodziny BSD wykorzystują procesory serii x86 właśnie w trybie. Intel 80386 i następne posiadają 32-bitowy tryb chroniony, w którym są dostępne 4 GB pamięci wirtualnej i stronicowanie pamięci.
Tryb rzeczywisty i przerwania W trybie rzeczywistym pracy procesora adres procedury obsługi przerwania jest zapisany w tablicy wektorów przerwań. Tablica wektorów przerwań przechowuje adresy poszczególnych procedur obsługi przerwań. Przerwania identyfikowane są przez numer (wektor przerwania) i w przypadku procesorów serii x86 jest możliwych do 256 przerwań. Tablica wektorów przerwań znajduje się w pierwszych 1024 (256 4 Bajtowych adresów procedur obsługi przerwań) komórkach pamięci operacyjnej. W komputerach PC jest 16 różnych sygnałów IRQ (ang. interrupt request) – IRQ0 do IRQ15. IRQ określa się również jako zasób udostępniany przez procesor. Jest ich tylko 16, bywają problemy z przydzieleniem osobnego przerwania każdemu z urządzeń, które go potrzebuje. Może to powodować przydzielenie tego samego przerwania dwóm urządzeniom. Mówi się wtedy o konflikcie przerwań, gdyż najczęściej dwa urządzenia nie mogą współdzielić jednego.
Tryb chroniony GDT (Global Descriptor Table - Globalna Tablica Deskryptorów) Zawiera podstawowe informacje o segmentach. W trybie rzeczywistym segmenty miały maksymalny rozmiar 64KB i następowały po sobie w 16 bajtowych odstępach. W trybie chronionym można dowolnie ustalać rozmiar segmentu aż do max. 4GB. Można także decydować gdzie ma się zaczynać każdy segment. Przykładowo tablicę GDT zarezerwuje dla siebie System Operacyjny a dla każdego procesu stworzy osobną tablicę LDT z jego deskryptorami segmentów. LDT (Local Descriptor Table - Lokalna Tablica Deskryptorów) także zawiera podstawowe informacje o sektorach ale jest ona używana dla aplikacji. IDT (Interrupts Descriptor Table - Tablica Deskryptorów Przerwań) Zawiera podstawowe informacje o przerwaniach. Tabela ta mówi procesorowi gdzie ma znaleć 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 GDT lub LDT opisującego segment, w którym znajduje się wykonywany kod przerwania.
Tryb chroniony i przerwania IDT łączy każdy wektor wyjątku lub przerwania z deskryptorem bramy dla procedury lub zadania (ang. task) obsługującym dany wyjątek lub przerwanie. Deskryptory bram to deskryptory pozwalające na kontrolowany dostęp do segmentów kodu o różnych stopniach uprzywilejowania Położenie IDT jest zapisane w rejestrze tablicy deskryptorów przerwań (ang. Interrupt Descriptor Table Register, IDTR). IDT może zawierać trzy różne rodzaje deskryptorów bram: deskryptor bramy zadania (ang. Task-Gate Descriptor) - deskryptor używany przy sprzętowej wielozadaniowości, wskazuje położenie w pamięci struktury opisującej zadanie deskryptor bramy przerwania (ang. Interrupt-Gate Descriptor) - informujący procesor o kodzie któy ma wykonać po napotkaniu przerwania deskryptor bramy pułapki (ang. Trap-Gate Descriptor) - zawierający lokalizację w kodzie, które gdy zostanie zostanie osiągnięte wywoła przerwanie - pułapkę (użyteczne przy debuggowaniu)
GDTR Global Descriptor Table Register (GDTR) - 48-bitowy rejestr procesora 386 Rejestr ten służy do określania rozmiaru tablicy GDT i jej położenia w pamięci operacyjnej. Ma on rozmiar 6 bajtów. Przed inicjacja trybu chronionego należy zapisać ten rejestr odpowiednimi wartościami przy czym po jego zainicjowaniu nie można już zmieniać adresu tablicy GDT. HI 5 4 3 2 1 0 LO (Bajty) +---+---+---+---+---+---+ | ADRES | ROZM. | ROZM. - Znajduje się w dwóch "niskich" bajtach i określa rozmiar tablicy GDT. Maksymalny rozmiar tablicy GDT wynosi 65536 bajtów czyli 64KB. ADRES - Jest to fizyczny adres położenia tablicy GDT w pamięci operacyjnej.
IDTR Interrupt Descriptor Table Register (IDTR) - 48-bitowy rejestr procesora 386. Rejestr przekierowania przerwań. HI 5 4 3 2 1 0 LO (Bajty) +---+---+---+---+---+---+ | L |N/U| BASE | LIMIT | LIMIT - rozmiar tablicy deskryptorów przerwań. Maksymalny rozmiar tabeli to 65536 bajtów (64kb), ale ponieważ procesor dla zgodności wstecz obsługuje tylko 256 przerwań nie powinno się deklarować większego rozmiaru niż 256 * 8 (2KB). BASE - adres tablicy deskryptorów przerwań w pamięci. 8 bajt - długość każdego deskryptora.
Metody komunikacji SO z urządzeniami Metoda 1: Programowane wejście-wyjście (ang. Programmed Intput-Output - PIO) Drukowanie wiersza tekstu na drukarce. Odrębny bufor we-wy w pamięci jądra. użytkownika Program Jądro
PIO - algorytm Dwa rejestry we-wy: – printer_status_reg: Aktualny stan drukarki (czy może odebrać następny znak) – printer_data_reg: Bajt danych wysyłany do drukarki copy_from_user (buffer, p, count); // kopiuj dane do bufora jądra for (j = 0; j < count; j++) { // przesyłaj odrębnie każdy znak while (*printer_status_reg != READY) ; // czekaj aż drukarka stanie się wolna *printer_data_reg = p[j]; // wyślij pojedyńczy znak do drukarki } return_to_user(); // powrót do programu użytkownika Problem: bezczynne oczekiwanie procesora w pętli while Drukarka jest znacznie wolniejsza od procesora
Metody komunikacji SO z urządzeniami Wejście / wyjście sterowane przerwaniami (interrupt driven) Zakończenie transmisji każdego znaku potwierdzane jest przerwaniem. Procesor potwierdza przerwanie Transmisja zakończona kontroler zgłasza przerwanie
Metody komunikacji SO z urządzeniami Wywołanie systemowe copy_from_user (buffer, p, count); j = 0; enable_interrupts(); while (*printer_status_reg != READY) ; *printer_data_reg = p[0]; scheduler(); Wstrzymaj bieżący proces Procedura obsługi przerwania if (count == 0) { unblock_user(); } else { *printer_data_reg = p[j count--; j++; } acknowledge_interrupt(); return_from_interrupt(); Odblokuj proces
DMA Komunikacja z urządzeniami poprzez przerwania sprawdza się w przypadku wolnych urządzeń (tzw. znakowych, np. klawiatura). W przypadku urządzeń szybszych (np. dysk, tzw. urządzenie blokowe) częstotliwość zgłaszania przerwań może sparaliżować działanie SO. Rozwiązaniem jest zastosowanie dla tych urządzeń bezpośredniego dostępu do pamięci (DMA). System komputerowy jest wyposażony w sterownik zwany kontrolerem DMA.
DMA (direct memory access) Kiedy program użytkownika żąda transmisji danych z szybkiego urządzenia to SO programuje odpowiednio sterownik DMA. Obejmuje to również wyznaczenie obszaru w pamięci z którego urządzenie będzie pobierało dane lub w którym będzie je składowało oraz określenie wielkości tych danych. Urządzenie przesyła te dane blokami wielkości kilkuset lub nawet kilku tysięcy bajtów. Przesyłanie bloku danych pomiędzy urządzeniem a pamięcią odbywa się bez angażowania procesora. Przesłanie bloku poprzez DMA jest współbieżne z pracą procesora Gdy nadejdzie czas przesłania kolejnego bajtu urządzenie DMA przejmuje (na chwilę) od procesora kontrolę nad magistralą – ang. cycle stealing. Następuje transmisja bajtu pomiędzy urządzeniem i pamięcią. W tym czasie procesor ma zablokowany dostęp do magistrali. (Nie musi to oznaczać zatrzymania pracy procesora – jeżeli posiada on pamięć podręczną)
Organizacja DMA CPU DMA I/O I/O Mem CPU DMA I/O Mem DMA jest kolejnym modułem podłączonym magistrali – Transfer może wymagać dwóch cykli magistrali – Starsze systemy (Z80, IBM PC AT) CPU DMA I/O Mem DMA zintegrowane z kontrolerem urządzenia Nowsze systemy (magistrala PCI)
Operacja z wykorzystaniem DMA Procesor programuje kontroler DMA Przesłanie danych Potwier dzenie przerwanie DMA żąda zapisu do pamięci Address – gdzie przesłać dane, Count – ile przesłać, Control – rodzaj operacji (np. odczyt zapis) Kontoler DMA zajmuje się zliczaniem bajtów, podawaniem adresu i sygnałów sterujących na magistralę
Operacja DMA Kod wykonywany przez wywołanie systemowe copy_from_user (buffer, p, count); set_up_DMA_controller(); scheduler(); // wstrzymaj aktualny proces // i przekaż procesor innemu Kod wykonywany przez wywołanie systemowe acknowledge_interrupt(); unblock_user(); // odblokuj czekający proces return_from_interrupt(); Kod wykonywany przez procedurę obsługi przerwania set_up_DMA_controller() - zaprogramuj DMA (numer urządzania, adres bufora w pamięci, liczba bajtów) DMA zajmuje się zliczaniem bajtów i oczekiwaniem na gotowość urządzenia
System pułapek Jednym z zastosowań wektorowego systemu obsługi przerwań jest obsługa sytuacji wyjątkowych (np. próba dzielenia przez zero). Przerwania obsługujące tego typu zdarzenia nazywamy pułapkami (ang. trap) lub wyjątkami (exception). Mają one wysokie priorytety i są niemaskowalne. Pułapki są zwykle przerwaniami nieprecyzyjnymi: jeżeli sygnał przerwania pojawi się w trakcie wykonywania rozkazu, to rozkaz nie jest kończony. Dla porównania – przerwania związane z rozkazami wejścia wyjścia są precyzyjne – ich obsługa rozpoczyna się po zakończeniu wykonania rozkazu. Pułapki są przerwaniami synchronicznymi – pojawiają się podczas realizacji określonych fragmentów programu. Przerwania związane z urządzeniami IO są asynchroniczne.
Obsługa wielu żądań przerwania Działanie SO w dużej mierze zależy od systemu przerwań. System ten jest zorientowany zdarzeniowo. Projektując system przerwań należy uwzględnić sytuację, w której urządzenie I/O nie jest w stanie obsłużyć dużej liczby żądań. Rozwiązanie – tablica stanów urządzeń (device-status table)– umieszczona w pamięci operacyjnej komputera. Tablica ta zawiera po jednej pozycji dla każdego urządzenia w systemie. Na pozycję w takiej tablicy składa się opis aktualnego stanu urządzenia oraz kolejka zleceń operacji wejścia/wyjścia.
Tablica stanów urządzeń Jeżeli urządzenie nie wykonuje żadnej operacji wejścia/wyjścia, to odpowiadająca mu kolejka jest pusta. W przeciwnym przypadku, pierwsze zlecenie w kolejce odpowiada aktualnie wykonywanej operacji, a kolejne zlecenia odpowiadają operacjom oczekującym na wykonanie. Zlecenia w kolejce zawierają m.in. informacje o zadaniu, od którego pochodzi zlecenie, tak że w momencie wykonania zlecenia system operacyjny wie, które zadanie należy wznowić.
Rozkaz oczekiwania Co powinien zrobić SO z procesem, którego żądanie operacji wejścia-wyjścia oczekuje na realizację: Pozwolić takiemu procesowi na oczekiwanie aż ta operacja się zakończy. Marnowanie czasu procesora (możliwe – gdy nie ma więcej zadań do wykonania) Przystąpić do realizacji innych zadań. Rozkaz wait zawiesza pracę procesu aż do czasu pojawienia się przerwania. SO może sam wywołać taki rozkaz.
Problem ochrony zasobów Procesy użytkownika nie powinny mieć możliwości wykonywania pewnych rozkazów. Przykłady niedozwolonych operacji programu: Bezpośrednia komunikacja z urządzeniami wejścia-wyjścia – naruszenie ochrony we/wy Dostęp do pamięci należącej do innych procesów lub do systemu – naruszenie ochrony pamięci Zablokowanie przerwań, zmiana wektora przerwań – naruszenie ochrony systemu przerwań Nieskończona pętla – naruszenie ochrony procesora
Dualny tryb pracy procesora Procesy użytkownika nie powinny mieć możliwości wykonywania pewnych rozkazów. Aby to zapewnić twórcy sprzętu wyposażyli procesory w dwa tryby pracy: tryb jądra (nazywany też trybem monitora, systemu lub nadzorcy) i tryb użytkownika. W pierwszym trybie wykonywany jest oczywiście system operacyjny, w drugim, procesy użytkownika. Przełączenie do z trybu użytkownika do trybu monitora następuje między innymi w wyniku wystąpienia przerwania lub pułapki.
Dualny tryb pracy procesora To w jakim trybie znajduje się w chwili obecnej procesor określone jest ustawieniem odpowiedniego bitu w rejestrze stanu procesora. rozruch systemu następuje w trybie jądra procesy użytkowe są uruchamiane w trybie użytkownika każde wystąpienie pułapki lub przerwania zmienia tryb pracy na tryb monitora. przejście do programu użytkownika powoduje przejście w tryb użytkownika
Dualny tryb pracy procesora Lista rozkazów jest podzielona na dwa zbiory: rozkazów uprzywilejowanych, które mogą być wykonywane jedynie w trybie jądra i nieuprzywilejowane, które mogą być wykonywane w trybie użytkownika. Rozkazy rozróżnia ustawienie odpowiedniego bitu w słowie rozkazu, który jest porównywany z bitem trybu pracy. Jeśli program użytkownika spróbuje wykonać rozkaz uprzywilejowany, to zostanie uruchomiona odpowiednia pułapka, która zakończy jego działanie w sposób krytyczny. Rozkazy uprzywilejowane można wykorzystać także do zorganizowania interakcji użytkownika z systemem operacyjnym, tj. umożliwienie użytkownikowi kierowania zleceń wykonania zadań zarezerwowanych dla systemu operacyjnego (wywołania systemowe) System traktuje wywołanie systemowe jako przerwanie programowe. Za pośrednictwem wektora przerwań sterowanie przechodzi do odpowiedniej procedury obsługi. System przechodzi w tryb monitora monitor sprawdza poprawność parametrów, wykonuje zlecenie i przekazuje sterowanie do rozkazu następującego po wywołaniu systemowym.
Ochrona zasobów Ochrona wejścia-wyjścia niedozwolone operacje wejścia-wyjścia mogą zakłócić działanie systemu wszystkie rozkazy wejścia-wyjścia są uprzywilejowane. Użytkownik nie może używać ich bezpośrednio, lecz za pośrednictwem systemu operacyjnego Ochrona pamięci niedopuszczalne jest, aby program użytkownika dokonał zmian w wektorze przerwań lub systemowych procedurach obsługi przerwań. Potrzebna jest również wzajemna ochrona programów użytkowników taką ochronę musi zapewniać sprzęt
Ochrona pamięci Możliwe rozwiązanie: rejestr bazowy i rejestr graniczny Rejestr bazowy przechowuje najmniejszy dopuszczalny adres fizyczny pamięci Rejestr graniczny zawiera rozmiar obszaru pamięci dozwolone są tylko odwołania do obszaru pamięci pomiędzy adresem pamiętanym w rejestrze granicznym a adresem uzyskanym przez dodanie zawartości rejestru bazowego i rejestru granicznego.
Ochrona pamięci Każdy adres wygenerowany przez proces użytkownika sprawdzany jest zgodnie z poniższym schematem. Jeśli test nie powiedzie się uruchamiana jest pułapka i sterowanie wraca do systemu operacyjnego. Rozkazy modyfikujące rejestr bazowy i graniczny muszą być uprzywilejowane.
Ochrona procesora Możliwe problemy wejście programu użytkownika w nieskończoną pętlę Próby obchodzenia przez użytkownika usług systemowych prowadzące do odebrania systemowi operacyjnemu sterowania Możliwe rozwiązanie: czasomierz(timer) generujący przerwanie po ustalonym okresie (sterowanie wraca wtedy do systemu operacyjnego). Inne zastosowanie czasomierza: podział czasu
Czasomierz Licznik czasu jest najczęściej implementowany jako licznik zliczający w dół, którego stan zmienia się co takt zegara. Po wyzerowaniu licznika sterownie wraca do systemu operacyjnego. Opisany czasomierz może służyć jako układ typu watchdog, który w systemie czasu rzeczywistego pozwalałby sprawdzić, czy zadanie wykonało się w przeznaczonym dla niego czasie. W systemach z podziałem czasu ten układ wyznacza moment, w którym system operacyjny powinien przełączyć procesor na inne zadanie użytkownika. Inicjalizacji czasomierza dokonuje system operacyjny, przed oddaniem sterowania procesowi użytkownika. Rozkaz inicjalizacji jest rozkazem uprzywilejowanym.