Când aflați mai multe despre cum funcționează și interacționează sistemele de operare și hardware-ul pe care le rulează, puteți fi surprins să vedeți ceea ce pare a fi ciudățenii sau subutilizarea „resurselor”. De ce este asta? Postarea de astăzi a SuperUser Q&A are răspunsul la întrebarea unui cititor curios.
Sesiunea de Întrebări și Răspunsuri de astăzi ne vine prin amabilitatea SuperUser - o subdiviziune a Stack Exchange, un grup de site-uri web de întrebări și răspunsuri bazat pe comunitate.
Fotografie oferită de Lemsipmatt (Flickr) .
Intrebarea
Cititorul SuperUser AdHominem vrea să știe de ce procesorii x86 folosesc doar două din patru inele:
Sistemele x86 bazate pe Linux și Windows folosesc numai Inel 0 pentru modul kernel și Inelul 3 pentru modul utilizator. De ce distinge procesoarele chiar patru inele diferite, dacă oricum ajung să le folosească pe două? S-a schimbat acest lucru odată cu arhitectura AMD64?
De ce CPU-urile x86 folosesc doar două din patru inele?
Răspunsul
Contribuitorul SuperUser Jamie Hanrahan are răspunsul pentru noi:
Există două motive principale.
Primul este că, deși procesoarele x86 oferă patru inele de protecție a memoriei, granularitatea protecției oferite prin aceasta este doar la nivel de segment. Adică, fiecare segment poate fi setat la un anumit inel (nivel de privilegiu) împreună cu alte protecții, cum ar fi dezactivarea scrierii. Dar nu sunt disponibili atât de mulți descriptori de segmente. Majoritatea sistemelor de operare ar dori să aibă o granularitate mult mai fină de protecție a memoriei, cum ar fi ... pentru pagini individuale.
Deci, introduceți protecția bazată pe tabelul de pagini. Majoritatea, dacă nu toate, sistemele de operare moderne x86 mai mult sau mai puțin ignoră mecanismul de segmentare (oricât de mult pot oricum) și se bazează pe protecția disponibilă din biții de ordin scăzut din intrările din tabelul de pagini. Unul dintre acestea se numește bitul „privilegiat”. Acest bit controlează dacă procesorul trebuie să fie sau nu într-unul din nivelurile „privilegiate” pentru a accesa pagina. Nivelurile „privilegiate” sunt PL 0, 1 și 2 . Dar este doar un bit, deci la nivelul de protecție pagină cu pagină, numărul de „moduri” disponibile în ceea ce privește protecția memoriei este doar de două: o pagină poate fi accesată din modul non-privilegiat sau nu. Prin urmare, doar două inele. Pentru a avea patru inele posibile pentru fiecare pagină, ar trebui să aibă doi biți de protecție în fiecare intrare a tabelului de pagini pentru a codifica unul dintre cele patru numere posibile de inel (la fel ca și descriptorii segmentelor). Cu toate acestea, nu o fac.
Celălalt motiv este dorința de portabilitate a sistemului de operare. Nu este vorba doar de x86; Unix ne-a învățat că un sistem de operare ar putea fi relativ portabil pentru mai multe arhitecturi de procesoare și că este un lucru bun. Și unele procesoare acceptă doar două inele. Prin faptul că nu depinde de mai multe inele din arhitectură, implementatorii de sisteme de operare au făcut sistemele de operare mai portabile.
Există un al treilea motiv, specific dezvoltării Windows NT. Designerii NT (David Cutler și echipa sa, pe care Microsoft i-a angajat în afara DEC Western Region Labs) au avut o experiență anterioară vastă în VMS; de fapt, Cutler și câțiva dintre ceilalți se numărau printre designerii originali ai VMS. Iar procesorul VAX pentru care a fost conceput VMS are patru inele (VMS folosește patru inele).
Dar componentele care rulează în VMS’s Inelele 1 și 2 (Serviciile de gestionare a înregistrărilor și, respectiv, CLI) au fost lăsate în afara designului NT. Inelul 2 în VMS nu se referea cu adevărat la securitatea sistemului de operare, ci mai degrabă la păstrarea mediului CLI al utilizatorului de la un program la altul, iar Windows nu avea acel concept; CLI rulează ca un proces obișnuit. Cât despre VMS Inelul 1 , codul RMS în Inelul 1 a trebuit să sune Inel 0 destul de des, iar tranzițiile inelului sunt scumpe. Sa dovedit a fi mult mai eficient la care să mergi Inel 0 și să se termine cu el mai degrabă decât să aibă o mulțime de Inel 0 tranziții în cadrul Inelul 1 cod (din nou, nu că NT are ceva de genul RMS oricum).
În ceea ce privește motivul pentru care x86 a implementat patru inele în timp ce sistemele de operare nu le-au folosit, vorbiți despre sisteme de operare cu un design mult mai recent decât x86. Multe dintre caracteristicile de programare a sistemului x86 au fost proiectate cu mult înainte ca NT sau kernelurile adevărate Unix-ish să fie implementate pe acesta și nu știau cu adevărat ce va folosi sistemul de operare. Abia când am primit paginarea pe x86 am putut implementa nuclee adevărate Unix-ish sau VMS.
Nu numai că sistemele de operare moderne x86 ignoră în mare măsură segmentarea (doar configurează segmentele C, D și S cu o adresă de bază de 0 și dimensiunea de 4 GB; segmentele F și G sunt uneori folosite pentru a indica structurile de date cheie ale sistemului de operare ), de asemenea, ignoră în mare măsură lucruri precum „segmentele de stare a sarcinilor”. Mecanismul TSS a fost conceput clar pentru comutarea contextului firelor, dar se dovedește a avea prea multe efecte secundare, astfel încât sistemele de operare moderne x86 o fac „manual”. Singura dată când x86 NT modifică sarcinile hardware este pentru anumite condiții cu adevărat excepționale, cum ar fi o excepție cu dublă eroare.
În ceea ce privește arhitectura x64, multe dintre aceste caracteristici dezafectate au fost lăsate deoparte. Spre meritul lor, AMD a vorbit cu echipele de kernel ale sistemului de operare și a întrebat ce au nevoie de la x86, ce nu au nevoie sau nu și ce ar dori să fie adăugat. Segmentele de pe x64 există doar în ceea ce s-ar putea numi formă vestigială, comutarea stării sarcinilor nu există etc., iar sistemele de operare continuă să folosească doar două inele.
Aveți ceva de adăugat la explicație? Sună în comentarii. Doriți să citiți mai multe răspunsuri de la alți utilizatori ai Stack Exchange? Consultați aici firul complet de discuție .