W wykładzie 13 jako interesujący przykład systemu operacyjnego rozważymy Windows 2000. Jest to wielozadaniowy system operacyjny z wywłaszczaniem. Przeznaczony jest głównie na mikroprocesory Intela. Zajmiemy się ciekawą architekturą tego systemu (m.in. mikrojądro), która umożliwiła osiągnięcie takich jego właściwości, jak przenośność, zabezpieczenie, zgodność ze standardem POSIX, wsparcie dla wieloprocesorowości, rozszerzalność i możliwość dostosowania do warunków panujących w rozmaitych krajach (język, format daty, czasu etc.). Nie bez znaczenia jest też zgodność z wszelkimi aplikacjami napisanymi dla MS-DOS i MS-Windows.
Możliwość rozszerzenia systemu operacyjnego o nowe elementy jest niezwykle istotna. W Windows 2000 osiągnięto ją dzięki warstwowej architekturze systemu. Podstawowe usługi systemowe są dostarczane przez tzw. egzekutora, który działa w trybie chronionym. Powyżej egzekutora działają w trybie użytkownika tzw. podsystemy środowiskowe, które emulują rozmaite systemy operacyjne. Jest więc podsystem środowiskowy dla DOS, Windows, POSIX etc. Nie ma przeszkód, żeby w ten sposób zaoferować też usługi innych systemów operacyjnych. Dodanie ich nie wymaga żadnych zmian w kodzie egzekutora.
Możliwość przeniesienia systemu operacyjnego na nową platformę sprzętową także jest niezwykle istotna, ponieważ cały czas dokonuje się postęp w dziedzinie sprzętu. Nie bez znaczenia jest także możliwość podboju nowych dotychczas niezdobytych rynków.
Windows 2000 można niewielkim kosztem przenieść na nowy sprzęt dzięki tzw. warstwie abstrakcji sprzętu (HAL -- Hardware Abstraction Level). Jest to biblioteka zawierająca wszystkie elementy zależne od konkretnego procesora. Pozostałe elementy systemu są już niezależne od sprzętu. Przeniesienie na nowy sprzęt wymaga więc jedynie napisania nowej warstwy HAL i podmiany jej. Większość kodu Windows 2000 napisano w C i C++.
Niezawodność to zdolność do radzenia sobie w sytuacjach błędu. Dotyczy to nieumyślnego błędu oraz wrogich działań zarówno ze strony użytkownika jak i zainstalowanego oprogramowania. Windows 2000 są zabezpieczone przez sprzętowe mechanizmy ochrony pamięci wirtualnej oraz programowe mechanizmy ochrony zasobów systemu. System plików Windows 2000 zwany NTFS ma mechanizmy, które automatycznie usuwają skutki wielu rodzajów usterek powstałych w wyniku awarii systemu.
System Windows 2000 jest zgodny na poziomie kodu źródłowego z programami spełniającymi standard IEEE 1003.1 (POSIX -- Portable Operating System Interface). Aplikacje napisane dla POSIX mogą być kompilowane dla Windows 2000 bez zmian w ich kodzie źródłowym. Ta możliwość wynika z warstwowej architektury systemu, w której łatwo było uwzględnić podsystem środowiskowy dla POSIX.
System Windows 2000 składa się z podsystemów, które się ze sobą komunikują za pomocą lokalnych procedur zapewniających szybkie przekazywanie komunikatów. W systemie przewidziano też wywłaszczanie wątków o niskim priorytecie, co pozwala szybko reagować na zdarzenia zewnętrzne. Możliwe jest też wieloprzetwarzanie symetryczne. Jeśli komputer ma wiele procesorów, wiele wątków może działać równolegle w tym samym czasie.
System Windows 2000 może być dostosowany do reguł i zwyczajów panujących w różnych krajach. Zrealizowano to za pomocą API wsparcia dla języków narodowych (NLS -- National Language Support). Ten interfejs zawiera różnorakie procedury do formatowania daty, czasu, waluty etc. Porównywanie napisów zaprogramowano tak, żeby działało dla różnych zbiorów znaków. Windows 2000 we wnętrzu używa kodu znaków Unicode. Te wszystkie działania mają na celu maksymalne powiększenie rynku, na którym można sprzedawać ów system.
Architektura systemu Windows 2000 jest warstwowa. W trybie chronionym działają trzy warstwy:
Jądro systemu jest podbudową dla egzekutora i podsystemów środowiskowych. Nigdy nie jest wyrzucane z pamięci operacyjnej do dyskowej pamięci podręcznej i nigdy się go nie wywłaszcza. Ma cztery zasadnicze zadania:
W Windows 2000 odróżniono proces od wątku. Proces ma przydzieloną przestrzeń adresową w pamięci wirtualnej, priorytet i przypisanie do co najmniej jednego procesora. Proces ma też co najmniej jeden wątek (może mieć ich wiele). Wątek to jednostka wykonania zarządzana przez jądro. Podlega planowaniu wykonywanemu przez ekspedytor jądra. Każdy wątek ma stan, priorytet i przypisanie do procesu. Wątek może być w jednym z sześciu stanów:
Planista używa schematu z 32 wartościami priorytetu. Priorytety podzielono na dwie klasy:
Planowanie jest wywłaszczające, ponieważ może nastąpić, gdy:
Czas rzeczywisty w Windows 2000 oznacza danie preferencyjnego dostępu do procesora, ale nie ma gwarancji, że wątek czasu rzeczywistego rozpocznie wykonanie po ustalonym czasie. Nie jest to więc rygorystyczny system czasu rzeczywistego.
Jądro zajmuje się obsługą pułapek tzn. wyjątków i przerwań sprzętowych i programowych.
Proste wyjątki mogą być obsługiwane przez procedurę obsługi pułapki. Obsługą pozostałych zajmuje się ekspedytor wyjątków, który zapisuje w dzienniku przyczynę wyjątku i znajduje procedurę jego obsługi.
Ekspedytor przerwań jądra obsługuje przerwania poprzez wywołanie podprogramu obsługi przerwania (np. w module sterującym urządzenia) albo wewnętrznego podprogramu jądra.
Egzekutor oferuje usługi, z których mogą korzystać wszystkie podsystemy środowiskowe. Można je podzielić następująco: zarządzanie obiektami, zarządzanie pamięcią wirtualną, zarządzanie procesami, obsługę lokalnych wywołań procedur, zarządzanie wejściem/wyjściem i monitorowanie bezpieczeństwa odwołań.
Windows 2000 posługuje się obiektami, które reprezentują wszystkie usługi i byty. Zarządca obiektów nadzoruje wszystkie te obiekty, tzn. obiekty katalogowe, obiekty dowiązań symbolicznych, semaforów, zdarzeń, procesów, wątków, portów i plików.
Do posługiwania się obiektami służy standardowy interfejs z procedurami
create
(utwórz),
open
(otwórz),
close
(zamknij),
query name
(podaj nazwę obiektu przypisanego do uchwytu),
parse
(znajdź obiekt na podstawie nazwy),
security
(procedura do sprawdzenia braku naruszenia ochrony).
Gdy wątek chce skorzystać z obiektu, wywołuje metodę open
, która przekazuje wątkowi tzw.
uchwyt do obiektu. Tym uchwytem wątek posługuje się przy następnych wywołaniach.
Zarządca obiektów generuje uchwyt sprawdzając zawczasu, czy nie nastąpiło naruszenie ochrony (każdy obiekt ma
przypisaną listę kontroli dostępu, z której wynika, kto ma prawo z niego korzystać).
Zarządca obiektów cały czas wie, które procesy używają których obiektów.
Proces może otrzymać uchwyt poprzez stworzenie obiektu, otwarcie istniejącego obiektu, otrzymanie duplikatu uchwytu od innego procesu lub poprzez odziedziczenie uchwytu po procesie macierzystym.
Nazwy obiektów mają taką strukturę jak nazwy ścieżkowe plików w systemie DOS i w Uniksie. Dodatkowo zaimplementowano też obiekty dowiązań symbolicznych, dzięki którym dany obiekt może mieć wiele nazw alternatywnych (aliasów).
Pamięć wirtualną Windows 2000 zaprojektowano przy założeniu, że sprzęt wspomaga mechanizm stronicowania z odwzorowaniem adresów logicznych na fizyczne, przezroczystą obsługę spójności pamięci podręcznej w systemach wieloprocesorowych oraz możliwość przypisania tej samej ramki do wielu pozycji tablicy stron. Zarządca pamięci wirtualnej realizuje stronicowanie ze stronami wielkości 4KB.
Przydział pamięci w Windows 2000 jest dwustopniowy. Najpierw rezerwuje się miejsce w przestrzeni adresowej procesu a następnie znajduje się miejsce w pliku stronicowania i przyporządkowuje je do zarezerwowanego miejsca w przestrzeni adresowej procesu.
Adres logiczny jest 32 bitowy, można więc nim zaadresować 4GB. Każdy proces ma katalog stron o 1024 pozycjach (adresowanie wymaga tu 10 bitów), każda pozycja to odwołanie do tablicy stron, z których każda ma 1024 pozycje (adresowanie wymaga tu 10 bitów) z odwołaniami do 4KB ramek w pamięci operacyjnej (adres względny w ramce ma więc 12 bitów). Razem daje to 32 bity. Każdy adres składa się z 10 bitów wskazujących pozycję w katalogu stron, 10 bitów wskazujących pozycję w tablicy stron i 12 bitów wskazujących przesunięcie na stronie.
Zarządca procesów oferuje usługi tworzenia, usuwania i używania wątków i procesów. Kwestie takie, jak zależności rodzic-dziecko i hierarchie procesów, są pozostawione podsystemom środowiskowym, które są właścicielami procesów. Proces jest oczywiście obiektem, więc na przykład przy tworzeniu pośredniczy też zarządca obiektów.
Lokalne wywołanie procedury (LPC -- Local Procedure Call) służy do przekazywania zleceń i wyników między procesami klienckimi i serwerowymi w ramach jednej maszyny. LPC jest podobne do RPC, ale jest zoptymalizowane do użycia w ramach jednego systemu Windows 2000.
Komunikacja przez LPC może odbywać się w jednym z trzech trybów:
Zarządca wejścia/wyjścia odpowiada za systemy plików, obsługę pamięci podręcznej, moduły sterujące urządzeniami i siecią. Śledzi na bieżąco, które z instalowalnych systemów plików są załadowane i zarządza buforami do obsługi zleceń wejścia/wyjścia.
Zarządca wejścia/wyjścia współpracuje z zarządcą pamięci wirtualnej w celu umieszczenia w pamięci wyników plikowych operacji wejścia/wyjścia. Nadzoruje również zarządcę pamięci podręcznej, który obsługuje pamięć podręczną dla całego systemu wejścia/wyjścia.
Zarządca wejścia/wyjścia umożliwia korzystanie z wejścia/wyjścia zarówno w trybie synchronicznym jak i asynchronicznym, oferuje odmierzanie czasu dla modułów sterujących oraz możliwość wywołania jednego modułu sterującego z innego modułu sterującego.
Ze względu na to, że Windows 2000 napisano metodami obiektowymi, można było zastosować w tym systemie uniwersalne mechanizmu kontroli dostępu do każdego bytu systemowego. Gdy proces prosi o uchwyt do obiektu, monitor bezpieczeństwa odwołań bada żeton bezpieczeństwa procesu i listę kontroli dostępu obiektu, żeby sprawdzić, czy proces ma wystarczające uprawnienia do korzystania z tego obiektu.
Zarządca urządzeń Plug-and-Play ma wykrywać zmiany w konfiguracji sprzętu i dostosowywać do nich system operacyjny. Gdy pojawia się nowy sprzęt, zarządca urządzeń Plug-and-Play ładuje odpowiedni moduł sterujący.
Egzekutor zapewnia odpowiednie usługi leżącym powyżej niego podsystemom środowiskowym. To wyższe położenie procesów użytkownika pozwala na uruchamianie w Windows 2000 programów dla innego systemu operacyjnego.
Wszystkie podsystemy środowiskowe działają w trybie użytkownika, podczas gdy egzekutor i warstwy niższe od niego działają w trybie chronionym.
Głównym podsystemem środowiskowym jest Win32. Służy on do uruchamiania wszystkich procesów. Wszystkim zapewnia też dostęp do klawiatury, myszy i możliwości wyświetlania grafiki.
Podsystem środowiskowy dla MS-DOS nosi też nazwę maszyny wirtualnej DOS (VDM - Virtual DOS Machine) i jest aplikacją działającą w trybie użytkownika napisaną powyżej Win32. Podsystem środowiskowy dla MS-DOS jest normalnym procesem użytkownika podlegającym planowaniu tak, jak każdy inny proces.
Nad Win32 istnieją jeszcze podsystemy środowiskowe Win16 (dla aplikacji 16 bitowych Windows 3.1) i POSIX (dla przenośnych aplikacji zgodnych z IEEE 1003.1) i OS/2.
Podsystemy rejestracji i podsystem bezpieczeństwa działają w trybie użytkownika i mają za zadanie weryfikację tożsamości rejestrującego się użytkownika. Napisano je ponad Win32.
Pakiet uwierzytelniania sprawdza prawa użytkowników za każdym razem, gdy chcą uzyskać dostęp do obiektów systemu. W Windows 2000 domyślnie korzysta się z Kerberosa jako mechanizmu uwierzytelniania.
W wykładzie 13 poznaliśmy wewnętrzną strukturę systemu Windows 2000. Ze względu na swoją warstwową architekturę, jest to niezwykle interesujący przykład systemu. Dzięki niej jest on "otwarty z obu stron".
Przez otwartość "od dołu" rozumiemy przenośność. Dzięki podmianie warstwy abstrakcji sprzętu można wymienić sprzęt leżący "pod" systemem operacyjnym.
Przez otwartość "od góry" rozumiemy rozszerzalność. Dzięki dodaniu nowego podsystemu środowiskowego można uruchomić aplikacje napisaną dla dowolnego systemu operacyjnego.
Przy obydwu tych operacjach (podmianie sprzętu i rozszerzeniu) bez zmian pozostają zasadnicze warstwy systemu, tzn. jądro i egzekutor.