Skyddat läge

I datoranvändning är skyddat läge , även kallat skyddat virtuellt adressläge , ett driftläge för x86 -kompatibla centralprocessorer (CPU). Det tillåter systemprogramvara att använda funktioner som virtuellt minne , personsökning och säker multi-tasking som är utformad för att öka ett operativsystems kontroll över applikationsprogramvara .

När en processor som stöder x86-skyddat läge slås på börjar den köra instruktioner i verkligt läge , för att bibehålla bakåtkompatibilitet med tidigare x86-processorer. Skyddat läge kan endast aktiveras efter att systemprogramvaran har satt upp en deskriptortabell och aktiverat skyddsaktiveringsbiten (PE) i kontrollregistret control register 0 (CR0).

Skyddat läge lades först till x86 -arkitekturen 1982, med lanseringen av Intels 80286 ( 286) processor, och utökades senare med lanseringen av 80386 (386) 1985. På grund av förbättringarna som lagts till av skyddat läge, har blivit allmänt antagen och har blivit grunden för alla efterföljande förbättringar av x86-arkitekturen, även om många av dessa förbättringar, såsom tillagda instruktioner och nya register, också gav fördelar för det verkliga läget.

Historia

Intel 8086 , föregångaren till 286, designades ursprungligen med en 20- bitars adressbuss för sitt minne . Detta gjorde det möjligt för processorn att komma åt 2 20 byte minne, motsvarande 1 megabyte . På den tiden ansågs 1 megabyte vara en relativt stor mängd minne, så designers av IBM Personal Computer reserverade de första 640 kilobyte för användning av applikationer och operativsystem och de återstående 384 kilobyte för BIOS (Basic Input/Output System ) och minne för tilläggsenheter .

Eftersom kostnaden för minne minskade och minnesanvändningen ökade, blev begränsningen på 1 MB ett betydande problem. Intel hade för avsikt att lösa denna begränsning tillsammans med andra med lanseringen av 286.

286:an

Det ursprungliga skyddade läget, som släpptes med 286:an, användes inte i stor utsträckning; till exempel användes den av Coherent (från 1982), Microsoft Xenix (cirka 1984) och Minix . Flera brister såsom oförmågan att komma åt BIOS eller DOS-anrop på grund av oförmåga att växla tillbaka till verkligt läge utan att återställa processorn förhindrade utbredd användning. Acceptansen försvårades dessutom av det faktum att 286 endast tillät minnesåtkomst i 16 bitars segment via vart och ett av fyra segmentregister, vilket betyder att endast 4*2 16 byte , motsvarande 256 kilobyte , kunde nås åt gången. Eftersom ändring av ett segmentregister i skyddat läge gjorde att en 6-byte segmentbeskrivning laddades in i CPU:n från minnet, tog segmentregistrets laddningsinstruktion många tiotals processorcykler, vilket gjorde den mycket långsammare än på 8086:an; därför blev strategin att beräkna segmentadresser i farten för att komma åt datastrukturer större än 128 kilobyte (den kombinerade storleken på de två datasegmenten) opraktisk, även för de få programmerare som hade bemästrat det på 8086/8088 .

286 bibehöll bakåtkompatibilitet med sin föregångare 8086 genom att initialt gå in i verkligt läge vid start. Real mode fungerade praktiskt taget identiskt med 8086, vilket gjorde att den stora majoriteten av befintlig 8086- programvara kunde köras oförändrad på den nyare 286. Real mode fungerade också som ett mer grundläggande läge där skyddat läge kunde ställas in, vilket löste ett slags kyckling- och -äggproblem. För att komma åt den utökade funktionaliteten hos 286:an skulle operativsystemet sätta upp några tabeller i minnet som kontrollerade minnesåtkomst i skyddat läge, ställa in adresserna för dessa tabeller i några speciella register för processorn och sedan ställa in processorn i skyddat läge. Detta möjliggjorde 24-bitars adressering som gjorde att processorn kunde komma åt 2 24 byte minne, motsvarande 16 megabyte .

386:an

En Intel 80386 mikroprocessor

