Varför använder x86-processorer bara två av fyra ringar?
När du lär dig mer om hur operativsystem och hårdvara de kör på jobbet och interagera med varandra kan du bli förvånad över att se vad som verkar vara oddities eller underutnyttjande av "resurser" som uppstår. Varför är det så? Dagens SuperUser Q & A inlägg har svaret på en nyfiken läsarens fråga.
Dagens Question & Answer-session kommer till oss med tillstånd av SuperUser-en indelning av Stack Exchange, en community-driven gruppering av Q & A-webbplatser.
Foto med tillstånd av Lemsipmatt (Flickr).
Frågan
SuperUser-läsare AdHominem vill veta varför x86-processorer bara använder två av fyra ringar:
Linux och Windows-baserade x86-system använder bara Ring 0 för kärnläge och Ring 3 för användarläge. Varför skiljer processorer till och med fyra olika ringar om de slutar bara använda två av dem ändå? Har detta ändrats med AMD64-arkitekturen?
Varför använder x86-processorer bara två av fyra ringar?
Svaret
SuperUser-bidragsgivaren Jamie Hanrahan har svaret för oss:
Det finns två huvudskäl.
Det första är att även om x86-CPU: erna erbjuder fyra ringar av minnesskydd, är skyddsgraden av skydd som erbjuds därmed endast på segmentnivå. Det vill säga, varje segment kan sättas till en viss ring (privilegierivå) tillsammans med andra skydd som skrivfunktion. Men det finns inte så många segmentbeskrivningar tillgängliga. De flesta operativsystem skulle vilja ha en mycket finare granularitet av minnesskydd, som ... för enskilda sidor.
Så skriv in sidobasbaserat skydd. De flesta, om inte alla, moderna x86-operativsystem mer eller mindre ignorerar segmenteringsmekanismen (så mycket som de kan ändå) och förlita sig på det skydd som finns tillgängligt från de lågordnade bitarna i sidobordsposter. En av dessa kallas den "privilegierade" biten. Denna bit styr huruvida processorn måste vara i någon av de "privilegierade" nivåerna för att komma åt sidan. De "privilegierade" nivåerna är PL 0, 1 och 2. Men det är bara en bit, så vid sidan om skyddsnivå är antalet "lägen" som är tillgängliga vad gäller minnesskydd bara två: En sida kan vara tillgänglig från icke-privilegierat läge, eller inte. Därför bara två ringar. För att få fyra möjliga ringar för varje sida, skulle de behöva ha två skyddsbitar i varje sidobordstangent för att koda ett av fyra möjliga ringsignaler (precis som segmentbeskrivningarna). Men det gör de inte.
Den andra anledningen är en önskan om operativsystemportabilitet. Det handlar inte bara om x86; Unix lärde oss att ett operativsystem skulle kunna vara relativt bärbart för flera processor arkitekturer, och att det var en bra sak. Och vissa processorer stöder bara två ringar. Genom att inte bero på flera ringar i arkitekturen gjorde operativsystemets implementatörer operativsystemen mer bärbara.
Det finns en tredje anledning som är specifik för Windows NT-utveckling. NT: s designers (David Cutler och hans team, som Microsoft hyrde från DEC Western Region Labs) hade omfattande tidigare erfarenheter av VMS; Faktum är att Cutler och några av de andra var bland VMS: s ursprungliga designers. Och VAX-processorn för vilken VMS konstruerades har fyra ringar (VMS använder fyra ringar).
Men de komponenter som sprang i VMS: s Ringar 1 och 2 (Record Management Services respektive CLI) lämnades ut ur NT-designen. Ring 2 i VMS handlade inte riktigt om operativsystemsäkerhet utan snarare om att bevara användarens CLI-miljö från ett program till det andra, och Windows hade inte det begreppet. CLI körs som en vanlig process. Vad gäller VMS: s Ring 1, RMS-koden i Ring 1 var tvungen att ringa in Ring 0 ganska ofta, och ringövergångar är dyra. Det visade sig vara mycket mer effektivt att bara gå till Ring 0 och gör det med det istället för att ha mycket Ring 0 övergångar inom Ring 1 kod (igen, inte att NT har något som RMS ändå).
När det gäller varför x86 implementerade fyra ringar medan operativsystem inte använde dem, talar du om operativsystem med långt senare design än x86. Många av systemprogrammeringsfunktionerna i x86 konstruerades länge innan NT eller sanna Unix-ish-kärnor implementerades på den, och de visste inte riktigt vad operativsystemet skulle använda. Det var inte förrän vi fick sökning på x86 att vi skulle kunna implementera sanna Unix-ish eller VMS-liknande kärnor.
Inte bara ignorerar moderna x86-operativsystem i stor utsträckning segmentering (de ställer bara in C-, D- och S-segmenten med en basadress på 0 och en storlek på 4 GB; F och G-segmenten används ibland för att peka på viktiga operativsystems datastrukturer ), ignorerar de också stort sett saker som "uppgiftsstatssegment". TSS-mekanismen var tydligt utformad för trådkonfiguration, men det visar sig ha många biverkningar, så moderna x86-operativsystem gör det "för hand". Den enda gången x86 NT ändrar maskinvaruuppgifter är för några riktigt exceptionella förhållanden, som ett undantag för dubbla fel.
När det gäller x64-arkitekturen var många av dessa oanvända funktioner utelämnade. Till sin kredit talade AMD faktiskt till operativsystemkärnelag och frågade vad de behövde från x86, vad de inte behövde eller inte ville ha, och vad de skulle vilja lägga till. Segment på x64 existerar endast i det som kan kallas vestigial form, uppgift om tillståndsstatusomkoppling existerar inte etc., och operativsystem fortsätter att använda bara två ringar.
Har du något att lägga till förklaringen? Ljud av i kommentarerna. Vill du läsa mer svar från andra tech-savvy Stack Exchange-användare? Kolla in hela diskussionsgängan här.