Kāpēc x86 CPU izmanto tikai divus no četriem “gredzeniem”?
Kad uzzināsiet vairāk par to, kā darbojas operētājsistēmas un aparatūra, ar ko viņi strādā, un mijiedarbojas viens ar otru, jūs varat būt pārsteigti, redzot, kas šķiet neparasti vai nepietiekami izmantoti “resursi”. Kāpēc ir tā, ka? Šodienas SuperUser Q&A ziņojumam ir atbilde uz ziņkārīga lasītāja jautājumu.
Šodienas jautājumu un atbilžu sesija mums dod pieklājību no SuperUser-Stack Exchange apakšnodaļas, kas ir kopienas orientēta Q & A tīmekļa vietņu grupa.
Foto pieklājīgi no Lemsipmatt (Flickr).
Jautājums
SuperUser lasītājs AdHominem vēlas uzzināt, kāpēc x86 CPU izmanto tikai divus no četriem gredzeniem:
Lieto tikai Linux un Windows balstītas x86 sistēmas Zvans 0 kodola režīmam un 3. gredzens lietotāja režīmā. Kāpēc pārstrādātāji pat izšķir četrus dažādus gredzenus, ja tie visi galu galā vienkārši izmanto divus no tiem? Vai tas ir mainījies ar AMD64 arhitektūru?
Kāpēc x86 CPU izmanto tikai divus no četriem gredzeniem?
Atbilde
SuperUser ieguldītājs Jamie Hanrahan ir atbilde mums:
Ir divi galvenie iemesli.
Pirmais ir tas, ka, lai gan x86 CPU piedāvā četrus atmiņas aizsardzības gredzenus, aizsardzības piedāvātā detalizācija ir tikai segmenta līmenī. Tas nozīmē, ka katru segmentu var iestatīt uz noteiktu gredzenu (privilēģijas līmeni) kopā ar citiem aizsargiem, piemēram, rakstīt invalīdiem. Taču nav pieejami daudzi segmentu apraksti. Lielākā daļa operētājsistēmu vēlas, lai atmiņas aizsardzība būtu daudz sīkāka, piemēram, atsevišķām lapām.
Tātad, ievadiet lapas tabulas aizsardzību. Lielākā daļa, ja ne visas, mūsdienīgās x86 operētājsistēmas vairāk vai mazāk ignorē segmentēšanas mehānismu (cik vien iespējams) un paļaujas uz aizsardzību, kas pieejama no zemās kārtas bitiem lapas tabulas ierakstos. Vienu no tiem sauc par “priviliģēto” bitu. Šis bits kontrolē, vai procesoram ir jābūt vienā no priviliģētajiem līmeņiem, lai piekļūtu lapai. “Priviliģētie” līmeņi ir PL 0, 1 un 2. Bet tas ir tikai viens bits, tāpēc, lai aizsargātu līmeni no vienas lapas pa lapām, pieejamo režīmu skaits, ciktāl tas attiecas uz atmiņas aizsardzību, ir tikai divi: lapa var būt pieejama no priviliģēta režīma vai ne. Tātad, tikai divi gredzeni. Lai katrai lapai būtu četri iespējamie gredzeni, katrai lappušu tabulas ierakstam viņiem būtu jābūt diviem aizsardzības bitiem, lai kodētu vienu no četriem iespējamiem zvana numuriem (tāpat kā segmenta deskriptoriem). Tomēr viņi to nedara.
Otrs iemesls ir operētājsistēmas pārnesamības vēlme. Tas nav tikai par x86; Unix mums mācīja, ka operētājsistēma var būt salīdzinoši pārnēsājama vairāku procesoru arhitektūrām un ka tā bija laba lieta. Un daži pārstrādātāji atbalsta tikai divus gredzenus. Neatkarīgi no arhitektūras vairākiem gredzeniem operētājsistēmas izpildītāji operētājsistēmas padarīja pārnēsājamākas.
Ir trešais iemesls, kas ir raksturīgs Windows NT izstrādei. NT dizaineriem (David Cutler un viņa komandai, kuru Microsoft nomāja no DEC Western Region Labs), bija plaša iepriekšēja pieredze VMS jomā; Patiešām, Cutler un daži no pārējiem bija VMS sākotnējie dizaineri. VAX procesoram, kuram tika izstrādāta VMS, ir četri gredzeni (VMS izmanto četrus gredzenus).
Bet komponenti, kas bija VMS Gredzeni 1 un 2 (Ierakstu pārvaldības pakalpojumi un CLI) netika iekļauti NT projektā. 2. gredzens VMS nebija īsti par operētājsistēmas drošību, bet gan par lietotāja CLI vides saglabāšanu no vienas programmas uz citu, un Windows nebija šīs koncepcijas; CLI darbojas kā parasts process. Attiecībā uz VMS 1. gredzens, RMS kodu 1. gredzens bija jāieslēdzas Zvans 0 diezgan bieži, un gredzenu pārejas ir dārgas. Izrādījās, ka ir daudz efektīvāka, lai vienkārši dotos Zvans 0 un jādara ar to, nevis daudz Zvans 0 pārejas 1. gredzens kods (atkal nav tas, ka NT jebkurā gadījumā ir kaut kas līdzīgs RMS).
Attiecībā uz to, kāpēc x86 ieviesa četrus gredzenus, bet operētājsistēmas tos neizmantoja, jūs runājat par operētājsistēmām ar daudz jaunāku dizainu nekā x86. Daudz x86 sistēmas programmēšanas iezīmes tika izstrādātas ilgi pirms NT vai patiesi Unix-ish kodolu ieviešanas, un viņi īsti nezināja, ko operētājsistēma izmantos. Līdz brīdim, kad mēs saņēmām lapotni par x86, mēs varējām ieviest patiesi Unix-ish vai VMS līdzīgus kodolus.
Mūsdienu x86 operētājsistēmas ne tikai ignorē segmentēšanu (tās tikai izveido C, D un S segmentus ar bāzes adresi 0 un lielumu 4 GB; dažreiz F un G segmenti tiek izmantoti, lai norādītu uz galvenajām operētājsistēmas datu struktūrām ), tie arī lielā mērā ignorē tādas lietas kā “uzdevuma valsts segmenti”. TSS mehānisms bija nepārprotami paredzēts vītņu konteksta maiņai, bet izrādās, ka tam ir pārāk daudz blakusparādību, tāpēc modernās x86 operētājsistēmas to dara „ar rokām”. Vienīgais laiks, kad x86 NT maina aparatūras uzdevumus, ir piemērots dažiem patiesi ārkārtējiem apstākļiem, piemēram, izņēmums par divkāršu kļūdu.
Attiecībā uz x64 arhitektūru, daudzas no šīm neizmantotajām funkcijām tika atstātas ārpus. Savam kredītam AMD tiešām runāja ar operētājsistēmas kodolu komandām un jautāja, kas viņiem nepieciešams no x86, ko viņiem nebija vajadzīgs vai ko negribēja, un to, ko viņi vēlētos pievienot. Segmenti uz x64 eksistē tikai tādā veidā, ko varētu saukt par „liellopu formu”, uzdevuma stāvokļa pārslēgšana neeksistē utt., Un operētājsistēmas turpina izmantot tikai divus gredzenus.
Vai kaut kas jāpievieno paskaidrojumam? Skaņas izslēgšana komentāros. Vai vēlaties lasīt vairāk atbildes no citiem tehnoloģiju gudriem Stack Exchange lietotājiem? Apskatiet pilnu diskusiju pavedienu šeit.