När 386:an släpptes 1985 åtgärdades många av de problem som förhindrade en utbredd användning av det tidigare skyddade läget. 386:an släpptes med en adressbussstorlek på 32 bitar, vilket möjliggör 2 32 byte minnesåtkomst, motsvarande 4 gigabyte . Segmentstorlekarna ökades också till 32 bitar, vilket innebär att hela adressutrymmet på 4 gigabyte kunde nås utan att behöva växla mellan flera segment. Utöver den ökade storleken på adressbuss- och segmentregistren tillkom många andra nya funktioner i syfte att öka driftsäkerheten och stabiliteten. Skyddat läge används nu i praktiskt taget alla moderna operativsystem som körs på x86-arkitekturen, som Microsoft Windows , Linux och många andra.

Dessutom lärde sig Intel av misslyckandena i 286-skyddat läge för att tillfredsställa behoven för fleranvändar-DOS, och Intel lade till ett separat virtuellt 8086-läge , vilket gjorde det möjligt att emulera flera virtualiserade 8086-processorer på 386. Hårdvara x86-virtualisering krävs för att virtualisera själva det skyddade läget fick dock vänta i ytterligare 20 år.

386 tillägg till skyddat läge

Med lanseringen av 386 lades följande ytterligare funktioner till i skyddat läge:

Gå in i och ur skyddat läge

Fram till släppet av 386, erbjöd skyddat läge inte en direkt metod för att växla tillbaka till verkligt läge när skyddat läge väl hade gått in. IBM utarbetade en lösning (implementerad i IBM AT ) som innebar att återställa CPU:n via tangentbordskontrollern och spara systemregistren, stackpekaren och ofta avbrottsmasken i realtidsklockkretsens RAM. Detta gjorde det möjligt för BIOS att återställa CPU:n till ett liknande tillstånd och börja exekvera kod före återställningen. [ förtydligande behövs ] Senare användes ett trippelfel för att återställa 286 CPU, vilket var mycket snabbare och renare än tangentbordskontrollmetoden (och inte beror på IBM AT-kompatibel hårdvara, men kommer att fungera på vilken 80286 CPU som helst i alla systemet).

För att gå in i skyddat läge måste Global Descriptor Table (GDT) först skapas med minst tre poster: en nolldeskriptor, en kodsegmentdeskriptor och datasegmentdeskriptor. I en IBM-kompatibel maskin A20-linjen (21:a adressraden) också vara aktiverad för att tillåta användning av alla adresslinjer så att CPU:n kan komma åt mer än 1 megabyte minne (endast de första 20 får användas efter uppstart, för att garantera kompatibilitet med äldre programvara skriven för Intel 8088-baserade IBM PC- och PC/XT- modeller). Efter att ha utfört dessa två steg måste PE-biten ställas in i CR0-registret och ett långt hopp måste göras för att rensa prefetch-ingångskön .



     
   
     


 
 ; MASM-program   ; gå in i skyddat läge (ställ in PE-bit)   mov  EBX  ,  CR0  ; spara kontrollregister 0 (CR0) till EBX   eller  EBX  ,  PE_BIT  ; ställ in PE-biten genom ELLER-ringning, spara till EBX   mov  CR0  ,  EBX  ; spara EBX tillbaka till CR0   ; rensa förhämtningskö;  (med fjärrhoppsinstruktion jmp)   jmp  CLEAR_LABEL  CLEAR_LABEL: 

När 386:an släpptes kunde skyddat läge lämnas genom att ladda segmentregistren med realmodvärden, inaktivera A20-linjen och rensa PE-biten i CR0-registret, utan att behöva utföra de initiala inställningsstegen som krävs med 286:an.

Funktioner

Skyddat läge har ett antal funktioner utformade för att förbättra ett operativsystems kontroll över applikationsprogramvara, för att öka säkerheten och systemstabiliteten. Dessa tillägg gör att operativsystemet kan fungera på ett sätt som skulle vara betydligt svårare eller till och med omöjligt utan ordentligt hårdvarustöd.

Privilegenivåer

Exempel på användning av behörighetsringningar i ett operativsystem som använder alla ringsignaler

I skyddat läge finns det fyra privilegienivåer eller ringsignaler , numrerade från 0 till 3, där ring 0 är den mest privilegierade och 3 är den minsta. Användningen av ringsignaler tillåter systemprogramvara att begränsa uppgifter från att komma åt data, anropsgrindar eller exekvera privilegierade instruktioner. I de flesta miljöer körs operativsystemet och vissa enhetsdrivrutiner i ring 0 och applikationer körs i ring 3.

Real mode applikationskompatibilitet

Enligt Intel 80286-programmerarens referensmanual ,

