Menu
Jest wolny
rejestracja
Dom  /  Oprogramowanie układowe/ Wykład: Sposoby implementacji stosowanych środowisk oprogramowania. Architektura, cel i funkcja systemów operacyjnych Cele i ćwiczenia

Wykład: Sposoby implementacji stosowanych środowisk programistycznych. Architektura, cel i funkcja systemów operacyjnych Cele i ćwiczenia

Podczas gdy wiele cech architektury systemu operacyjnego dotyczy bezpośrednio tylko programistów systemowych, koncepcja narzędzi wielu aplikacji (obsługujących) jest bezpośrednio związana z potrzebami użytkowników końcowych – zdolnością systemu operacyjnego do uruchamiania aplikacji napisanych dla innych systemów operacyjnych. Ta właściwość systemu operacyjnego nazywana jest kompatybilnością.

Kompatybilność aplikacji może być na poziomie binarnym i na poziomie źródłowym. Aplikacje są zwykle przechowywane w systemie operacyjnym jako pliki wykonywalne, które zawierają binarne obrazy kodu i danych. Kompatybilność binarna jest osiągana, jeśli możesz wziąć program wykonywalny i uruchomić go w innym środowisku systemu operacyjnego.

Kompatybilność źródeł wymaga odpowiedniego kompilatora w oprogramowaniu komputera, na którym zamierzasz uruchomić aplikację, a także kompatybilności bibliotek i wywołań systemowych. W takim przypadku konieczne jest przekompilowanie kodu źródłowego aplikacji do nowego modułu wykonywalnego.

Kompatybilność źródeł jest ważna przede wszystkim dla twórców aplikacji, którzy mają do dyspozycji kod źródłowy. Ale dla użytkowników końcowych tylko zgodność binarna ma praktyczne znaczenie, ponieważ tylko w tym przypadku mogą używać tego samego produktu w różnych systemach operacyjnych i na różnych maszynach.

Rodzaj możliwej kompatybilności zależy od wielu czynników. Najważniejszym z nich jest architektura procesora. Jeśli procesor wykorzystuje ten sam zestaw instrukcji (ewentualnie z dodatkami, jak w przypadku IBM PC: zestaw standardowy + multimedia + grafika + strumieniowanie) i ten sam zakres adresów, to zgodność binarną można osiągnąć całkiem prosto. Aby to zrobić, muszą być spełnione następujące warunki:

  • API używane przez aplikację musi być obsługiwane przez dany system operacyjny;
  • wewnętrzna struktura pliku wykonywalnego aplikacji musi odpowiadać strukturze plików wykonywalnych danego systemu operacyjnego.

Jeśli procesory mają różne architektury, to oprócz wymienionych warunków konieczne jest zorganizowanie emulacji kodu binarnego. Na przykład szeroko stosowana jest emulacja poleceń procesora Intel na procesorze Motorola 680x0 komputera Macintosh. Emulator oprogramowania następnie wybiera sekwencyjnie instrukcję binarną procesora Intel i wykonuje równoważny podprogram zapisany w instrukcjach procesora Motorola. Ponieważ procesor Motoroli nie ma dokładnie tych samych rejestrów, flag, wewnętrznej jednostki ALU itp., co w procesorach Intela, musi również symulować (emulować) wszystkie te elementy za pomocą swoich rejestrów lub pamięci.

Jest to prosta, ale bardzo powolna praca, ponieważ pojedyncze polecenie Intela jest znacznie szybsze niż sekwencja poleceń procesora Motorola, która je emuluje. Wyjściem w takich przypadkach jest wykorzystanie tak zwanych środowisk aplikacji lub środowisk operacyjnych. Jednym ze składników takiego środowiska jest zestaw funkcji API, które system operacyjny udostępnia swoim aplikacjom. Aby skrócić czas poświęcany na wykonywanie cudzych programów, środowiska aplikacji imitują wywołania funkcji bibliotecznych.

Skuteczność tego podejścia wynika z faktu, że większość dzisiejszych programów działa pod GUI (graficznymi interfejsami użytkownika), takimi jak Windows, MAC czy UNIX Motif, podczas gdy aplikacje spędzają 60-80% czasu na wykonywaniu funkcji GUI i innych wywołaniach bibliotek systemu operacyjnego . To właśnie ta właściwość aplikacji umożliwia środowiskom aplikacji zrekompensowanie dużej ilości czasu poświęconego na emulację programów na polecenie. Starannie zaprojektowane środowisko aplikacji zawiera biblioteki, które naśladują biblioteki GUI, ale są napisane w „natywnym” kodzie. W ten sposób uzyskuje się znaczne przyspieszenie wykonywania programów z API innego systemu operacyjnego. To podejście jest również nazywane rozgłaszaniem, aby odróżnić je od wolniejszego procesu emulacji jedno polecenie na raz.

Na przykład w przypadku programu Windows działającego na komputerze Macintosh podczas interpretowania poleceń z procesora Intel wydajność może być bardzo niski. Ale kiedy wywoływana jest funkcja GUI, otwierane jest okno itp., moduł systemu operacyjnego implementujący środowisko aplikacji Windows może przechwycić to wywołanie i przekierować je do procedury otwierania okna, która jest rekompilowana dla procesora Motorola 680x0. W rezultacie w takich częściach kodu szybkość programu może osiągnąć (i ewentualnie przewyższyć) szybkość pracy na własnym procesorze.

Aby program napisany dla jednego systemu operacyjnego był wykonywany na innym systemie operacyjnym, nie wystarczy zapewnić kompatybilność API. Koncepcje różnych systemów operacyjnych mogą ze sobą kolidować. Na przykład w jednym systemie operacyjnym aplikacja może sterować urządzeniami we / wy, w innym - te działania są prerogatywą systemu operacyjnego.

Każdy system operacyjny ma własne mechanizmy ochrony zasobów, własne algorytmy obsługi błędów i wyjątków, określoną strukturę procesora i schemat zarządzania pamięcią, własną semantykę dostępu do plików i graficzny interfejs użytkownika. Aby zapewnić kompatybilność, konieczne jest zorganizowanie bezkonfliktowego współistnienia w ramach jednego systemu operacyjnego kilku metod zarządzania zasobami komputera.

