Beskyttet modus

﻿Beskyttet modus er en av modusene en prosessor basert på IA-32-arkitekturen eller x86-64-arkitekturen kan operere i. I motsetning til den eldre reelle modusen arvet fra de første x86-prosessorene, tilbyr beskyttet modus støtte for multitasking med mekanismer som beskytter programmene mot hverandre, virtuelt minne, sideveksling og en andre mekanismer som bidrar til et mer sikkert system.

Selv om beskyttet modus på mange måter er hovedmodusen til IA32-prosessorer, starter de fortsatt opp i reell modus ettersom de fortsatt prøver å være kompatible med Intel 8086. Operativsystemer som kan utnytte beskyttet modus må selv konfigurere prosessoren for dette og bytte fra reell modus til beskyttet modus.

I x86-64-arkitekturen har lang modus overtatt for beskyttet modus som prosessorens hovedmodus. Lang modus har arvet noen av konseptene fra beskyttet modus.

Historikk
Intel 8086-prosessoren fra 1978 var den første i det som skulle vise seg å bli en veldig suksessrik serie med prosessorer basert på samme arkitektur. Det var en 16 bit-prosessor med en adressebuss på 20 biter, noe som betyr at den kunne adressere opp til 1 megabyte med minne. Dette var på den tiden ansett for å være mye.

Med sin 80286-prosessor introduserte Intel i 1982 en rekke forbedringer i sin x86-arkitektur. Prosessoren var fortsatt 16-biters, men fikk en adressebuss som gjorde det mulig å adressere opp til 16 megabyte med minne. For å få til dette introduserte de beskyttet modus. Denne utgaven manglet mange av de egenskapene beskyttet modus fikk i senere prosessorer og ble lite benyttet grunnet kompatibilitetsproblemer.

Først når Intel 80386, den første 32-biters prosessoren i x86-familien, kom i 1985, ble beskyttet modus fullutviklet. Bortsett fra noen utvidelser som gir er større fysisk adresserom, har beskyttet modus vært det samme siden da, selv om hver nye generasjon av x86-prosessorer har fått nye egenskaper ellers.

Privilegienivåer
Beskyttet modus har fire privilegienivåer, såkalte ringer. De er nummerert 0 til 3, hvor 0 er den mest privilegerte. Operativsystemet kjører i ring 0, mens brukerprogrammene kjører i ring 3. I ring 0 har man tilgang til alt, inkludert spesielle instruksjoner for å styre prosessoren. Ring 3 har kun tilgang til det mer privilegerte ringer har gitt tilgang til.

Et sett med regler styrer hvordan ringene forholder seg til hverandre og er blant mekanismene som sørger for at ulike programmer og systemkomponenter ikke roter til hverandres data. Alle ringene har en egen stakk, noe som bidrar til at mindre privilegert kode ikke kan rote til stakken for de mer privilegerte.

I sidevekslingsmekanismen skilles det bare mellom ring 0, 1 og 2 på den ene siden, og ring 3 på den andre.

Minneadressering
I beskyttet modus skilles det mellom tre typer minneadresser: logiske, lineære og fysiske. Skillet mellom disse er henholdsvis segmentering og sideveksling.

Logisk minneadresse og segmentering
Logiske minneadresser er den adressetypen de fleste instruksjoner opererer med og som vanlige programmer forholder seg til. En logisk minneadresse består av to deler, et segment på 16 bit og et offset på 32 bit. Disse har noenlunde samme mening som minneadressene i reell modus og benytter de samme registrene, men segmentene har fått noen nye egenskaper og er mer fleksible. Mens det i reell modus finnes et fast antall segmenter (65536) med fast lengde og som starter på hver 16. byte, så er det opp til operativsystemet å definere segmentene slik det vil ha dem. Segmentene kan starte hvor som helst i minnet og ha en hvilken som helst lengde. Det skilles det mellom kode- og datasegmenter. I tillegg angis det hvilken ring som har tilgang til segmentet. Det må eksistere minst to segmenter, et kodesegment og et datasegment, begge for ring 0.

Mens segmentene i reell modus bare var en del av minneadressen, er de i beskyttet modus en av de konseptene som gjør modusen beskyttet. Prosesser i de høyere ringene kan ikke lese fra eller skrive til segmenter med lavere ringnummer, ei heller har de tilgang til minneområder utenfor de segmentene operativsystemet har definert for prosessen. Ved å holde kode- og datasegmentene adskilt i minnet unngår man også krasj som oppstår når programmet ved en feil overskriver sin egen maskinkode med data. Datasegmenter kan også være skrivebeskyttet og kodesegmenter kan beskyttes mot lesing.

Offsetet er som i reell modus relativ til starten av segmentet. Dersom segmentet på en eller annen måte er gitt, så angir man bare offsetet som minneadresse. Når man legger sammen offsetet og startadressen for segmentet får man en 32-biters lineær adresse.