80286 förblir uppåtkompatibel med de flesta 8086 och 80186 applikationsprogram. De flesta 8086-applikationsprogram kan återkompileras eller återmonteras och köras på 80286 i skyddat läge.

För det mesta var den binära kompatibiliteten med real-mode-kod, möjligheten att komma åt upp till 16 MB fysiskt minne och 1 GB virtuellt minne , de mest uppenbara förändringarna för applikationsprogrammerare. Detta var inte utan sina begränsningar. Om en applikation använde eller förlitade sig på någon av teknikerna nedan, skulle den inte köras:

  • Segmentaritmetik
  • Privilegerade instruktioner
  • Direkt åtkomst till hårdvara
  • Skriva till ett kodsegment
  • Utför data
  • Överlappande segment
  • Användning av BIOS-funktioner, på grund av att BIOS-avbrotten reserveras av Intel

I verkligheten bröt nästan alla DOS- applikationsprogram mot dessa regler. På grund av dessa begränsningar introducerades virtuellt 8086-läge med 386. Trots sådana potentiella bakslag kan Windows 3.0 och dess efterföljare dra fördel av den binära kompatibiliteten med real mode för att köra många Windows 2.x ( Windows 2.0 och Windows 2.1x ) applikationer i skyddat läge, som kördes i verkligt läge i Windows 2.x.

Virtuellt 8086-läge

Med lanseringen av 386 erbjuder skyddat läge vad Intels manualer kallar virtuellt 8086-läge . Virtuellt 8086-läge är utformat för att tillåta kod som tidigare skrivits för 8086:an att köras oförändrad och samtidigt med andra uppgifter, utan att kompromissa med säkerheten eller systemstabiliteten.

Virtuellt 8086-läge är dock inte helt bakåtkompatibelt med alla program. Program som kräver segmentmanipulering, privilegierade instruktioner, direkt maskinvaruåtkomst eller använder självmodifierande kod kommer att generera ett undantag som måste betjänas av operativsystemet. Dessutom genererar applikationer som körs i virtuellt 8086-läge en fälla med hjälp av instruktioner som involverar input/output (I/O), vilket kan påverka prestandan negativt.

På grund av dessa begränsningar kan vissa program som ursprungligen utformades för att köras på 8086 inte köras i virtuellt 8086-läge. Som ett resultat av detta tvingas systemprogramvaran att antingen äventyra systemsäkerheten eller bakåtkompatibiliteten när man hanterar äldre programvara . Ett exempel på en sådan kompromiss kan ses med lanseringen av Windows NT , som minskade bakåtkompatibiliteten för "illa uppförda" DOS-program.

Segmentadressering

Virtuella segment av 80286

Verkligt läge

I verkligt läge pekar varje logisk adress direkt till en fysisk minnesplats, varje logisk adress består av två 16 bitars delar: Segmentdelen av den logiska adressen innehåller basadressen för ett segment med en granularitet på 16 byte, dvs ett segment kan starta på fysisk adress 0, 16, 32, ..., 2 20 -16. Offsetdelen av den logiska adressen innehåller en offset inuti segmentet, dvs den fysiska adressen kan beräknas som fysisk_adress : = segment_del × 16 + offset (om adressraden A20 är aktiverad), respektive (segment_del × 16 + offset) mod 2 20 (om A20 är avstängd) [ förtydligande behövs ] Varje segment har en storlek på 2 16 byte.

Skyddat läge

I skyddat läge ersätts segment_part av en 16-bitars väljare , där de 13 övre bitarna (bit 3 till bit 15) innehåller indexet för en post i en deskriptortabell . Nästa bit (bit 2) specificerar om operationen används med GDT eller LDT. De två lägsta bitarna (bit 1 och bit 0) i väljaren kombineras för att definiera privilegiet för begäran, där värdena 0 och 3 representerar den högsta respektive den lägsta rätten. Detta betyder att byteförskjutningen av deskriptorer i deskriptortabellen är densamma som 16-bitarsväljaren, förutsatt att de tre nedre bitarna nollställs.

Deskriptortabellposten definierar segmentets verkliga linjära adress, ett gränsvärde för segmentstorleken och några attributbitar (flaggor).

286

Segmentadressen inuti deskriptortabellposten har en längd på 24 bitar så varje byte i det fysiska minnet kan definieras som bunden av segmentet. Gränsvärdet inuti deskriptortabellposten har en längd på 16 bitar så segmentlängden kan vara mellan 1 byte och 2 16 byte. Den beräknade linjära adressen är lika med den fysiska minnesadressen.