Istnieją różne opcje tworzenia środowisk z wieloma aplikacjami, różniące się zarówno cechami architektonicznymi, jak i funkcjonalnością, które zapewniają różne stopnie przenośności aplikacji. Jedna z najbardziej oczywistych opcji implementacji wielu środowisk aplikacji opiera się na standardowej strukturze warstwowej systemu operacyjnego.

Inny sposób budowania wielu środowisk aplikacji opiera się na podejściu mikrojądra. Jednocześnie bardzo ważne jest zwrócenie uwagi na podstawową, wspólną dla wszystkich środowisk aplikacyjnych różnicę między mechanizmami systemu operacyjnego a funkcjami wysokiego poziomu specyficznymi dla każdego ze środowisk aplikacyjnych, które rozwiązują problemy strategiczne. Zgodnie z architektura mikrojądra wszystkie funkcje systemu operacyjnego są realizowane przez mikrojądro i serwery trybu użytkownika. Ważne jest, aby środowisko aplikacji zostało zaprojektowane jako osobny serwer trybu użytkownika i nie zawiera podstawowych mechanizmów.

Aplikacje korzystające z API dokonują wywołań systemowych do odpowiedniego środowiska aplikacji poprzez mikrojądro. Środowisko aplikacji przetwarza żądanie, wykonuje je (być może przy użyciu podstawowych funkcji mikrojądra w celu uzyskania pomocy) i wysyła wynik z powrotem do aplikacji. W trakcie wykonywania żądania środowisko aplikacji musi z kolei mieć dostęp do podstawowych mechanizmów systemu operacyjnego zaimplementowanych przez mikrojądro i inne serwery systemu operacyjnego.

Wszystkie zalety i wady architektury mikrojądrowej tkwią w tym podejściu do budowy środowisk wieloaplikacyjnych, a w szczególności:

  • bardzo łatwo jest dodawać i wykluczać środowiska aplikacji, co jest konsekwencją dobrej rozszerzalności systemu operacyjnego mikrojądra;
  • jeśli jedno ze środowisk aplikacyjnych ulegnie awarii, pozostałe pozostają sprawne, co przyczynia się do niezawodności i stabilności systemu jako całości;
  • niska wydajność systemów operacyjnych z mikrojądrem wpływa na szybkość narzędzi aplikacji, a co za tym idzie na szybkość aplikacji.

W rezultacie należy zauważyć, że tworzenie kilku narzędzi aplikacji w jednym systemie operacyjnym do wykonywania aplikacji z różnych systemów operacyjnych to sposób, który pozwala mieć jedną wersję programu i przenosić ją między różnymi systemami operacyjnymi. Wiele środowisk aplikacji zapewnia binarną zgodność danego systemu operacyjnego z aplikacjami napisanymi dla innych systemów operacyjnych.

1.9. Maszyny wirtualne jako nowoczesne podejście do wdrażania środowisk wieloaplikacyjnych

Koncepcja „monitorowania maszyny wirtualnej” (VMM) powstała pod koniec lat 60. jako oprogramowanie poziom abstrakcji który podzielił platformę sprzętową na wiele maszyn wirtualnych. Każda z tych maszyn wirtualnych (VM) była tak podobna do podstawowej maszyny fizycznej, że istniejąca oprogramowanie można na nim wykonać bez zmian. W tamtych czasach ogólne zadania obliczeniowe były wykonywane na drogich komputerach mainframe (takich jak IBM/360), a użytkownicy docenili zdolność VMM do rozprowadzania ograniczonych zasobów w wielu aplikacjach.

W latach 80-90 koszty sprzętu komputerowego znacznie i skutecznie spadły wielozadaniowy system operacyjny, co zmniejszyło wartość VMM w oczach użytkowników. Komputery mainframe ustąpiły miejsca minikomputerom, a następnie komputerom PC i nie było potrzeby stosowania VMM. W rezultacie architektura komputerowa po prostu zniknęła sprzęt komputerowy za ich skuteczną realizację. Pod koniec lat 80. w nauce i produkcji MVM były postrzegane jedynie jako ciekawostka historyczna.

Dziś MVM ponownie znajduje się w centrum uwagi. Intel, AMD, Sun Microsystems i IBM tworzą strategie wirtualizacji, a podejścia oparte na maszynach wirtualnych ewoluują w środowisku akademickim i uniwersyteckim w celu rozwiązania problemów związanych z mobilnością, bezpieczeństwem i zarządzaniem. Co się stało między rezygnacją MVM a ich odrodzeniem?

W latach 90. naukowcy ze Stanford University zaczęli badać wykorzystanie maszyn wirtualnych do przezwyciężenia ograniczeń sprzętu i systemów operacyjnych. Problemy pojawiły się z komputerami z technologią Massively Parallel Processing (MPP), które były trudne do zaprogramowania i nie mogły uruchamiać istniejących systemów operacyjnych. Badacze odkryli, że maszyny wirtualne mogą upodobnić tę niezręczną architekturę do istniejących platform, aby skorzystać z gotowych systemów operacyjnych. Z tego projektu pochodzili ludzie i pomysły, które stały się rezerwą złota firmy VMware (www.vmware.com), pierwszego dostawcy VMM dla komputerów głównego nurtu.

Jak na ironię, postęp nowoczesnych systemów operacyjnych i redukcja kosztów sprzętu doprowadziły do ​​problemów, które naukowcy mieli nadzieję rozwiązać za pomocą VMM. Tani sprzęt przyczynił się do szybkiego rozpowszechnienia komputerów, ale często były one niewykorzystane, wymagając dodatkowej przestrzeni i wysiłku w utrzymaniu. A konsekwencjami wzrostu funkcjonalnych możliwości systemu operacyjnego była ich niestabilność i podatność na ataki.

