1. SPRZĘTOWE MECHANIZMY OCHRONY PROCESÓW
OBLICZENIOWYCH
procesor
urządzenia
pamięć zewnętrzne
operacyjna
Płyta główna
Ogólny schemat logiczny komputera (pomijający organizację magistral,
pamięć podręczną itd.)
W pamięci komputera może jednocześnie przebywać wiele programów (wśród
nich system
operacyjny) oraz danych dla nich.
program 1
dane1
program 5
dane 5 Przykładowa zawartość pamięci
operacyjnej
(dane niekoniecznie muszą być
umieszczane
w pobliżu programów, które z nich
korzystają)
program 17
dane 17
Programem (wykonywalnym) nazywamy zapis ciągu rozkazów (instrukcji)
przeznaczonych do
wykonania przez procesor komputera.
Procesem (obliczeniowym) nazywamy „wykonywanie programu”, czyli ciąg
stanów, jakie kolejno
przyjmuje procesor (jego rejestry) oraz obszar danych programu w związku z
wykonywaniem przez
procesor tego programu (uwaga: kolejność wykonywanych instrukcji nie musi
być taka sama, jak
kolejność ich zapisu w programie).
Pierwotnie użytkownik komputera sprawował nad nim „nieograniczoną władzę”
- miał dostęp do
wszystkich instrukcji procesora, wszystkich lokat pamięci operacyjnej oraz
wszystkich portów.
Dawało mu to pełną swobodę poczynań, ale jednocześnie nieograniczone
możliwości szkodzenia
zarówno samemu sobie, jak i innym użytkownikom komputera.
Obecnie tak szerokie możliwości mają jedynie:
1) użytkownicy komputerów indywidualnych (którzy świadomie chcą z tych
możliwości korzystać);
2) administratorzy wielodostępnych systemów komputerowych.
Zadaniem systemu operacyjnego jest chronienie sprzętu komputerowego oraz
wykonywanych na nim
procesów obliczeniowych przed uszkodzeniem przez nieświadomych lub
złośliwych użytkowników.
Jakiego rodzaju szkody może wyrządzać błędny program ?
1) Niewłaściwa komunikacja z urządzeniem zewnętrznym może spowodować:
a) utratę części bądź całości danych przekazywanych do / z urządzenia;
b) trwałe uszkodzenie urządzenia lub jego przedwczesne zużycie.
2) Program użytkownika może się zapętlić i angażować procesor komputera aż
do wyłączenia
zasilania (restartu systemu).
3) Program użytkownika może wywołać rozkaz zatrzymania pracy procesora
(zazwyczaj jest to
rozkaz halt).
4) Program może błędnie zmodyfikować swój własny kod (zapis) lub zniszczyć
swoje dane.
5) W przypadku pracy w systemie wielozadaniowym program może również
zniszczyć programy
i dane należące do innych użytkowników (zarówno w pamięci operacyjnej, jak
i na nośnikach
zewnętrznych). W szczególności może popsuć system operacyjny.
Nawet najlepiej zaprojektowane systemy operacyjne nie są w stanie zapobiegać
takim zjawiskom,
jeśli nie umożliwiają tego odpowiednie rozwiązania sprzętowe. Ogólnie, systemy
operacyjne są
projektowane pod kątem funkcjonowania na konkretnym sprzęcie, a dokładniej,
na sprzęcie od
którego można oczekiwać pewnych konkretnych własności.
Jakie są minimalne wymogi wobec sprzętu komputerowego, aby można było
zapewnić ochronę
jemu oraz procesom obliczeniowym ?
Musi być zapewniona możliwość ciągłego śledzenia pewnych aspektów
wykonywania programów
użytkowników oraz możliwość natychmiastowej interwencji w przypadku
próby wykonania
instrukcji potencjalnie szkodliwej.
Minimum sprzętowe niezbędne w każdym przypadku to posiadanie przez
procesor bitu trybu pracy
(co najmniej jednego). Tradycyjnie był to jeden bit, którego ustawienie na 1
oznaczało tryb
użytkownika, zaś ustawienie na 0 - tryb monitora (nadzorcy systemu).
Instrukcje procesora, które są potencjalnie niebezpieczne (w sensie wyżej
wymienionych zagrożeń)
załadowane do rejestru rozkazów procesora będącego w trybie pracy
użytkownika powodują:
1) przełączenie trybu pracy na tryb nadzorcy;
2) zarzucenie wykonywania programu użytkownika i przejście do wykonywania
kodu systemu
operacyjnego.
Aby stwierdzić, czy instrukcja pobrana do wykonania jest potencjalnie
niebezpieczna, procesor musi
przeanalizować: 1) co dana instrukcja ma wykonać; 2) na czym (na jakim
miejscu w pamięci) ma być
wykonana. Musi zatem sprawdzić zarówno część kodową instrukcji, jak i jej
część adresową.
Instrukcje potencjalnie niebezpieczne ze względu na swoją część kodową (na
przykład instrukcja
zawieszenia lub zatrzymania procesora) nazywane są czasem
uprzywilejowanymi (dawniej
nazywano je nielegalnymi). Instrukcje odwołujące się do lokat w pamięci, które
nie zostały
przydzielone danemu procesowi, powodują błąd adresowania.
Opisany wyżej przeskok do wykonywania innego programu, połączony z
zapamiętaniem informacji
o aktualnym stanie procesora (w tym jego wskaźnika instrukcji) nazywany jest
przerwaniem
(interrupt)
. Mechanizm przerwania jest dużo bardziej ogólny i niekoniecznie
musi wiązać się z próbą
wykonania „niebezpiecznego” rozkazu przez program użytkownika. Możliwość
wywoływania
i obsługi przerwań wykorzystywana jest w praktycznie wszystkich procesorach,
niezależnie od
istniejących w nich zabezpieczeń.
Ogólna idea przerwań: procesor powinien móc natychmiast reagować na
zdarzenia asynchroniczne,
czyli takie, których moment pojawienia się był niemożliwy do przewidzenia (nie
wynikał w logiczny
sposób z ciągu wykonywanych instrukcji programu).
Ogólna klasyfikacja przerwań:
1) przerwania sprzętowe
(hardware interrupt)
;
2) przerwania związane z sytuacjami wyjątkowymi
(exception interrupt)
;
3) przerwania programowe
(software interrupt)
.
ad. 1) Przerwania sprzętowe mogą pochodzić od autonomicznie pracujących
układów zawiadujących
pracą urządzeń zewnętrznych (kontrolerów urządzeń), które na przykład
mogą powiadamiać
procesor o zakończeniu transmisji danych. Mogą też pochodzić od zegara
systemowego, co
umożliwia procesorowi cykliczne przeprowadzenie pewnych rutynowych
czynności (nie musi
tego wykorzystywać).
ad.2) Przerwania związane z sytuacjami wyjątkowymi pozwalają reagować nie
tylko na próby
wykonania instrukcji niebezpiecznych, ale również na próby wykonania
instrukcji uznanych
za błędne z innych powodów (na przykład próba dzielenia przez zero).
ad.3) Mechanizm przerwań objawił tak wiele zalet, że w listach instrukcji
procesorów przewidziano
instrukcję „specjalnego” wywołania przerwania przez program
użytkownika (to już trudno
nazwać „zdarzeniem asynchronicznym”), która powoduje zapamiętanie
bieżącego stanu
procesu i przeskok do podprogramu obsługi przerwania.
Typowy ciąg czynności procesora po otrzymaniu sygnału przerwania:
1) identyfikacja przyczyny przerwania;
2) stwierdzenie, czy przerwanie może być obsłużone (być może sygnał
przerwania nadszedł
w trakcie obsługiwania innego przerwania o wyższym priorytecie, wtedy
obsługiwanie
przerwań o niższym priorytecie jest czasowo zamaskowane);
3) jeśli może być obsłużone, zapamiętywana jest bieżąca zawartość rejestrów
procesora i ustawiana
jest maska sygnałów;
4) następuje przeskok do odpowiedniego miejsca w pamięci (czyli wpisanie
odpowiedniej wartości
do wskaźnika instrukcji, zależnej od wykrytej przyczyny przerwania) i
wykonanie podprogramu
obsługi przerwania;
5) na ogół (jeśli umożliwia to przyczyna przerwania) po zakończeniu
wykonywania podprogramu
obsługi przerwania następuje odtworzenie zapamiętanego stanu rejestrów
procesora i powrót do
programu, z którego nastąpił wyskok.
Jak zatem systemy operacyjne dysponujące mechanizmem przerwań radzą sobie
z wymienionymi
wcześniej rodzajami błędów w programach użytkowników ?
1) Każda próba bezpośredniego wykonania operacji na urządzeniach
zewnętrznych przez program
użytkownika będzie uznana za nielegalną - użytkownik może tylko poprosić o
taką przysługę
system operacyjny (wywołać funkcję systemową);
2) Zapętleniu zapobiega możliwość czasowego przyjmowania przerwań od
zegara systemowego
i wykorzystanie ich obsługi do zatrzymania zapętlonego procesu;
3) Instrukcja zatrzymania (oraz inne instrukcje uprzywilejowane) nie będą
wykonane z poziomu
programu użytkownika;
4) i 5) Ochrona zawartości pamięci operacyjnej musi być zapewniona sprzętowo.
Procesy mają
przydzielone oddzielne segmenty pamięci na kody programów oraz na dane.
Z każdym segmentem
związane są dwa rejestry: rejestr bazowy oraz rejestr graniczny. W
rejestrze bazowym pamiętany
jest początkowy adres w danym segmencie, a w rejestrze granicznym -
wielkość segmentu.
wzrost segment
base base
adresów
pamięci
base
+
limit limit
Część adresowa instrukcji pobranej do wykonania z programu użytkownika musi
mieścić się
w przedziale wyznaczonym przez zawartości tych dwóch rejestrów (dotyczy to
rejestrów zwią-
zanych z segmentem danych w przypadku instrukcji operujących na danych, zaś
rejestrów
związanych z segmentem kodu w przypadku instrukcji skoku). W przypadku
wykrycia przekroczenia
system zapamiętuje przyczynę i przechodzi do uprzywilejowanego trybu pracy
(przeskakuje do
odpowiedniego podprogramu obsługi przerwania).
Ochrona dostępu do plików realizowana jest przez wielozadaniowe systemy
operacyjne programowo.
Każdy plik musi mieć określonego właściciela oraz prawa dostępu. Właściciel
pliku ustanawia
prawa dostępu do niego (będzie to bardziej szczegółowo omówione przy okazji
omawiania
konkretnych systemów). Ponieważ procesy również mają swoich właścicieli, przy
każdym odwołaniu
procesu do pliku system operacyjny sprawdza najpierw, czy odwołanie to jest
legalne z punktu
widzenia obowiązujących praw.
Ochrona plików jest zatem dwojakiego rodzaju:
1) niskopoziomowa (podobnie jak dostępu do każdego innego urządzenia
zewnętrznego);
2) wysokopoziomowa (w sensie wymuszenia przestrzegania praw własności).
Oddzielnym problemem jest chronienie procesów przed skutkami awarii
sprzętu w systemach
komputerowych, od których sprawności działania bardzo dużo zależy. Tu
również możliwości
systemów operacyjnych w istotny sposób zależą od własności sprzętu
(wykrywanie czasowego
zaniku zasilania i awaryjne zapamiętywanie najważniejszych danych,
instalowanie dodatkowych
procesorów i dublowanie obliczeń na wypadek awarii jednego z nich itd.).