386

Segmentadressen inuti deskriptortabellposten utökas till 32 bitar så att varje byte i det fysiska minnet kan definieras som bunden av segmentet. Gränsvärdet inuti deskriptortabellposten utökas till 20 bitar och kompletteras med en granularitetsflagga (G-bit, för kort):

  • Om G-bit är noll har gränsen en granularitet på 1 byte, dvs segmentstorleken kan vara 1, 2, ..., 2 20 byte.
  • Om G-bit är en gräns har en granularitet på 2 12 byte, dvs segmentstorleken kan vara 1 × 2 12 , 2 × 2 12 , ..., 2 20 × 2 12 byte. Om personsökning är avstängd är den beräknade linjära adressen lika med den fysiska minnesadressen. Om personsökning är på används den beräknade linjära adressen som indata för personsökning.

386-processorn använder också 32-bitars värden för adressoffset.

För att upprätthålla kompatibilitet med 286 skyddat läge lades en ny standardflagga (D-bit, för kort) till. Om D-biten för ett kodsegment är avstängd (0) kommer alla kommandon inuti detta segment att tolkas som 16-bitars kommandon som standard; om den är på (1) kommer de att tolkas som 32-bitars kommandon.

Struktur för inmatning av segmentbeskrivning

80286 Segmentbeskrivning
3 1 30 2 9 2 8 2 7 2 6 2 5 2 4 2 3 2 2 2 1 20 1 9 1 8 1 7 1 6 1 5 1 4 1 3 1 2 1 1 10 09 08 07 06 05 04 03 02 01 00
Bas[0..15] Gräns[0..15]
6 3 6 2 6 1 60 5 9 5 8 5 7 5 6 5 5 5 4 5 3 5 2 5 1 50 4 9 4 8 4 7 4 6 4 5 4 4 4 3 4 2 4 1 40 3 9 3 8 3 7 3 6 3 5 3 4 3 3 3 2
Oanvänd P DPL S X C R A Bas[16..23]
80386 Segmentbeskrivning
3 1 30 2 9 2 8 2 7 2 6 2 5 2 4 2 3 2 2 2 1 20 1 9 1 8 1 7 1 6 1 5 1 4 1 3 1 2 1 1 10 09 08 07 06 05 04 03 02 01 00
Bas[0..15] Gräns[0..15]
6 3 6 2 6 1 60 5 9 5 8 5 7 5 6 5 5 5 4 5 3 5 2 5 1 50 4 9 4 8 4 7 4 6 4 5 4 4 4 3 4 2 4 1 40 3 9 3 8 3 7 3 6 3 5 3 4 3 3 3 2
Base[24..31] G D 0 U Gräns[16..19] P DPL S X C R A Bas[16..23]

Var:

  • A är åtkomstbiten ;
  • R är den läsbara biten;
  • C (Bit 42) beror på X :
    • om X = 1 är C den överensstämmande biten och bestämmer vilka behörighetsnivåer som kan hoppa långt till detta segment (utan att ändra behörighetsnivån):
      • om C = 0 får endast kod med samma behörighetsnivå som DPL hoppa hit;
      • om C = 1 kan kod med samma eller lägre behörighetsnivå i förhållande till DPL hoppa hit.
    • om X = 0 så är C riktningsbiten :
      • om C = 0 så växer segmentet upp ;
      • om C = 1 så växer segmentet ner .
  • X är den körbara biten:
    • om X = 1 så är segmentet ett kodsegment;
    • om X = 0 är segmentet ett datasegment.
  • S är segmenttypbiten , som i allmänhet bör nollställas för systemsegment;
  • DPL är Descriptor Privilege Level ;
  • P är den nuvarande biten;
  • D är standardoperandstorleken ;
  • G är granularitetsbiten ;
  • Bit 52 i 80386-deskriptorn används inte av hårdvaran.

Personsökning

Vanlig metod för att använda personsökning för att skapa ett virtuellt adressutrymme
Personsökning (på Intel 80386) med sidstorlek på 4K