Aby zmniejszyć wpływ awarii systemu i chronić przed włamaniami, administratorzy systemu ponownie zwrócili się do jednego zadania model obliczeniowy(z jedną aplikacją na jednym komputerze). Spowodowało to dodatkowe koszty ze względu na zwiększone wymagania sprzętowe. Przenoszenie aplikacji z różnych maszyn fizycznych na maszyny wirtualne i konsolidacja tych maszyn wirtualnych na kilku platformach fizycznych pozwoliło na zwiększenie wykorzystania sprzętu, zmniejszenie kosztów zarządzania i zmniejszenie powierzchni. Tak więc zdolność VMM do multipleksowania sprzętu — tym razem w imię konsolidacji serwerów i obliczeń użytkowych — przywróciła je do życia.

W dzisiejszych czasach VMM stał się nie tyle narzędziem do organizacji wielozadaniowości, co kiedyś pomyślany jako rozwiązanie problemów zapewnienia bezpieczeństwa, mobilności i niezawodności. Pod wieloma względami VMM daje twórcom systemów operacyjnych możliwość rozwijania funkcjonalności, które nie są możliwe w dzisiejszych złożonych systemach operacyjnych. Funkcje, takie jak migracja i zabezpieczenia, są znacznie wygodniejsze do wdrożenia na poziomie VMM, co zapewnia zgodność wsteczną podczas wdrażania innowacyjnych rozwiązań systemu operacyjnego przy zachowaniu wcześniejszych osiągnięć.

Wirtualizacja to ewoluująca technologia. Ogólnie rzecz biorąc, wirtualizacja umożliwia oddzielenie oprogramowania od podstawowej infrastruktury sprzętowej. W rzeczywistości zrywa połączenie między określonym zestawem programów a określonym komputerem. Monitor maszyny wirtualnej oddziela się oprogramowanie od sprzętu i tworzy warstwę pośrednią między oprogramowaniem uruchamianym przez maszyny wirtualne a sprzętem. Ten poziom umożliwia VMM pełną kontrolę wykorzystania zasobów sprzętowych. systemy operacyjne gościa (GuestOS) które działają na maszynie wirtualnej.

VMM tworzy ujednolicony widok podstawowego sprzętu, dzięki czemu fizyczne maszyny od różnych dostawców z różnymi podsystemami we/wy wyglądają tak samo, a maszyny wirtualne działają na dowolnym dostępnym sprzęcie. Nie martwiąc się o poszczególne maszyny z ich ścisłymi połączeniami między sprzętem a oprogramowaniem, administratorzy mogą postrzegać sprzęt jako po prostu pulę zasobów do świadczenia dowolnej usługi na żądanie.

Dzięki pełna enkapsulacja Monitor VMM może mapować maszynę wirtualną na dowolne dostępne zasoby sprzętowe, a nawet przenosić ją z jednej fizycznej maszyny na drugą. Zadanie równoważenia obciążenia na grupie maszyn staje się trywialne, a pojawiają się niezawodne sposoby radzenia sobie z awariami sprzętu i wzrostem systemu. Jeśli musisz wyłączyć uszkodzony komputer lub uruchomić nowy, VMM może odpowiednio rozmieścić maszyny wirtualne. Maszyna wirtualna jest łatwa do replikacji, co pozwala administratorom na szybkie dostarczanie nowych usług w razie potrzeby.

Enkapsulacja oznacza również, że administrator może w dowolnym momencie zawiesić lub wznowić maszynę wirtualną, a także zapisać aktualny stan maszyny wirtualnej lub przywrócić ją do stanu poprzedniego. Dzięki uniwersalnym możliwościom cofania łatwo radzić sobie z wypadkami i błędami konfiguracji. Enkapsulacja jest sercem ogólnego modelu mobilności, ponieważ zawieszona maszyna wirtualna może być kopiowana przez sieć, przechowywana i transportowana na nośnikach wymiennych.

VMM działa jako pośrednik we wszystkich interakcjach między maszyną wirtualną a sprzętem bazowym, utrzymując wiele maszyn wirtualnych działających na jednej platformie sprzętowej i zapewniając niezawodną izolację. VMM pozwala na złożenie grupy maszyn wirtualnych o niskich wymaganiach dotyczących zasobów na osobnym komputerze, zmniejszając koszty sprzęt komputerowy oraz zapotrzebowanie na przestrzeń produkcyjną.

Całkowita izolacja jest również ważna dla niezawodności i bezpieczeństwa. Aplikacje, które kiedyś działały na tej samej maszynie, mogą teraz być dystrybuowane na różne maszyny wirtualne. Jeśli jeden z nich w wyniku błędu spowoduje awarię systemu operacyjnego, inne aplikacje zostaną od niego odizolowane i będą nadal działać. Jeśli jedna z aplikacji jest zagrożona atakiem zewnętrznym, atak zostanie zlokalizowany w „zaatakowanej” maszynie wirtualnej. W ten sposób VMM jest narzędziem do restrukturyzacji systemu w celu zwiększenia jego odporności i bezpieczeństwa, bez dodatkowej przestrzeni i wysiłku administracyjnego wymaganego podczas uruchamiania aplikacji na oddzielnych komputerach fizycznych.

VMM musi skojarzyć interfejs sprzętowy z maszyną wirtualną, zachowując pełną kontrolę nad podstawową maszyną i procedurami interakcji z jej sprzętem. Istnieją różne metody osiągnięcia tego celu, oparte na pewnych kompromisach technicznych. Szukając takich kompromisów brane są pod uwagę główne wymagania dla VMM: kompatybilność, wydajność i prostota. Kompatybilność jest ważna, ponieważ główną zaletą VMM jest możliwość uruchamiania starszych aplikacji. Wydajność określa wielkość narzutu wirtualizacji — programy na maszynie wirtualnej muszą działać z taką samą szybkością, jak na maszynie rzeczywistej. Potrzebna jest prostota, ponieważ awaria VMM spowoduje awarię wszystkich maszyn wirtualnych działających na komputerze. W szczególności bezpieczna izolacja wymaga, aby VMM był wolny od błędów, które atakujący mogą wykorzystać do zniszczenia systemu.

Zamiast majstrować przy skomplikowanym przepisaniu kodu systemu operacyjnego gościa, możesz wprowadzić pewne zmiany w systemie operacyjnym hosta, zmieniając niektóre z bardziej „irytujących” części jądra. Takie podejście nazywa się parawirtualizacją. Oczywiste jest, że w tym przypadku tylko autor może dostosować jądro systemu operacyjnego i np. Microsoft nie wykazuje chęci dostosowania popularnego jądra Windows 2000 do realiów konkretnych maszyn wirtualnych.