Det er vanlig at operativsystemer setter starten på segmentene til 0 og lengden til maksimalt. Dette gjør at offset blir lik den lineære adressen og at programmene slipper å tenke på segmenter.

Lineær adresse og paging
Dersom sideveksling (paging) ikke er aktivert av operativsystemet, vil den lineære adressen tilsvare den 32-biters fysiske adressen. Aktiveres derimot sideveksling, må den gjennom en omfattende oversettelsesprosess som gir mange muligheter, inkludert virtuelt minne. Denne oversettelsen kan gjøre at flere lineære adresser tilsvarer den samme fysiske adressen, eller at en lineær adresse ikke tilsvarer noen fysisk adresse i det hele tatt. Å forsøke å lese fra eller skrive til en lineær adresse som ikke tilsvarer en fysisk adresse vil gjøre at et unntak, en såkalt sidefeil (page fault), oppstår.

Sideveksling deler minnet inn i sider (pages) på 4 kB, 2 MB eller 4 MB. Det er mulig å adressere sider på 4 kB og 4 MB, eller 4 kB og 2 MB, samtidig. Alle sider starter på en fysisk adresse som er et helt antall ganger sidens størrelse. Etterhvert har det oppstått tre algoritmer for sideveksling som kan velges ved å sette tilhørende kontrollflagg.

En IA32-prosessor inneholder et sidekatalogbaseregister (page directory base register) som inneholder den fysiske adressen til en tabell med 1024 elementer. De 10 første (mest signifikante) bitene i den 32 biter lange lineære adressen brukes til å indeksere ett av disse elementene.

Dersom elementet angir en sidestørrelse på 4 kB, så angir det også en 20-biters fysisk adresse til en sidetabell (page table). Sidetabellen i seg selv utgjør en side på 4 kB, derfor er de nederste 12 bitene i den fysiske adressen alltid null og trenger ikke lagres. Sidetabellen inneholder også 1024 elementer og de neste 10 bitene i den lineære adressen brukes til å plukke ut én. Fra det elementet hentes det ut en ny 20-biters fysisk adresse til en side. Disse 20 bitene settes så foran de siste 12 bitene fra den lineære adressen for å få en fysiske adresse på 32 biter.

Hvis sidekatalogelementet derimot angir en sidestørrelse på 4 MB, så hentes bare 10 biter ut av elementet. Disse kombineres med de siste 22 bitene fra den lineære adressen for å danne den fysiske adressen.

Felter i elementene i sidekatalogen og sidetabellen angir blant annet om sidene de peker til kan skrives til, om bare operativsystemet har tilgang til de eller om sidene er tilgjengelig i minnet. De to første egenskapene gir beskyttelse som delvis overlapper det segmentering gir, mens sistnevnte er grunnlaget for virtuelt minne.

PAE
Intels Pentium Pro-prosessorer introduserte muligheten for å benytte 36 biters fysiske adresser. Dette ble kalt physical address extension. For å forvandle en 32-biters lineær adresse til en 36-biters fysisk adresse ble størrelsen på elementene i sidekatalogen og sidetabellene doblet slik at de fikk plass til større fysiske adresser. For å kompensere for at det ble plass til færre elementer i katalogen og tabellene, ble det introdusert enda et nivå. I tillegg ble den store sidestørrelsen redusert fra 4 til 2 MB. Sidekatalogbaseregisteret peker ikke lenger til en sidekatalog, men en tabell med pekere til fire sidekataloger.

Når sideveksling med PAE var aktivert, benyttes de to første bitene i den lineære adressen til å hente adressen til én av sidekatalogene fra en tabell med pekere til sidekataloger. Deretter benyttes de neste 9 bitene i den lineære adressen til å hente ut et element fra sidekatalogen. Hvis elementet angir 4 kB sider, så inneholder det også en peker til en sidetabell. De neste 9 bitene i den lineære adressen indekserer et element i sidetabellen. Til slutt kombineres 24 biter fra dette sidetabellelementet med de siste 12 bitene i den lineære adressen for å få en fysisk adresse på 36 biter.

Når sidekatalogelementet angir 2 MB-sider, angir det også 15 biter som kombineres med de siste 21 bitene i den lineære adressen for å danne den fysiske adressen.

Ettersom de lineære adressene fortsatt er 32 biter brede, så kan ikke en prosess ha tilgang til med enn 4 GB minne til enhver tid, men ved å endre på sidetabellene kan den få tilgang til forskjellige deler av opptil 64 GB alt ettersom. Forskjellige prosesser med egne sidetabeller vil også kunne spre seg utover det mye større fysiske adresserommet, selv om hver enkel prosess fortsatt har et lineært adresserom på 4 GB.

PSE
Senere ble det introdusert enda en måte å omforme lineære adresser til 36-biters fysiske adresser. Denne metoden benytter bare sider på 4 MB. Som vanlig benyttes de første 10 bitene i den lineære adressen til å hente ut et element fra sidekatalogen. 14 biter fra dette elementet kombineres med de gjenværende 22 bitene i den lineære adressen for å danne den fysiske adressen. Denne metoden kalles page size extension.

