POLITECHNIKA CZĘSTOCHOWSKA
LABORATORIUM SYSTEMÓW OPERACYJNYCH KOMPUTERÓW
PROCESOR 80386
RAFAŁ SCHERER
czwartek 1830
1
WSTĘP
Wprowadzony w 1985 roku 80386 jest pierwszym 32-bitowym procesorem firmy Intel. Jest on następcą procesora 80286 wyposażonym, między innymi , w 32-bitowe rejestry, co pociągnęło rozszerzenie listy instrukcji o nowe rozkazy operujące na tych rejestrach. Ponadto wprowadzono następujące ulepszenia:
w trybie wirtualnym stosowanie 32-bitowych adresów ( 4 GB pamięci )
w trybie wirtualnym segment może być umieszczony w dowolnym miejscu przestrzeni adresów liniowych i może mieć wielkość do 4 GB
może wykonywać programy w trybie wirtualnym 8086
poza mechanizmem segmentacji posiada mechanizm stronicowania
większa częstotliwość zegara ( 25, 33 i 40 Mhz )
współpraca z zewnętrzną pamięcią podręczną ( dzięki sterownikowi 82385 )
dynamiczna zmiana rozmiaru danej (16/32 bity) przesyłanej po szynie dla ułatwienia współpracy z układami i/o
sprzętowe mechanizmy testowania
Zachowana jest zgodność programowa (na poziomie kodu wynikowego ) z pozostałymi układami rodziny iAPX 86.
2
SYGNAŁY STERUJĄCE
386 przesyła dane po 32-bitowej szynie danych. Sygnały byte enable BE#0-BE#3 są zdekodowanymi sygnałami A0,A1 , sygnalizują które bajty magistrali danych są przesyłane w danym cyklu. Sygnały RD# i WR# 8086 są zastąpione sygnałem W/R#. Sygnał M/IO# oznacza czy w danym cyklu aktywna ma być pamięć czy porty we/wy. ADS# jest odpowiednikiem sygnału ALE z 8086 i oznacza, że ważny adres i sygnały sterujące są aktualnie na magistrali. Po aktywacji sygnału NA# procesor wysyła na magistralę następny adres.
Rys.1 Wyprowadzenia 80386
Jest to adresowanie potokowe ( address pipelining ) służące zmniejszeniu wymagań na czas dostępu do pamięci dzięki wcześniejszemu wysłaniu adresu. BS16# zapewnia dynamiczną zmianę szerokości magistrali danych. Jeśli wybrane urządzenie jest 16-bitowe to uaktywnia ten sygnał i przesłanie odbywa się po dolnej części szyny danych ( jeśli przesyłamy 32 bity to trwa to wtedy 2 razy dłużej ).
Sygnał READY# jest utrzymywany w stanie niskim przez urządzenie , które nie jest gotowe do przesłania ( na przykład przez zbyt duży czas dostępu ). Wejście CLK służy do podłączenia sygnału zegara systemowego o częstotliwości 2x większej niż częstotliwość zegara procesora. Wyjście LOCK# blokuje dostęp innych urządzeń do współnych zasobów.
Kolejne porty urządzeń 8-bitowych nie mogą znajdować się pod kolejnymi adresami, ponieważ port o adresie nieparzystym musiałby być podłączony do górnej połowy szyny danych. Wiele urządzeń współpracuje z 8-bitową szyną danych, więc w komputerach PC/386 zastosowano specjalny konwerter cyklu szyny , który zamienia 16-bitowe cykle przesłania adresowane do ośmiobitowych pamięci i urządzeń i/o na 8-bitowe. W procesorze i486 sprawa jest prostsza ze względu na istnienie sygnału BS8#.
W trybie rzeczywistym adres rzeczywisty jest tworzony przez dodanie do 20-bitowego adresu bazowego segmentu 16-bitowego przemieszczenia ( offset ). W większości przypadków wynik dodawania będzie liczbą 20-bitową, jednakże dla niektórych wartości adresu bazowego i przemieszczenia może wystąpić przeniesienie z najbardziej znaczącego bitu ( wynikiem jest liczba 21-bitowa ). Ponieważ szyna adresowa procesora 8086 jest 20-bitowa, najstarszy bajt jest ignorowany. Adres zawija się wokół adresu 0. W procesorach od 286 wzwyż , najstarszy bit nie jest ignorowany ale wysyłany linią A20. Procesory te mogą zaadresować w trybie rzeczywistym 1MB+64kB-16B. W komputerach AT przewidziano możliwość maskowania linii A20. Sterownik klawiatury generuje specjalny sygnał zerujący bit A20, którego stan można zmieniać programowo poprzez wysłanie odpowiedniego rozkazu do sterownika klawiatury. Dezakywacja tego sygnału powoduje zwiększenie przestrzeni adresowej o 64kB ( High Memory Area )
3
ARCHITEKTURA
80386 zawiera osiem 32-bitowych rejestrów ogólnego przeznaczenia ( general purpose register ), sześć rejestrów segmentów ( segment register ), rejestry systemowe ( GDTR, IDTR, LDTR, TR ), rejstr wskaźnika instrukcji, rejestr znaczników, rejestry sterujące, uruchomieniowe ( debug registers ) i testowe ( test registers ).
bit31 15 7 0
EAX |
|
AH |
AL |
EBX |
|
BH |
BL |
ECX |
|
CH |
CL |
EDX |
|
DH |
DL |
ESI |
|
SI |
|
EDI |
|
DI |
|
EBP |
|
BP |
|
ESP |
|
SP |
bit15 0 31 15 0
CS |
EIP |
|
IP |
DS |
EFLAGS |
|
FLAGS |
ES |
|
|
|
SS |
CR0 |
|
MSW |
FS |
|
CR2 |
|
GS |
|
CR3 |
bit47 0
GDTR |
|
IDTR |
|
LDTR |
|
TR |
bit15 0
bit31 0 31 0
DR0 |
|
TR6 |
DR1 |
|
TR7 |
DR2 |
||
DR3 |
||
DR6 |
||
DR7 |
ZARZĄDZANIE ZASOBAMI PAMIĘCI
4
W 80386 zaimplementowano funkcje zarządzania pamięcią. Obsługa pamięci wirtualnej jest bardzo ułatwiona dzięki zastosowaniu mechanizmu stronicowania. Pozwala on na wymianę małych porcji danych pomiędzy pamięcią operacyjną, a pamięcią wirtualną w pamięci masowej.
Rys.2 Sposób translacji adresu w 80386
Ale najpierw należy omówić mechanizm segmentacji.
SEGMENTACJA
Podawany w programie adres logiczny składa się z selektora przestrzeni logicznej oraz adresu efektywnego ( przesunięcia w przestrzeni logicznej ). Adres logiczny składający się z selektora i przemieszczenia jest inaczej nazywany dalekim wskaźnikiem adresowym.
Rys.3 Mechanizm segmentacji
Selektor zazwyczaj nie jest podawany bezpośrednio w kodzie rozkazu . Jest on przechowywany w jednym z sześciu rejestrów segmentowych : CS, DS, ES, FS, GS, SS. Wybór określonego segmentu jest dokonywany typu operacji generującej dostęp do pamięci. Na przykład kod progamu jest odczytywany z wykorzystaniem rejestru segmentu programu CS, operacje na stosie z wykorzystaniem rejestru SS. Standardowe przypisanie rejestru segmentu do określonej operacji można zmienić podając przed rozkazem jeden z sześciu specjalnych prefiksów wymuszającego wykorzystanie danego rejestru. Umożliwia to szybką zmianę przestrzeni adresowej bez konieczności ładowania za każdym razem rejestru segmentu.
Przemieszczenie względem bazowego adresu segmentu jest otrzymywane w wyniku zsumowania zawartości rejestru bazowego ( baza przemieszczenia ), rejestru indeksowego i przemieszczenia podanego bezpośrednio w kodzie rozkazu.
Adres liniowy powstaje z adresu logicznego z wykorzystaniem specjalnych tablic, w których są umieszczone deskryptory segmentów (w trybie rzeczywistym wystarczy pomnożyć selektor przez 16 ). Deskryptor jest 8-bajtowym rekordem opisującym m.in. położenie , wielkość i atrybuty dostępu.
15 8 7 4 0
Adres bazowy segmentu 31…24 |
G |
D |
0 |
AVL |
Wielkość 19..16 |
||||
P |
DPL |
S |
typ |
A |
Adres bazowy segmentu 23…16 |
||||
Adres bazowy segmentu 23…16 |
|||||||||
Wielkość segmentu 15…0 |
Rys.4 Format deskryptora segmentu pamięci w 386
Oznaczenia pól z Rys.4:
G ( granularity ) - ziarnistość
D ( Default ) - długość słowa
AVL ( Available to Software ) - pole dostępne dla programu
P ( Present ) - segment obecny
DPL ( Descriptor Privilige Level ) - poziom ochrony opisywanego segmentu
S - rodzaj deskryptora :
0 - segment danych , tylko odczytywanie
1 - segment danych , odczyt i zapis
2 - segment danych rozszerzalny w dół, tylko odczyt
3 - segment danych rozszerzalny w dół, odczyt i zapis
4 - segment kodu , tylko wykonywanie
5 - segment kodu , wykonywanie i odczytywanie
6 - zgodny segment kodu , tylko wykonywanie
7 - zgodny segment kodu , wykonywanie i odczytywanie
A - segment użyty
Selektor wskazuje więc bezpośrednio na deskryptor segmentu , a pośrednio na segment. Deskryptory segmentów są umieszczane w pamięci kolejno tworząc tablice deskryptorów. Wykonywany program ma dostęp do dwóch tablic deskryptorów : globalnej tablicy deskryptorów GDT i lokalnej tablicy deskryptorów LDT . Stosowanie dwóch tablic deskryptorów umożliwia realizację ochrony pamięci zadań w systemach wielozadaniowych . W systemie może istnieć wiele LDT , zwykle po jednej na każde zadanie. Format selektora w trybie wirtualnym jest następujący :
15 3 2 1 0
Numer deskryptora |
TI |
RPL |
TI - ( Table Indicator ) wskaźnik tablicy
RPL - ( Requestor's Privilige Level ) poziom ochrony zadania żądającego dostępu
Rozmiar logicznej przestrzeni adresowej określa się jako maksymalną wielkość pamięci widzianą przez pojedyncze zadanie. Ponieważ numer deskryptora ma 13 bitów, w jednej tablicy może być 8192 deskryptorów. Program ma dostęp do tablicy GDT i swojej LDT, może więc korzystać z 16384 segmentów. Maksymalna długość segmentu wynosi 4GB ( przesunięcie 32 bity ) , tak więc pamięć wirtualna widziana przez zadanie wynosi : 16kB * 4GB = 64TB. Oczywiście jedynie część tej pamięci może być odwzorowana w danej chwili w rzeczywistej pamięci operacyjnej.
W danej chwili program ma dostęp jedynie do 6 segmentów ( tyle jest rejestrów segmentów ). Ponieważ powiązanie pomiędzy selektorem , a odpowiednim segmentem określa deskryptor zapisany w pamięci, wydawałoby się, że odwołania do pamięci są bardzo nieefektywne , gdyż każde wyliczenie adresu wymaga skorzystania z informacji zawartej w deskryptorze. W celu zoptymalizowania procesu adresowania wprowadzono ukryte rejestry deskryptorów stanowiące szybką podręczną pamięć deskryptorów. Są one ładowane automatycznie danymi z odpowiedniego deskryptora podczas umieszczania selektora w rejestrze segmentu , a następnie procesor korzysta z ich zawartości podczas przy wyliczaniu adresu, bez konieczności odwoływania się do deskr. w pamięci. Takie rozwiązanie jest efektywne gdyż z reguły programy rzadko zmieniają zawartość rejestrów segmentów tzn. całe ciągi sąsiadujących ze sobą instrukcji dotyczą danych w jednym lub kilku segmentach.
Położenie tablic deskryptorów GDT i aktualnie używanej LDT jest określone poprzez zawartość specjalnych rejestrów procesora - odpowiednio rejestru globalnej tablicy deskryptorów GDTR ( Global Descriptor Table Register ) i rejestru lokalnej tablicy deskryptorów LDTR ( Local Descriptor Table Register ). Rejestry te pokazane są na rys.5. Części dostępne programowo otoczone są podwójną linią.
31 0 15 0
GDTR |
Adres bazowy |
Wielkość |
|||||||||
|
15 0 |
|
|
|
|
||||||
LDTR |
Selektor |
|
Adres bazowy |
Wielkość |
Atrybuty |
Rys. 5 Format rejestrów tablic deskryptorów
W każdym z rejestrów jest umieszczony liniowy adres początku odpowiedniej tablicy oraz wielkość tablicy. Struktura rejestru LDTR jest analogiczna do rejestru segmentu : zawiera część ukrytą , ładowaną automatycznie , będącą odpowiednikiem rejestru deskryptora segmentu. Wynika to z faktu , że lokalna tablica deskryptorów sama stanowi odrębny segment , należący do grupy tzw. segmentów systemowych. Jako segment ma swój deskryptor , który musi być umieszczony w globalnej tablicy deskryptorów. Rejestr LDTR jest traktowany w czasie ładowania podobnie jak rejestr segmentu. Tablica LDT , podobnie jak GDT może zawierać do 8192 deskryptorów tzn jej długość nie może przekraczać 64KB. Sposób translacji logicznego adresu bajtu w przykładowym segmencie pamięci opisanym przez deskryptor w LDT pokazany był na Rys.3.
STRONICOWANIE
Podobnie jak mechanizm segmentacji również mechanizm stronicowania posługuje się w procesie translacji tablicami systemowymi zawartymi w pamięci i odbywa się zupełnie niezależnie od segmentacji.
Rys.6 Mechanizm stronicowania
Adresy tablic GDT i LDT umieszczone w odpowiednich rejestrach dotyczą liniowej przestrzeni adresowej. Mechanizm segmentacji nic nie wie o fizycznym położeniu tych tablic w pamięci. Z kolei adresy tablic, z których korzysta mechanizm stronicowania są adresami fizycznymi.
Zarówno liniowa jak i fizyczna przestrzeń adresowa obejmuje 4GB. Stronicowanie polega na wyróżnieniu w obu tych przestrzeniach bloków pamięci bloków pamięci - stron o ustalonej długości 4KB, rozmieszczonych sekwencyjnie począwszy od adresu 0 i przyporządkowaniu stronom w przestrzeni liniowej stron w przes. fizycznej. Każda z tych przestrzeni składa się z 232/212 = 220 = 1M stron. Położenie strony jest jednoznacznie określone za pomocą 20-bitowego numeru. W 80386 wprowadzono dwupoziomową organizację tablic translacji. Wprowadzono dwa rodzje tablic : tablice stron zawierające numery stron w fizycznej przestrzeni adresowej oraz katalogi tablic stron .Elementy tablicy stron i elementy katalogu stron mają identyczny format :
31 12 11 9 8 7 6 5 4 3 2 1 0
Numer strony |
AVL |
0 |
0 |
D |
A |
0 |
0 |
U/S |
R/W |
P |
Rys.7 Format elementu katalogu i tablicy stron
AVL - dostępne dla programu
D - strona zmieniona
A - strona użyta
U/S - poziom ochrony użytkowy / systemowy
R/W - tylko odczyt / dozwolony zapis
P - strona obecna
Podobnie jak ma to miejsce w przypadku segmentacji, również przy stronicowaniu używany jest specjalny rejestr mikroprocesora do wskazania położenia tablic systemowych w pamięci . Rolę tę pełni rejestr sterujący CR3 zawierający numer strony , na której zapisano katalog tablic stron. W celu przyspieszenia procesu translacji adresu liniowego na fizyczny 386 wyposażono w wewnętrzną pamięć asocjacyjną elementów tablic stron , w której przechowywane są ostatnio używane opisy 32 stron.
MECHANIZMY ZABEZPIECZANIA
Mechanizmy ochrony obszarów pamięci są stosowane zarówno przy segmentacji jak i przy stronicowaniu . Pierwszym sposobem ochrony jest separacja zadań. Polega ona na tym że każde zadanie dysponuje własną wirtualną przestrzenią adresową.Drugi mechanizm ochrony związany jest z wprowadzeniem poziomów ochrony:
PL=0
jądro
Informacja o poziomie ochrony danego segmentu zawarta jest w polu DPL jego deskryptora.Oprócz poziomu uprzywilejowania w deskryptorze segmentu są umieszczone atrybuty określające charakter dopuszczalnych odwołań .
Wyróżnia się dwa poziomy ochrony stron : poziom systemowy i poziom użytkowy. Poziom systemowy strony oznacza ,że jest ona dostępna tylko z poziomów ochrony 0, 1 i 2, a więc przeznaczonych dla oprogramowania systemowego. Z kolei strona mająca użytkowy poziom ochrony jest dotępna ze wszystkich programów , również wykonyjących się na poziomie 3. Iformacja o poziomie ochrony strony jest zawarta w elementach katalogów i tablic stron.
5
LITERATURA
Badźmirowski K., Pieńkoś J. : Układy i systemy mikroprocesorowe , część 1
Bronson Gary, Silver H. : 32-Bit Mikroprocessors
Goczyński R. , Tuszyński M. : Mikropocesory 80286, 80386 i i486
Protopapas D.A. : Microcomputer hardware design
Stępień C. : Mikroprocesory firmy intel