W parawirtualizacji projektant VMM na nowo definiuje interfejs maszyny wirtualnej, zastępując niemożliwy do wirtualizacji podzbiór oryginalnego zestawu instrukcji wygodniejszymi i wydajniejszymi odpowiednikami. Należy pamiętać, że chociaż system operacyjny musi zostać przeniesiony, aby działał na tych maszynach wirtualnych, większość popularnych aplikacji może działać bez zmian.

Największą wadą parawirtualizacji jest niekompatybilność. Każdy system operacyjny zaprojektowany do działania pod kontrolą parawirtualizowanego monitora VMM musi zostać przeniesiony do tej architektury poprzez negocjowanie współpracy z dostawcami systemu operacyjnego. Ponadto nie można używać starszych systemów operacyjnych, a istniejących maszyn nie można łatwo zastąpić maszynami wirtualnymi.

Aby osiągnąć wysoką wydajność i kompatybilność podczas wirtualizacji architektury x86, VMware opracował nową technikę wirtualizacji, która łączy tradycyjne wykonywanie na żywo z szybką translacją binarną w locie. W większości nowoczesnych systemów operacyjnych tryby pracy procesora podczas wykonywania zwykłych aplikacji są łatwo zwirtualizowane, a zatem można je zwirtualizować poprzez bezpośrednie wykonanie. Nieodpowiednie dla wirtualizacji tryby uprzywilejowane mogą być wykonywane przez translator binarny, naprawiając „niezręczne” instrukcje x86. Rezultatem jest bardzo wydajny maszyna wirtualna który w pełni pasuje do sprzętu i zachowuje pełną kompatybilność oprogramowania.

Przekonwertowany kod jest bardzo podobny do wyników parawirtualizacji. Zwykłe polecenia są wykonywane bez zmian, a polecenia wymagające specjalnego przetwarzania (takie jak POPF i polecenia odczytu rejestrów segmentu kodu) są zastępowane przez translator sekwencjami poleceń podobnymi do tych, które są wymagane do wykonania na parawirtualizowanej maszynie wirtualnej. Istnieje jednak ważna różnica: zamiast modyfikować kod źródłowy systemu operacyjnego lub aplikacji, translator binarny modyfikuje kod przy pierwszym uruchomieniu.

Chociaż tłumaczenie kodu binarnego wymaga pewnych dodatkowych nakładów, jest to znikome przy normalnych obciążeniach. Tłumacz przetwarza tylko część kodu, a szybkość wykonania programu staje się porównywalna z szybkością wykonania bezpośredniego - gdy tylko pamięć podręczna się zapełni

Stworzenie pełnoprawnego środowiska aplikacji, w pełni kompatybilnego ze środowiskiem innego systemu operacyjnego, jest dość trudnym zadaniem, ściśle związanym ze strukturą systemu operacyjnego. Istnieją różne opcje budowania środowisk z wieloma aplikacjami, różniące się zarówno cechami rozwiązań architektonicznych, jak i funkcjonalnością, która zapewnia różne stopnie przenośności aplikacji. .

W wielu wersjach systemu UNIX OS translator środowiska aplikacji jest zaimplementowany jako zwykła aplikacja. W systemach operacyjnych zbudowanych z wykorzystaniem koncepcji mikrojądra, takich jak Windows NT lub Workplace OS, środowiska aplikacji działają jako serwery trybu użytkownika. A w systemie OS/2, z jego prostszą architekturą, narzędzia do organizowania środowisk aplikacji są wbudowane głęboko w system operacyjny. Jedna z najbardziej oczywistych opcji implementacji wielu środowisk aplikacji opiera się na standardowej warstwowej strukturze systemu operacyjnego. .

Ryż. 3.13. Środowiska programowania aplikacji, które tłumaczą wywołania systemowe

Niestety, zachowanie prawie wszystkich funkcji składających się na API jednego systemu operacyjnego znacznie różni się od zachowania odpowiadających im funkcji innego systemu operacyjnego.

W innej implementacji wielu środowisk aplikacji system operacyjny ma wiele równorzędnych interfejsów API. W przykładzie pokazanym na ryc. 3.14 Przykład systemu operacyjnego obsługuje aplikacje napisane dla OS1, OS2 i OS3. W tym celu interfejsy programowania aplikacji wszystkich tych systemów operacyjnych znajdują się bezpośrednio w przestrzeni jądra systemu: API OS1, API OS2 i API OS3. W tej odmianie funkcje poziomu API odnoszą się do funkcji systemu operacyjnego niższego poziomu, które muszą obsługiwać wszystkie trzy ogólnie niezgodne środowiska aplikacji.

Różne systemy operacyjne inaczej zarządzają czasem systemowym, używają innego formatu pory dnia, współdzielą czas procesora w oparciu o własne algorytmy itp. Funkcje każdego interfejsu API są implementowane przez jądro, biorąc pod uwagę specyfikę odpowiedniego systemu operacyjnego, nawet jeśli mają podobny cel. Na przykład, jak wspomniano, funkcja tworzenia procesu działa inaczej dla aplikacji UNIX i aplikacji OS/2. Podobnie, gdy proces się kończy, jądro musi również określić, do którego systemu operacyjnego należy proces. Jeśli proces ten został utworzony na żądanie aplikacji UNIX, to podczas jego zakończenia jądro powinno wysłać sygnał do procesu nadrzędnego, tak jak to ma miejsce w UNIX OS. A po zakończeniu procesu OS / 2 jądro powinno zauważyć, że identyfikator procesu nie może być ponownie użyty przez inny proces OS / 2. Aby jądro mogło wybrać pożądaną implementację wywołania systemowego, każdy proces musi przekazać do jądra zestaw cech identyfikujących.

Ryż. 3.14 Wdrażanie interoperacyjności w oparciu o wiele interfejsów API równorzędnych

