Waarom gebruiken x86-CPU's slechts twee van de vier ringen?
Wanneer u meer te weten komt over de manier waarop besturingssystemen en de hardware die zij op het werk gebruiken en met elkaar communiceren, zich misschien verbaast over wat er lijkt aan rariteiten of onderbenutting van "bronnen". Waarom is dat? De SuperUser Q & A-post van vandaag heeft het antwoord op de vraag van een nieuwsgierige lezer.
De Question & Answer-sessie van vandaag komt tot ons dankzij SuperUser - een onderdeel van Stack Exchange, een gemeenschapsgedreven groep van Q & A-websites.
Foto met dank aan Lemsipmatt (Flickr).
De vraag
SuperUser-lezer AdHominem wil weten waarom x86-CPU's slechts twee van de vier ringen gebruiken:
Op Linux en Windows gebaseerde x86-systemen gebruiken alleen Ring 0 voor kernelmodus en Ring 3 voor gebruikersmodus. Waarom kunnen processors zelfs vier verschillende ringen onderscheiden als ze er uiteindelijk toch maar twee gebruiken? Is dit veranderd met de AMD64-architectuur?
Waarom gebruiken x86-CPU's maar twee van de vier ringen?
Het antwoord
SuperUser-bijdrager Jamie Hanrahan heeft het antwoord voor ons:
Er zijn twee hoofdredenen.
De eerste is dat, hoewel de x86-CPU's vierringen geheugenbescherming bieden, de granulariteit van de bescherming die daardoor wordt geboden slechts op het niveau van het per segment is. Dat wil zeggen, elk segment kan worden ingesteld op een specifieke ring (bevoegdheidsniveau) samen met andere beveiligingen zoals schrijf-uitgeschakeld. Maar er zijn niet veel segmentdescriptors beschikbaar. De meeste besturingssystemen willen een veel fijnere korreligheid van geheugenbescherming, zoals ... voor afzonderlijke pagina's.
Voer daarom op paginatabel gebaseerde beveiliging in. De meeste, zo niet alle, moderne x86-besturingssystemen negeren het segmenteringsmechanisme min of meer (voor zover ze dat kunnen hoe dan ook) en vertrouwen op de bescherming die beschikbaar is uit de low-orderbits in paginatabelitems. Een daarvan wordt het "bevoorrechte" bit genoemd. Deze bit bepaalt of de processor zich in een van de "bevoorrechte" niveaus moet bevinden om toegang tot de pagina te krijgen. De "bevoorrechte" niveaus zijn PL 0, 1 en 2. Maar het is maar één bit, dus op het niveau van pagina voor pagina is het aantal beschikbare "modi" voor geheugenbescherming slechts twee: een pagina kan toegankelijk zijn vanuit de niet-geprivilegieerde modus, of niet. Vandaar, slechts twee ringen. Om voor elke pagina vier mogelijke ringen te hebben, moeten deze twee beveiligingsbits hebben in elk paginatabelitem om een van de vier mogelijke belnummers te coderen (net als de segmentdescriptors). Ze doen dat echter niet.
De andere reden is een verlangen naar draagbaarheid van het besturingssysteem. Het gaat niet alleen om x86; Unix heeft ons geleerd dat een besturingssysteem relatief draagbaar kan zijn naar meerdere processorarchitecturen, en dat het een goede zaak was. En sommige processoren ondersteunen slechts twee ringen. Door niet afhankelijk te zijn van meerdere ringen in de architectuur, maakten de implementeerders van het besturingssysteem de besturingssystemen draagbaarder.
Er is een derde reden die specifiek is voor Windows NT-ontwikkeling. De ontwerpers van NT (David Cutler en zijn team, die door Microsoft waren ingehuurd bij DEC Western Region Labs) hadden uitgebreide eerdere ervaring met VMS; in feite waren Cutler en enkele anderen de oorspronkelijke ontwerpers van VMS. En de VAX-processor waarvoor VMS is ontworpen, heeft vier ringen (VMS gebruikt vier ringen).
Maar de componenten die in VMS's draaiden Ringen 1 en 2 (Record Management Services en de CLI, respectievelijk) werden weggelaten uit het NT-ontwerp. Ring 2 in VMS ging het niet echt om de beveiliging van besturingssystemen, maar om het behoud van de CLI-omgeving van de gebruiker van het ene programma naar het andere, en Windows had dat concept niet; de CLI werkt als een gewoon proces. Wat betreft VMS's Ring 1, de RMS-code in Ring 1 moest inbellen Ring 0 redelijk vaak en ringovergangen zijn duur. Het bleek veel efficiënter om gewoon naar toe te gaan Ring 0 en er mee klaar zijn in plaats van veel Ring 0 overgangen binnen de Ring 1 code (nogmaals, niet dat NT sowieso zoiets als RMS heeft).
Waarom x86 vier ringen implementeerde terwijl besturingssystemen ze niet gebruikten, dan heb je het over besturingssystemen met een veel recenter ontwerp dan x86. Veel van de systeemprogrammafuncties van x86 zijn ontworpen lang voordat NT of echte Unix-hash-kernels erop waren geïmplementeerd en ze wisten niet echt wat het besturingssysteem zou gebruiken. Pas toen we op x86 begonnen te piepen, konden we echte Unix-achtige of VMS-achtige kernels implementeren.
Niet alleen negeren moderne x86-besturingssystemen segmentatie grotendeels (ze stellen alleen de C-, D- en S-segmenten in met een basisadres van 0 en een grootte van 4 GB; F- en G-segmenten worden soms gebruikt om te wijzen naar belangrijke datastructuren van het besturingssysteem ), negeren ze ook grotendeels dingen als "taakstatussegmenten". Het TSS-mechanisme was duidelijk ontworpen voor thread context-switching, maar het blijkt te veel bijwerkingen te hebben, dus moderne x86-besturingssystemen doen dit "met de hand". De enige keer dat x86 NT hardwaretaken wijzigt, is voor sommige werkelijk uitzonderlijke omstandigheden, zoals een dubbele foutuitzondering.
Met betrekking tot de x64-architectuur zijn veel van deze niet meer gebruikte functies weggelaten. Het is op zich een goede zaak dat AMD daadwerkelijk met de kernteams van het besturingssysteem heeft gesproken en vroeg wat ze nodig hadden van x86, wat ze niet nodig hadden of niet wilden, en wat ze zouden willen toevoegen. Segmenten op x64 bestaan alleen in wat een rudimentaire vorm kan worden genoemd, taakomschakeling bestaat niet enz. En besturingssystemen blijven slechts twee ringen gebruiken.
Heb je iets toe te voegen aan de uitleg? Geluid uit in de reacties. Wilt u meer antwoorden van andere technisch onderlegde Stack Exchange-gebruikers lezen? Bekijk hier de volledige discussiethread.