Miksi rakennan kyvykkyyspohjaista mikroytimeä alusta asti
Käyttöjärjestelmät ovat ohjelmistojen monimutkaisimpia kokonaisuuksia. Ne hallitsevat muistia, ajoittavat laskentaa, ohjaavat laitteistoa ja valvovat suojausrajoja, jotka suojaavat jokaista koneella ajettavaa sovellusta.
Silti monet nykyisin käyttämämme käyttöjärjestelmät perustuvat arkkitehtonisiin ideoihin, jotka ovat peräisin vuosikymmenten takaa. Nämä järjestelmät ovat erittäin tehokkaita ja taistelussa testattuja, mutta niihin on myös kertynyt vuosikymmenten monimutkaisuus.
Tämä projekti tutkii toista suuntaa: rakennetaan moderni, kyvykkyyspohjainen mikroytimeen perustuva käyttöjärjestelmä alusta asti, vahvalla painotuksella eksplisiittiseen auktoriteettiin, minimaaliseen luotettuun laskentapohjaan (TCB) ja tiukkaan erotteluun ytimen ja käyttäjätilan välillä.
Tämän käyttöjärjestelmän nimi on EriX.
Miksi rakentaa vielä yksi käyttöjärjestelmä?⌗
Ensi silmäyksellä uuden käyttöjärjestelmän rakentaminen voi vaikuttaa tarpeettomalta. Kypsät järjestelmät kuten Linux, Windows ja BSD ovat jo olemassa ja pyörittävät miljardeja laitteita.
Nämä järjestelmät ovat kuitenkin kehittyneet historiallisten rajoitteiden alla. Ajan myötä niihin on kertynyt abstraktiokerroksia, yhteensopivuusmekanismeja ja perittyjä rajapintoja. Vaikka nämä ominaisuudet ovat usein välttämättömiä oikeissa tuotantojärjestelmissä, ne myös vaikeuttavat perustavanlaatuisesti erilaisten arkkitehtonisten ideoiden kokeilemista.
Tutkimuskäyttöjärjestelmät ovat jo pitkään tarkastelleet vaihtoehtoisia tapoja suunnitella käyttöjärjestelmiä. Mikroytimet, kyvykkyysjärjestelmät ja formaalisti verifioidut ytimet ovat osoittaneet, että on mahdollista rakentaa järjestelmiä, jotka ovat pienempiä, turvallisempia ja helpompia ymmärtää.
EriXin tavoitteena ei ole korvata olemassa olevia käyttöjärjestelmiä. Sen sijaan projekti tutkii, millainen moderni käyttöjärjestelmä voisi olla, jos suunnittelu aloitetaan ensimmäisistä periaatteista.
Mikroytimet ja luotettu laskentapohja⌗
Yksi EriXin keskeisistä ideoista on mikroytimeen perustuva arkkitehtuuri.
Perinteisissä monoliittisissa ytimissä monia palveluita sisällytetään suoraan ytimeen. Näihin kuuluvat usein:
- laiteajurit
- tiedostojärjestelmät
- verkkopinot
- prosessinhallinnan alijärjestelmät
Vaikka tämä lähestymistapa voi olla tehokas, se kasvattaa myös luotetun laskentapohjan (TCB) kokoa. TCB sisältää kaiken koodin, jonka on toimittava oikein, jotta järjestelmä pysyy turvallisena ja luotettavana.
Mikroytimet lähestyvät asiaa toisin.
Mikroytimeen jätetään vain kaikkein perustavimmat mekanismit, tyypillisesti:
- säikeiden ajoitus
- osoiteavaruuksien hallinta
- prosessien välinen viestintä (IPC)
- kyvykkyyksien hallinta
- keskeytysten ja poikkeusten käsittely
Kaikki muu ajetaan käyttäjätilassa, mukaan lukien ajurit, tiedostojärjestelmät ja korkeamman tason palvelut.
Tämä malli vähentää dramaattisesti luotettavan koodin määrää. Käyttäjätilan komponenttien virheet vaarantavat harvemmin koko järjestelmää, ja yksittäisiä komponentteja voidaan käynnistää uudelleen tai vaihtaa ilman, että ydin kaatuu.
Kyvykkyyspohjainen tietoturva⌗
Toinen EriXin keskeinen suunnitteluperiaate on kyvykkyyspohjainen tietoturva.
Useimmat käyttöjärjestelmät nojaavat vahvasti ympäristöauktoriteettiin. Tällaisissa järjestelmissä prosesseilla on usein implisiittinen pääsy resursseihin globaalien nimiavaruuksien, käyttäjäidentiteettien tai perittyjen oikeuksien perusteella.
Esimerkiksi prosessi voi avata tiedoston pelkästään siksi, että se tietää polun ja käyttöjärjestelmä päättää prosessilla olevan siihen oikeus.
Kyvykkyysjärjestelmät lähestyvät tätä toisin.
Kyvykkyys on väärentämätön tunniste, joka antaa pääsyn tiettyyn objektiin tietyin oikeuksin. Prosessi voi käyttää objektia vain, jos sillä on kyvykkyys, joka valtuuttaa kyseisen käytön.
Kyvykkyyksillä on useita tärkeitä ominaisuuksia:
- Ne esittävät auktoriteetin eksplisiittisesti.
- Ne voidaan siirtää prosessien välillä.
- Ne voivat rajoittaa operaatiot tarkasti määriteltyihin oikeuksiin.
Kyvykkyyspohjaisessa järjestelmässä auktoriteetti virtaa eksplisiittisten siirtojen kautta globaalien nimiavaruuksien sijaan. Tämä tekee järjestelmästä helpommin ymmärrettävän ja auttaa poistamaan kokonaisia haavoittuvuusluokkia.
Miksi Rust?⌗
Käyttöjärjestelmät kirjoitetaan perinteisesti C:llä tai assemblerilla. Nämä kielet tarjoavat tarkan hallinnan laitteistoon ja muistiin, mutta samalla niillä on helppo tehdä hienovaraisia virheitä.
Muistiturvallisuusvirheet, kuten vapautetun muistin käyttö, puskuriylivuodot ja datakilpailut, ovat historiallisesti olleet yksi suurimmista haavoittuvuuksien lähteistä järjestelmäohjelmistossa.
EriX on kirjoitettu pääosin Rustilla.
Rust tarjoaa vahvat takuut muistiturvallisuudesta ja mahdollistaa silti
matalan tason laitteistonhallinnan. Kielen omistajuusmalli estää monia
virheluokkia jo käännösaikana, ja eksplisiittiset unsafe-lohkot tekevät
potentiaalisesti vaarallisista operaatioista näkyviä ja auditoitavia.
Rustin käyttö ei poista kaikkia mahdollisia virheitä, mutta se nostaa merkittävästi järjestelmäohjelmoinnin turvallisuuden perustasoa.
Puhdastila-käyttöjärjestelmä⌗
Yksi EriX-projektin poikkeuksellinen piirre on sen puhdastilakehitysmalli.
Kaikki järjestelmän komponentit toteutetaan projektin sisällä. Ulkopuolista lähdekoodia ei kopioida eikä sisällytetä, eikä kolmannen osapuolen kirjastoja käytetä.
Tällä rajoitteella on useita tarkoituksia:
- Se varmistaa, että koko järjestelmä voidaan ymmärtää ja auditoida.
- Se välttää piiloriippuvuudet ja odottamattoman käyttäytymisen.
- Se pakottaa arkkitehtuuriratkaisut eksplisiittisiksi perittyjen sijaan.
Puhdastilakehitys tekee projektista myös opettavaisen harjoituksen. Jokainen alijärjestelmä käynnistyslataajasta muistinhallintaan on suunniteltava ja toteutettava tietoisesti.
Pitkän aikavälin tavoite: itseisännöinti⌗
Yksi EriXin pitkän aikavälin tavoitteista on itseisännöinti.
Järjestelmä on itseisännöivä, kun se pystyy rakentamaan oman lähdekoodinsa käyttäen työkaluja, jotka toimivat itse järjestelmässä.
EriXin kohdalla tämä tarkoittaa, että lopulta:
- Rust-kääntäjä toimii EriXissä
- rakennustyökalut toimivat EriXissä
- koko käyttöjärjestelmä voidaan kääntää natiivisti EriXin sisällä
Tämän virstanpylvään saavuttaminen vaatii monien infrastruktuurikerrosten toteuttamista, mukaan lukien tiedostojärjestelmät, prosessinhallinta ja POSIX-yhteensopiva käyttäjätilaympäristö.
Miksi dokumentoida matkaa?⌗
Käyttöjärjestelmän rakentaminen on pitkä ja monimutkainen prosessi. Monet kiinnostavimmista oivalluksista eivät näy valmiissa järjestelmässä, vaan matkan varrella tehdyissä päätöksissä, kompromisseissa ja virheissä.
Tämä blogi dokumentoi EriXin kehitystä sen edetessä. Tulevat kirjoitukset käsittelevät esimerkiksi:
- käynnistyskuvaformaatin suunnittelua
- kyvykkyysavaruuksien toteutusta
- IPC-järjestelmän rakentamista
- muistiauktoriteetin hallintaa
- käyttäjätilapalvelimien rakentamista
Tavoitteena on tehdä kehitysprosessista läpinäkyvä ja opettavainen.
Katse eteenpäin⌗
EriX on edelleen varhaisessa vaiheessa. Suuri osa järjestelmästä on vielä rakentamatta, ja monet suunnittelupäätökset varmasti elävät ajan myötä.
Ohjaavat periaatteet ovat kuitenkin jo selviä:
- minimaalinen ydin
- eksplisiittinen auktoriteetti
- kyvykkyyspohjainen tietoturva
- tiukka modulaarisuus
- puhdastilatoteutus
Seuraavassa kirjoituksessa tarkastelemme yhtä järjestelmän ydinideoista:
mitä kyvykkyyspohjaiset käyttöjärjestelmät ovat ja miksi niillä on väliä.