Inny sposób budowania wielu środowisk aplikacji opiera się na podejściu mikrojądra... Jednocześnie bardzo ważne jest oddzielenie podstawowych mechanizmów systemu operacyjnego wspólnych dla wszystkich środowisk aplikacyjnych od funkcji wysokiego poziomu specyficznych dla każdego ze środowisk aplikacyjnych, które rozwiązują problemy strategiczne.

Zgodnie z architekturą mikrojądra, wszystkie funkcje systemu operacyjnego są implementowane przez serwery mikrojądra i trybu użytkownika. Ważne jest, aby każde środowisko aplikacji było zaprojektowane jako osobny serwer trybu użytkownika i nie zawierało podstawowych mechanizmów (rysunek 3.15). Aplikacje korzystające z API dokonują wywołań systemowych do odpowiedniego środowiska aplikacji poprzez mikrojądro. Środowisko aplikacji przetwarza żądanie, wykonuje je (być może przy użyciu podstawowych funkcji mikrojądra w celu uzyskania pomocy) i wysyła wynik z powrotem do aplikacji. W trakcie wykonywania żądania środowisko aplikacji musi z kolei mieć dostęp do podstawowych mechanizmów systemu operacyjnego zaimplementowanych przez mikrojądro i inne serwery systemu operacyjnego.

Takie podejście do budowy środowisk wieloaplikacyjnych ma wszystkie zalety i wady architektury mikrojądra, a w szczególności:

§ bardzo łatwo jest dodawać i wykluczać środowiska aplikacji, co jest konsekwencją dobrej rozszerzalności systemów operacyjnych z mikrojądrem;

§ niezawodność i stabilność wyraża się w tym, że w przypadku awarii jednego ze środowisk aplikacji wszystkie pozostałe pozostają sprawne;

§ Niska wydajność systemu operacyjnego mikrojądra wpływa na szybkość środowisk aplikacji, a tym samym na szybkość wykonywania aplikacji.

Ryż. 3.15. Podejście mikrojądra do wdrażania wielu środowisk aplikacji

Tworzenie kilku środowisk aplikacji w jednym systemie operacyjnym do wykonywania aplikacji z różnych systemów operacyjnych to sposób, który pozwala na posiadanie jednej wersji programu i przenoszenie jej między systemami operacyjnymi. Wiele środowisk aplikacji zapewnia binarną zgodność danego systemu operacyjnego z aplikacjami napisanymi dla innych systemów operacyjnych. W rezultacie użytkownicy mają większą swobodę wyboru systemu operacyjnego i łatwiejszy dostęp do wysokiej jakości oprogramowania.

Wnioski:

§ Najprostsza struktura systemu operacyjnego polega na podzieleniu wszystkich komponentów systemu operacyjnego na moduły realizujące główne funkcje systemu operacyjnego (jądro) oraz moduły realizujące funkcje pomocnicze systemu operacyjnego. Wspierające moduły systemu operacyjnego są projektowane albo jako aplikacje (narzędzia i programy do przetwarzania systemu), albo jako biblioteki procedur. Moduły pomocnicze są ładowane do pamięci RAM tylko na czas ich funkcji, to znaczy są przejściowe. Moduły jądra są rezydentami w pamięci RAM, to znaczy są rezydentami.

§ W przypadku sprzętowej obsługi trybów o różnych poziomach uprawnień stabilność systemu operacyjnego można zwiększyć, wykonując funkcje jądra w trybie uprzywilejowanym, a pomocnicze moduły i aplikacje systemu operacyjnego w trybie użytkownika. Umożliwia to ochronę kodów i danych systemu operacyjnego i aplikacji przed nieautoryzowanym dostępem. System operacyjny może pełnić rolę arbitra w sporach dotyczących aplikacji o zasoby.

§ Jądro, będące elementem strukturalnym systemu operacyjnego, z kolei można logicznie rozłożyć na następujące warstwy (od najniższej):

§ zależne od maszyny komponenty systemu operacyjnego;

§ podstawowe mechanizmy jądra;

§ menedżerowie zasobów;

§ interfejs wywołań systemowych.

§ W systemie wielowarstwowym każda warstwa służy warstwie nadrzędnej, pełniąc dla niej pewien zestaw funkcji, które tworzą interfejs międzywarstwowy. W oparciu o funkcje warstwy pod spodem kolejna warstwa hierarchii buduje swoje funkcje - bardziej złożone i potężniejsze, które z kolei okazują się prymitywami do tworzenia jeszcze potężniejszych funkcji warstwy nadrzędnej. Wielowarstwowa organizacja systemu operacyjnego znacznie upraszcza rozwój i modernizację systemu.

§ Każdy system operacyjny, aby rozwiązać swoje zadania, wchodzi w interakcję ze sprzętem komputerowym, a mianowicie: środkami wspierania trybu uprzywilejowanego i translacji adresów, środkami przełączania procesów i ochrony obszarów pamięci, systemem przerwań i zegarem systemowym. To sprawia, że ​​system operacyjny jest zależny, powiązany z określoną platformą sprzętową.

§ Przenośność systemu operacyjnego można osiągnąć, przestrzegając następujących zasad. Po pierwsze, większość kodu musi być napisana w języku, który ma tłumaczy na wszystkich komputerach, na które system ma zostać przeniesiony. Po drugie, ilość fragmentów kodu zależnych od komputera, które bezpośrednio wchodzą w interakcję ze sprzętem, powinna być maksymalnie zminimalizowana. Po trzecie, kod zależny od sprzętu musi być niezawodnie zlokalizowany w wielu modułach.

§ Architektura mikrojądra jest alternatywą dla klasycznego sposobu budowania systemu operacyjnego, zgodnie z którą wszystkie główne funkcje systemu operacyjnego składające się na jądro wielowarstwowe są wykonywane w trybie uprzywilejowanym. W systemach operacyjnych z mikrojądrem tylko bardzo mała część systemu operacyjnego, zwana mikrojądrem, działa w trybie uprzywilejowanym. Wszystkie inne funkcje jądra wysokiego poziomu zaprojektowano jako aplikacje trybu użytkownika.