Förutom att lägga till virtuellt 8086-läge, lade 386 också till personsökning till skyddat läge. Genom personsökning kan systemprogramvara begränsa och kontrollera en uppgifts åtkomst till sidor, som är delar av minnet. I många operativsystem används personsökning för att skapa ett oberoende virtuellt adressutrymme för varje uppgift, vilket förhindrar en uppgift från att manipulera minnet i en annan. Personsökning gör det också möjligt att flytta sidor från det primära lagringsutrymmet och till ett långsammare och större sekundärt lagringsutrymme, till exempel en hårddisk . Detta gör att mer minne kan användas än fysiskt tillgängligt i primärminnet.

x86-arkitekturen tillåter kontroll av sidor genom två arrayer : sidkataloger och sidtabeller . Ursprungligen var en sidkatalog storleken på en sida, fyra kilobyte, och innehöll 1 024 sidkatalogposter (PDE), även om efterföljande förbättringar av x86-arkitekturen har lagt till möjligheten att använda större sidstorlekar. Varje PDE innehöll en pekare till en sidtabell. En sidtabell var också ursprungligen fyra kilobyte stor och innehöll 1 024 sidtabellposter (PTE). Varje PTE innehöll en pekare till den faktiska sidans fysiska adress och används endast när de fyra kilobyte sidorna används. Vid varje given tidpunkt kan endast en sidkatalog vara i aktiv användning.

Göra flera saker samtidigt

Genom användningen av ringsignaler, privilegierade anropsgrindar och Task State Segment (TSS), som introducerades med 286, möjliggjordes förebyggande multitasking på x86-arkitekturen. TSS tillåter allmänna register, segmentväljarfält och stackar att alla modifieras utan att påverka de för en annan uppgift. TSS tillåter också en uppgifts behörighetsnivå och I/O-portbehörigheter att vara oberoende av en annan uppgift.

I många operativsystem används inte alla funktioner i TSS. Detta beror vanligtvis på portabilitetsproblem eller på prestandaproblem som skapas med hårdvaruuppgiftsväxlar. Som ett resultat använder många operativsystem både hårdvara och mjukvara för att skapa ett multitasking-system.

Operativsystem

Operativsystem som OS/2 1.x försöker växla processorn mellan skyddat och verkligt läge. Detta är både långsamt och osäkert, eftersom ett program i verkligt läge lätt kan krascha en dator. OS/2 1.x definierar restriktiva programmeringsregler som tillåter ett Family API eller bundet program att köras i antingen verkligt eller skyddat läge. Vissa tidiga Unix- operativsystem, OS/2 1.x och Windows använde detta läge.

Windows 3.0 kunde köra real mode-program i 16-bitars skyddat läge; när man bytte till skyddat läge bestämde man sig för att bevara modellen med en privilegienivå som användes i verkligt läge, vilket är anledningen till att Windows-applikationer och DLL-filer kan koppla avbrott och göra direkt maskinvaruåtkomst. Det varade genom Windows 9x -serien. Om ett Windows 1.x- eller 2.x-program är korrekt skrivet och undviker segmentaritmetik, kommer det att köras på samma sätt i både verkligt och skyddat läge. Windows-program undviker i allmänhet segmentaritmetik eftersom Windows implementerar ett virtuellt minnesschema för programvara, flyttar programkod och data i minnet när program inte körs, så att manipulera absoluta adresser är farligt; program bör bara hålla handtag till minnesblock när de inte körs. Att starta ett gammalt program medan Windows 3.0 körs i skyddat läge utlöser en varningsdialogruta som föreslår att antingen köra Windows i verkligt läge eller att skaffa en uppdaterad version av programmet. Genom att uppdatera väluppfostrade program med hjälp av verktyget MARK med parametern MEMORY undviks denna dialog. Det är inte möjligt att ha vissa GUI-program som körs i 16-bitars skyddat läge och andra GUI-program körs i verkligt läge. I Windows 3.1 stöddes inte längre verkligt läge och kunde inte nås.

I moderna 32-bitars operativsystem används fortfarande virtuellt 8086-läge för att köra applikationer, t.ex. DPMI- kompatibla DOS-förlängningsprogram (genom virtuella DOS-maskiner ) eller Windows 3.x-applikationer (genom Windows på Windows- undersystemet) och vissa klasser av enhetsdrivrutiner (t.ex. för att ändra skärmupplösningen med hjälp av BIOS-funktionalitet) i OS/2 2.0 (och senare OS/2) och 32-bitars Windows NT , allt under kontroll av en 32-bitars kärna. Men 64-bitars operativsystem (som körs i långt läge ) använder inte längre detta, eftersom virtuellt 8086-läge har tagits bort från långt läge.

Se även

externa länkar