Fysiske adresser
De fysiske adressene tilsvarer de adressene som sendes på adressebussen og som alle andre enheter i datamaskinen forholder seg til. Grunnet de to oversettelsene de logiske adressene har vært igjennom, kan etterfølgende logiske adresser ende opp som vidt forskjellige fysiske adresser.

Selv om programmer vanligvis forholder seg til logiske adresser, er det enkelte ting som angis med fysiske adresser. Selv om minneadresser stort sett er adresser i RAM, så er det enkelte andre enheter som også har tatt plass i dette adresserommet. Både BIOS og grafikkort er såkalt minnemappede enheter som gjør sine dataområder tilgjengelig for prosessoren som om det var RAM. For at operativsystemet skal kunne kommunisere med disse enhetene, er det viktig at det setter opp segmentene og sidetabellene slik at det finner igjen deres adresseområder i det logiske adresserommet. I tillegg er det selvfølgelig viktig at disse minneområdene ikke blir gitt til programmer som om de var vanlig RAM.

Avbruddshåndtering
Når en prosessor som kjører i beskyttet modus mottar et avbrudd, slår den opp i en tabell definert av operativsystemet som blant annet angir de ulike avbruddsrutinens adresser, i form av et segment og et offset. Segmentet rutinen ligger i angir hvilke ring den skal kjøres i. Prosessoren vil deretter avbryte det kjørende programmet dersom det kjørte i den samme ringen som  skal håndtere avbruddet, eller en mer privilegert ring. Dersom prosessoren bytter til en mer privilegert ring, byttes også stakken ut. Når avbruddsrutinen er ferdig, går prosessoren tilbake til programmet som ble avbrutt. Ring og stakk endres tilbake om de ble endret før avbruddsrutinen.

Avbruddshåndteringen kan også kobles opp mot prosessorens multitaskingmekanisme. I stedet for å kalle opp en avbruddsrutine, vil prosessoren bytte til en angitt prosess eller tråd opprettet av operativsystemet for å ta seg av det aktuelle avbruddet.

Avbrudd kan genereres av prosessoren selv, av det kjørende programmet, eller av eksterne enheter. De som kommer fra prosessoren selv kalles unntak. Disse signaliserer at et problem har oppstått med utføringen av et program og gir operativsystemet en mulighet til å rydde opp. Dersom operativsystemet feiler mens det håndterer et unntak, vil den få et nytt unntak som (double fault). Feiler operativsystemet igjen, restartes prosessoren automatisk.

Programmer kan med vilje utløse både unntak og vanlige avbrudd gjennom spesielle instruksjoner. Tabellen som angir adressen til avbruddet setter også krav til hvilke ringer som kan kalle opp avbruddsrutinen på denne måten.

Den tredje typen unntak er de som sendes til prosessoren fra andre enheter i datamaskinen. De brukes ofte for å signalisere at nye data er klare på en inndataenhet eller at en utdataenhet er klar til å motta mer. Ettersom disse kan komme helt uavhengig av hva prosessoren holder på med, kan disse deaktiveres av privilegert kode slik at de ikke forstyrrer kjørende program i en kritisk fase. Det vil for eksempel skape problemer om prosessoren begynte å behandle et innkommende avbrudd før operativsystemet har gjort klar avbruddstabellen.

Multitasking

I beskyttet modus finnes det maskinvarestøtte for multitasking som er tett knyttet opp mot mekanismene brukt for segmentering. Hver prosess (eller tråd) får tildelt et lite segment som brukes til å lagre innholdet i de generelle registrene, segmentregistrene og et utvalg andre registre slik de var når prosessen sist kjørte. Når man utfører et lovlig kall til et slikt segment, vil prosessoren automatisk skrive ut registrenes nåværende verdi til segmentet til den kjørende prosessen og laste verdiene fra den nye prosessens segment tilbake inn i registrene. Den nye prosessen vil dermed fortsette der den slapp.

Det er fullt mulig å implementere multitasking uten å benytte denne innebygde mekanismen for å bytte mellom prosesser. Dette gir mer fleksibilitet. Et operativsystem må likevel fylle inn minst ett task-segment dersom det vil skje bytter mellom ringer, ettersom stakkene for de forskjellige ringene defineres der.

Virtuell 8086 modus

Virtuell 8086 modus er egentlig ingen modus på linje med reell eller beskyttet modus, men en mekanisme for å emulere 8086 prosessoren mens prosessoren kjører i beskyttet modus. Dette gjør det mulig å kjøre programmer skrevet for reell modus sammen med andre programmer i et multitasket, beskyttet miljø. Det er opp til operativsystemet å ta seg av problemet med at 8086-programmer ikke er vant til multitasking og tror det har eksklusiv tilgang til hele systemet.

Kilder
 
X86-adresseringsmodi