§ Systemy operacyjne z mikrojądrem spełniają większość wymagań nowoczesnych systemów operacyjnych, zapewniając przenośność, rozszerzalność, niezawodność i tworząc dobre warunki do obsługi aplikacji rozproszonych. Te zalety wiążą się z obniżoną wydajnością, co jest główną wadą architektury mikrojądra.

§ Środowisko oprogramowania aplikacyjnego - zestaw narzędzi systemu operacyjnego zaprojektowanych do organizowania wykonywania aplikacji przy użyciu określonego systemu instrukcji maszynowych, określonego typu API i określonego formatu programu wykonywalnego. Każdy system operacyjny tworzy co najmniej jedno środowisko programowania aplikacji. Problem polega na zapewnieniu zgodności kilku środowisk oprogramowania w ramach tego samego systemu operacyjnego. Podczas budowania wielu środowisk aplikacji wykorzystywane są różne rozwiązania architektoniczne, koncepcje emulacji kodu binarnego oraz translacje API.

Zadania i ćwiczenia

1. Które z poniższych terminów są synonimami?

§ uprzywilejowany reżim;

§ tryb obronny;

§ tryb nadzorcy;

§ tryb użytkownika;

§ tryb rzeczywisty;

§ tryb jądra.

2. Czy można, analizując kod binarny programu, stwierdzić, że nie można go wykonać w trybie użytkownika?

3. Jakie są różnice między procesorem w trybie uprzywilejowanym a trybem użytkownika?

4. W idealnym przypadku architektura systemu operacyjnego mikrojądra wymaga umieszczenia w mikrojądrze tylko tych składników systemu operacyjnego, których nie można uruchomić w trybie użytkownika. Co sprawia, że ​​twórcy systemów operacyjnych odchodzą od tej zasady i rozbudowują jądro, przenosząc do niego funkcje, które mogłyby być zaimplementowane w postaci procesów serwerowych?

5. Jakie są kroki związane z opracowaniem wariantu mobilnego systemu operacyjnego dla nowej platformy sprzętowej?

6. Opisz, w jaki sposób aplikacje współdziałają z systemem operacyjnym o architekturze mikrojądra.

7. Jakie są kroki związane z wykonaniem wywołania systemowego w systemie operacyjnym z mikrojądrem i systemie operacyjnym z jądrem monolitycznym?

8. Czy program emulowany na "obcym" procesorze może działać szybciej niż na "rodzimym"?

Alternatywą dla emulacji jest wiele środowisk aplikacji, który zawiera zestaw funkcji API. Naśladują one wywołanie funkcji bibliotecznych środowiska aplikacji, ale w rzeczywistości nazywają swoje biblioteki wewnętrzne. Nazywa się to tłumaczenie bibliotek... To jest pakiet czysto programowy.

Aby program napisany pod jednym systemem operacyjnym działał pod innym, konieczne jest zapewnienie bezkonfliktowej interakcji między metodami zarządzania procesami w różnych systemach operacyjnych.

Metody implementacji środowisk oprogramowania aplikacyjnego

W zależności od architektury:

1. Środowisko oprogramowania aplikacji w postaci aplikacji (górna warstwa natywnego jądra systemu operacyjnego).

Tryb działania użytkownika, tłumaczenie wywołań systemowych (wywołań API) na wywołania do „natywnego” systemu operacyjnego. Odpowiada klasycznemu wielowarstwowemu systemowi operacyjnemu (Unix, Windows).

2. Obecność kilku środowisk aplikacji, które działają jednakowo. Każdy w postaci osobnej warstwy rdzenia.

Uprzywilejowany tryb pracy. Interfejs API odnosi się do funkcji podstawowej (uprzywilejowanej) warstwy systemu operacyjnego. System odpowiada za rozpoznanie i adaptację wezwania. Wymaga dużej ilości zasobów. Do rdzenia zostaje przeniesiony zestaw cech identyfikujących do rozpoznawania.

3. Zasada mikrojądra.

Każde środowisko aplikacji jest zaprojektowane jako oddzielny serwer trybu użytkownika. Aplikacje korzystające z API dokonują wywołań systemowych do odpowiedniego środowiska aplikacji poprzez mikrojądro. Środowisko aplikacji przetwarza żądanie i zwraca wynik przez mikrojądro. Można używać funkcji mikrojądra. Możliwy jest wielokrotny dostęp do innych zasobów (podczas działania mikrojądra).

Interfejsy systemu operacyjnego

Interfejs systemu operacyjnego Jest systemem programowania aplikacji. Regulowane normami (POSIX, ISO).

1. Interfejs użytkownika- jest realizowany za pomocą specjalnych modułów oprogramowania, które tłumaczą żądania użytkownika w specjalnym języku poleceń na żądania kierowane do systemu operacyjnego.

Zbiór takich modułów nazywa się interpretator... Wykonuje leksykalne i parsowanie i albo wykonuje samo polecenie, albo przekazuje je do API.

2. API- zaprojektowany w celu zapewnienia aplikacjom zasobów systemu operacyjnego i implementacji innych funkcji. API opisuje zestaw funkcji, procedur należących do jądra i dodatków do systemu operacyjnego. Interfejs API wykorzystuje programy systemowe zarówno w systemie operacyjnym, jak i poza nim, korzystając z aplikacji za pośrednictwem środowiska programistycznego.

U podstaw udostępniania zasobów systemu operacyjnego ostatecznie leży przerwanie oprogramowania. Ich realizacja w zależności od systemu (wektorowe, tabelaryczne). Istnieje kilka możliwości implementacji API na poziomie systemu operacyjnego (najszybszy, najniższy), na poziomie programowania systemu (bardziej abstrakcyjne, mniej szybkie) oraz na poziomie zewnętrznej biblioteki procedur i funkcji (mały zestaw).

Interfejsy systemu operacyjnego Linux:

· Oprogramowanie (bez pośredników - rzeczywista realizacja wywołań systemowych);

· Wiersz poleceń (pośrednik - powłoka interpretera Shell, przekierowująca wywołanie);

· Graficzny (pośrednicy - Shell + powłoka graficzna).

System plików

System plików to część systemu operacyjnego zaprojektowana w celu zapewnienia użytkownikom wygodnego interfejsu do pracy z plikami i zapewnienia korzystania z plików przechowywanych na nośnikach zewnętrznych (dysk twardy + RAM) przez kilku użytkowników i procesy.

Według składu FS:

Zbiór wszystkich plików na dysku na wszystkich nośnikach,

Zestawy struktur danych wykorzystywanych do zarządzania plikami, takie jak katalogi plików, deskryptory plików, tabele alokacji wolnego i zajętego miejsca na dysku,

· Zestaw systemowych narzędzi programowych realizujących zarządzanie plikami, w szczególności: tworzenie, niszczenie, odczytywanie, zapisywanie, nazywanie, wyszukiwanie i inne operacje na plikach.

Jeden z atrybutów plików — nazwy plików — jest sposobem na identyfikację pliku przez użytkownika. W systemach, w których dozwolonych jest wiele nazw, do pliku przypisywany jest i-węzeł używany przez jądro systemu operacyjnego. Nazwy są różnie definiowane w różnych systemach operacyjnych.

Rozważ strukturę abstrakcyjnego wielojęzycznego, otwartego, kompilującego się systemu programowania i proces tworzenia aplikacji w tym środowisku (rys. 1.4).

Program w języku źródłowym (moduł źródłowy) jest przygotowywany przy pomocy edytorów tekstu i wprowadzany do translatora w postaci pliku tekstowego lub sekcji biblioteki.

Tłumaczenie programu źródłowego to procedura konwersji modułu źródłowego na pośrednią, tzw. formę obiektową. Tłumaczenie zazwyczaj obejmuje przetwarzanie wstępne (przetwarzanie wstępne) i kompilację.

Przetwarzanie wstępne to opcjonalna faza, która polega na analizie tekstu źródłowego, wydobyciu z niego dyrektyw preprocesora i ich wykonaniu.

Dyrektywy preprocesora to ciągi oznaczone znakami specjalnymi (zwykle %, #, &) zawierające skróty, symbole itp. konstrukcje zawarte w programie źródłowym przed jego przetworzeniem przez kompilator.

Dane do rozszerzenia tekstu źródłowego mogą być standardowe, zdefiniowane przez użytkownika lub zawarte w bibliotekach systemu operacyjnego.

Kompilacja jest zazwyczaj procesem wieloetapowym, który obejmuje następujące fazy:

Analiza leksykalna - sprawdzenie składu leksykalnego tekstu wejściowego i przetłumaczenie znaków złożonych (operatorów, nawiasów, identyfikatorów itp.) na pośrednią formę wewnętrzną (tabele, wykresy, stosy, hiperłącza), dogodną do dalszego przetwarzania;

rozbiór gramatyczny zdania- sprawdzenie poprawności konstrukcji użytych przez programistę w przygotowaniu tekstu;

analiza semantyczna- identyfikacja niezgodności typów i struktur zmiennych, funkcji i procedur;

Generowanie kodu obiektowego to ostatnia faza translacji.

Tłumaczenie (kompilacja) może odbywać się w różnych trybach, których instalacja odbywa się za pomocą klawiszy, parametrów lub opcji. Może to być na przykład wymagane tylko do wykonania fazy parsowania i tym podobnych.

Moduł obiektowy to moduł programu, który jest wynikiem kompilacji modułu źródłowego. Zawiera instrukcje maszynowe, słowniki, informacje serwisowe.

Moduł obiektowy nie działa, ponieważ zawiera nierozwiązane odniesienia do wywoływanych podprogramów biblioteki translatora (w ogólnym przypadku systemów programowania), które implementują funkcje wejścia/wyjścia, przetwarzanie zmiennych numerycznych i łańcuchowych, a także do innych programów lub narzędzi użytkownika pakietów aplikacji.

Ryż. 1.4. Abstrakcyjny wielojęzyczny, open source, system programowania kompilacji

Ładowanie modułu moduł programu w formie odpowiedniej do załadowania i wykonania. Budowa modułu ładującego jest realizowana za pomocą specjalnych narzędzi programowych - edytora linków, konstruktora zadań, konsolidatora, kolektora, których główną funkcją jest łączenie modułów obiektowych i ładujących w jeden moduł ładujący z późniejszym zapisem do biblioteka lub plik. Powstały moduł można później wykorzystać do budowy innych programów itp., co umożliwia budowanie oprogramowania.

Po złożeniu moduł ładujący jest umieszczany w bibliotece programu użytkownika lub bezpośrednio wysyłany do wykonania. Wykonanie modułu polega na załadowaniu go do pamięci RAM, ustawieniu go w pamięci i przekazaniu do niego sterowania. Obraz modułu ładującego w pamięci nazywany jest modułem bezwzględnym, ponieważ wszystkie polecenia komputerowe przyjmują tutaj swoją ostateczną formę i otrzymują adresy bezwzględne w pamięci. Tworzenie modułu bezwzględnego może być realizowane zarówno programowo, przetwarzając kody poleceń modułu przez program ładujący, jak i sprzętowo, stosując indeksowanie i oparcie poleceń modułu ładującego oraz doprowadzenie do wskazanych w nich adresów względnych. forma absolutna.

Nowoczesne systemy programowania pozwalają na wygodne przechodzenie z jednego etapu do drugiego. Odbywa się to dzięki obecności tzw. zintegrowanego środowiska programistycznego, które zawiera edytor tekstu, kompilator, linker, wbudowany debugger i w zależności od systemu lub jego wersji zapewnia programiście dodatkową wygodę pisania i debugowania programów .

Stworzenie pełnoprawnego środowiska aplikacyjnego, w pełni kompatybilnego ze środowiskiem innego systemu operacyjnego, to dość złożone zadanie, ściśle związane ze strukturą systemu operacyjnego. Istnieją różne opcje budowania środowisk z wieloma aplikacjami, różniące się zarówno cechami rozwiązań architektonicznych, jak i funkcjonalnością, która zapewnia różne stopnie przenośności aplikacji.

W wielu wersjach systemu UNIX OS translator środowiska aplikacji jest zaimplementowany jako zwykła aplikacja. W systemach operacyjnych zbudowanych przy użyciu koncepcji mikrojądra, takich jak Windows NT, środowiska aplikacji działają jako serwery trybu użytkownika. A w systemie operacyjnym OS/2, z jego prostszą architekturą, narzędzia do organizowania środowisk aplikacji są wbudowane głęboko w system.

Jedna z najbardziej oczywistych opcji implementacji wielu środowisk aplikacji opiera się na standardowej strukturze warstwowej systemu operacyjnego. Na ryc. 2.7 System operacyjny OS1 obsługuje, oprócz swoich "natywnych" aplikacji, aplikacje systemu operacyjnego OS2. W tym celu zawiera specjalną aplikację - środowisko oprogramowania aplikacyjnego, które tłumaczy interfejs "obcego" systemu operacyjnego - OS2 API na interfejs jego "natywnego" systemu operacyjnego - OS1 API.



Tryb niestandardowy

Tryb uprzywilejowany

Ryż. 2.7. Środowisko oprogramowania aplikacyjnego,
tłumaczenie wywołań systemowych

W innej implementacji wielu środowisk aplikacji system operacyjny ma wiele równorzędnych interfejsów API. W przykładzie pokazanym na ryc. W przykładzie 2.8 system operacyjny obsługuje aplikacje napisane dla OS1, OS2 i OS3. W tym celu aplikacje znajdują się bezpośrednio w przestrzeni jądra systemu.

interfejsy programistyczne wszystkich tych systemów operacyjnych: API OS1, API OS2 i
API OS3.


Tryb niestandardowy


Uprzywilejowany

Ryż. 2.8. Implementacja kompatybilności
w oparciu o wiele równorzędnych interfejsów API

W tej odmianie funkcje API odnoszą się do funkcji podstawowej warstwy systemu operacyjnego, która musi obsługiwać wszystkie trzy ogólnie niekompatybilne środowiska aplikacji. Różne systemy operacyjne zarządzają czasem systemowym na różne sposoby, używają innego formatu pory dnia, oddzielnego czasu procesora opartego na własnych algorytmach itp. Funkcje każdego interfejsu API są implementowane przez jądro, biorąc pod uwagę specyfikę odpowiedniego systemu operacyjnego, nawet jeśli mają podobny cel.

Inny sposób budowania wielu środowisk aplikacji opiera się na podejściu mikrojądra. Jednocześnie bardzo ważne jest oddzielenie podstawowych mechanizmów systemu operacyjnego, wspólnych dla wszystkich środowisk aplikacji, od funkcji wysokiego poziomu, specyficznych dla każdego ze środowisk aplikacji, które rozwiązują problemy strategiczne.

Zgodnie z architekturą mikrojądra, wszystkie funkcje systemu operacyjnego są implementowane przez serwery mikrojądra i trybu użytkownika. Ważne jest, aby każde środowisko aplikacji było zaprojektowane jako osobny serwer trybu użytkownika i nie zawierało podstawowych mechanizmów (rysunek 2.9). Aplikacje korzystające z API dokonują wywołań systemowych do odpowiedniego środowiska aplikacji poprzez mikrojądro. Środowisko aplikacji przetwarza żądanie, wykonuje je (być może przy użyciu podstawowych funkcji mikrojądra w celu uzyskania pomocy) i wysyła wynik z powrotem do aplikacji. W trakcie wykonywania żądania środowisko aplikacji musi z kolei mieć dostęp do podstawowych mechanizmów systemu operacyjnego zaimplementowanych przez mikrojądro i inne serwery systemu operacyjnego.

Aplikacje Serwery OS


Zwyczaj


Uprzywilejowany

Ryż. 2.9. Podejście mikrojądra
do implementacji wielu środowisk aplikacyjnych

Takie podejście do budowy środowisk wieloaplikacyjnych ma wszystkie zalety i wady architektury mikrojądra, a w szczególności:

bardzo łatwo jest dodawać i wykluczać środowiska aplikacji, co jest konsekwencją dobrej rozszerzalności systemów operacyjnych z mikrojądrem;

niezawodność i stabilność wyraża się w tym, że w przypadku awarii jednego ze środowisk aplikacji wszystkie pozostałe pozostają sprawne;

niska wydajność systemów operacyjnych z mikrojądrem wpływa na szybkość środowisk aplikacji, a co za tym idzie na szybkość wykonywania aplikacji.

Tworzenie kilku środowisk aplikacji w ramach jednego systemu operacyjnego do wykonywania aplikacji z różnych systemów operacyjnych to sposób, który pozwala na posiadanie jednej wersji programu i przenoszenie jej między systemami operacyjnymi. Wiele środowisk aplikacji zapewnia binarną zgodność danego systemu operacyjnego z aplikacjami napisanymi dla innych systemów operacyjnych. Dzięki temu użytkownicy mają większą swobodę wyboru systemów operacyjnych i łatwiejszy dostęp do wysokiej jakości oprogramowania.

Pytania autotestu

50. Jaka jest różnica między architekturą mikrojądra a tradycyjną architekturą systemu operacyjnego?

51. Dlaczego mikrojądro jest dobrze przystosowane do obsługi przetwarzania rozproszonego?

52. Co oznacza pojęcie środowiska wielu aplikacji?

53. Jaka jest istota metody tłumaczenia bibliotecznego?

Pytania kontrolne

54. Jaki jest termin używany w architekturze mikrojądra w odniesieniu do menedżerów zasobów umieszczonych w trybie użytkownika?

56. Dlaczego architektura mikrojądra systemu operacyjnego jest bardziej rozszerzalna niż klasyczny system operacyjny?

57. Czy architektura mikrojądra jest bardziej niezawodna niż architektura tradycyjna?

58. Podaj powód, dla którego wydajność architektury mikrojądra jest niższa niż wydajność tradycyjnego systemu operacyjnego.

60. Jakie znasz rodzaje kompatybilności?

61. Jak osiągnąć binarną kompatybilność dla procesorów o różnych architekturach?

62. Określ metodę, która pozwala poprawić wydajność komputera podczas wykonywania „obcego” pliku wykonywalnego.

63. Czy jedna metoda tłumaczenia biblioteki wystarczy do pełnej kompatybilności aplikacji?