Redox - Unix-szerű, mikrokerneles operációs rendszer Rust-ban

A Redox egy Rust-ban írt, UNIX-szerű operációs rendszer. Célja a Rust innovációit felhasználva egy modern mikrokernel és teljes alkalmazáskészlet létrehozása.

Redox is a general purpose operating system and surrounding ecosystem written in pure Rust. Our aim is to provide a fully functioning Linux alternative, without the bad parts.

We have modest compatibility with Linux syscalls, allowing Redox to run many Linux programs without virtualization.

We take inspiration from Plan9, Minix, and BSD. We are trying to generalize various concepts from other systems, to get one unified design. We will speak about this some more in the Design chapter.

Redox runs on real hardware today.

TODO: Make this better.

Jellemzői:

  • mikrokernel dizájn
  • a legtöbb funkció Rust-ban implementált
  • opcionális grafikus felhasználói felületet tartalmaz
  • az eszközmeghajtó programok user space-ben futnak
  • tartalmazza a megszokott UNIX parancsokat
  • ZFS fájlrendszer támogatás (folyamatban)
  • stb.

Weboldala itt, kézikönyv itt.

Hozzászólások

Hatan fejlesztik?
"Our aim is to provide a fully functioning Linux alternative, without the bad parts."
Csak azt tudom mondani, hogy hajrá!
--
Tertilla; Tisztelem a botladozó embert és nem rokonszenvezem a tökéletessel! Hagyd már abba!; DropBox

Ígéretnek szép, pár év múlva rákukkantunk, él-e még a projekt?

--
robyboy

Egyik ismerős mondta, hogy DMA-nál nincs user space. Szóval a frankó mikrokerneles fájlkezelő felülírhat más procesz címet is a RAM-ban.

Ha pedig a DMA kiakad, vagy az IRQ beakad, az viszi magával mikrokernelestül mindenestül az egészet. Fagyás mikrokernellel is lesz.

Viszont a Linux most sem döglik ki mindig, ha a kernel kód elszáll, mert csak az adott procesz fog repülni.

Milyen többletet ad a mikrokernel?

Az elveket olvastam róla, mármint hogy kidobták a mutexek zömét és ésszel kezdtek programozni.

Mikrokontrollereknél sem lehet orrvérzésig tiltani az interruptokat, mert pl. UART-nál simán adatvesztés lehet miatta, ha késnek.

Valahogy úgy oldják meg, hogy egy csak olvassa, a másik csak írja, így nem kell a mutex (feltéve, hogy az integer írás atomi).

Példa:
- körkörös puffer
- a feltöltési mutatót (head) a termelő szál írja, a fogyasztó olvassa
- a kiolvasási mutatót (tail) a fogyasztó szál írja, a termelő olvassa (puffer túlcsordulás ellenőrzése)
- két szál simán képes mutex nélkül üzenetket küldeni egymásnak

Vagy: 4 byte-os óra érték kiolvasása (a 8-bites processzorok 1 byte-ot tudnak atomi módon kezelni):
- kiolvasod egyszer
- kiolvasod mégegyszer
- ha egyezik oké (nem volt interrupt a byte olvasása közben)
- ha nem egyezik, újra próbálod

Az L4 lényege, hogy mutexelés helyett megpróbálsz mindent a beépített atomi műveletekkel elintézni.

Mi az, hogy beakad meg kiakad? :)

Az XMach-nál ezt úgy csináltuk emlékeim szerint, hogy a kernel DMA-buffert biztosított amit user space-ből lehetett hívogatni, így lehetett implementálni pl. QoS-t az ütemzéshez amint futási időben változtathattál. Azért, mert mikrokerneles, nem azt jelenti, hogy a minden driver hozzápiszkálhat minden szarhoz, beleírkál egymás címterébe (ez amúgy sem lehetséges védett módban).

Az i386-os architektúrát nem ismerem.

Mikrovezérlő alatt az IRQ-t ha a hardver 0-ban hagyja, akkor más IRQ nem lehetséges. Minden megáll, tehát a drivernek ezt törölnie kell az esemény lekezelése után.
Gondolom i386-on is hasonló az egész, csak több interrupt vonal van. Azok az eszközök döglenek meg, amik azonos interruptot használnak a beragadt eszközzel. Ehhez a drivert jól kell megírni, különben szétszáll.

A DMA valóban megoldható user space hívogatással, csak User1 ne tudjon bele-DMA-zni User2 adataiba.

Szóval nem triviális hogy mit, hová DMA-zol. Szoftverből kell ellenőriznie a kernelnek, hogy adott területre jogod van-e belenyomni adatokat.

Ha történetesen a DMA egy félrekonfigurálás miatt leáll (más architektúrán simán előfordulhat, PC-t nem ismerem), akkor az természetesen mindent visz (ha a file betöltés nem megy, akkor semmi más sem).

> Mikrovezérlő alatt az IRQ-t ha a hardver 0-ban hagyja, akkor más IRQ nem lehetséges.

A "nagy" procikon (en elsosorban ARMv7-re irtam drivereket) tobb megszakitas van, de ezeket egy megszakitasvezerlo kezeli. Ezert...
1. Vannak prioritasok es egy megszakitas fontosabb mint egy masik
2. A kernelt "meg lehet tanitani" a megszakitasvezerlo kezelesere es igy a driverek ebben nem tudnak hibazni.

Tehat ez nem valodi problema. Ha egy drivert sem erdekli a megszakitas akkor maszkolva van. Ha van egy amit erdekel, akkor annak szol a kernel, maszkolja, majd a driver keresere (amikor a driver kezelte a megszakitast) ujra engedelyezi a megszakitast. A maszkolas miatt a megszakitasok kezeleset is lehet utemezni.

> Ha történetesen a DMA egy félrekonfigurálás miatt leáll

A DMA nem resze a CPU-nak. Egy nagy ARM SoC-n tobb DMA vezerlo szokott lenni es a nagy adatatvitelre kepes periferiak (pl. Ethernet) sajat DMA-val rendelkeznek. A DMA vezerlok egy belso buszon osztoznak, de ez a busz ugy van kialakitva, hogy egy DMA sem foglalhatja tul sokaig. A DMA vezerloknek amiken tobb periferia osztozik altalaban tobb csatornaja van, es egy driver csak egy csatornat kezel. A DMA vezerlo felvaltva szokta a csatornak kereseit teljesiteni, es ha "beakad" egy csatorna akkor sem all le a tobbi. Valamit nagyon felre kell konfiguralni ahhoz, hogy megdogoljon a rendszer. :)

Engem az érdekelne, hogy Linus Torvals már 1991-ben elismerte a mikrokernel előnyeit, viszont a Linux az elmúlt 25 év alatt sem váltott. Pedig menet közben moduláris is lett.

Mi az indoka, hogy nem tették meg a lépést? Azt mondják, hogy az L4 már nem annyira lassú, mint a Minixnél volt. Az L4 20-szorosára gyorsította a "hagyományos" mutexes mikrokernelt, de még ez sem elég?

Olvastam egyébként azt is, hogy a mai gépek már elég gyorsak a mikrokernel overhead-hez, de ez szerintem nem igaz. Nincs az a telefongyártó, aki 20%-kal csökkentené az akkumulátoridőt a mikrokernel kedvéért.

"Olvastam egyébként azt is, hogy a mai gépek már elég gyorsak a mikrokernel overhead-hez, de ez szerintem nem igaz. Nincs az a telefongyártó, aki 20%-kal csökkentené az akkumulátoridőt a mikrokernel kedvéért."

A telefonokon nem mikrokernelek szoktak lenni? (gondolok itt: Symbian, BB, iOS, gombos telefonok, etc)

Az mar nem lenne Linux. :) Gyakorlatilag nullarol kene ujratervezni a kernelt ahhoz, hogy jo mikrokernel legyen.

Raadasul egy mikrokernel valoban valamivel lassabb, de van rengeteg terulet ahol az kevesbe szamit mint az elonyei.

> a mai gépek már elég gyorsak a mikrokernel overhead-hez, de ez szerintem nem igaz. Nincs az a telefongyártó,

QNX sok ideje van mar es eleg sok teruleten hasznaljak:
http://image.slidesharecdn.com/qnx35ways-150209141721-conversion-gate01…

(Azt hiszem ezen a ponton illik megemlitenem, hogy egykor QNX alkalmazott voltam.)

Az L4-nél állítólag kihagyták a mutexeket, ez pedig programozási stílus váltás, lentebb írtam már róla.

Mutex nélkül is képes vagy rengeteg dolgot megcsinálni, ami egyébként szinkronizálást igényelne.

Példa:
- ki szeretnéd olvasni az nap/óra/perc/másodperc értékeket, amit egy szál frissít
- ha nem szinkronizálsz, bajban lehetsz, mert 23:59:59-ről akár 24:59:59-re is ugorhatsz, ha nem lockolsz (az óra kiolvasás nem atomi).

Jön a trükk:
- kétszer olvasod ki az órát gyorsan egymás után, ha megegyezik a két érték, akkor nem volt váltás félúton
- ha épp kiolvasás közben jött az órafrissítés, nincs más dolgod, mit újra kiolvasni

Szinkronizálás nulla, overhead minimális.

Amit az L4-ről olvastam, hogy ha van más megoldás, akkor nem használ mutexet.

Szerencsere vannak atomi muveletek a modern processzorokon, mert ez a trukk nem minden processzoron mukodik. :)

Pelda: Az ARM processzorok atrendezhetik ezt a muveletet ugy, hogy valojaban ugyanazt a hibas erteket olvasod ki ketszer. Tehat ha akkor eppen a frissites felenel jarna a masik szal, akkor a hibas ertekrol hiszi azt a programod, hogy helyes. Ezzel a problemaval a legtobb programozo nem talalkozik, mert ha megfelelo szinkronizaciot hasznal akkor nem tortenik meg, hiszen a mutex muveletek tartalmaznak egy DMB utasitast, igy biztos, hogy a tobbi mag is tud a valtozasrol.

Meg egy aprosag: mi garantalja, hogy a masik szalnak van ideje befejezni a memoria muveletet a ket olvasas kozott ha az utemezo megszakitja a modositas kozepen?

Egyebkent nem olyan borzaszto dolog egy mutex. Persze, az ido lekerdezesehez tulzas lehet, de egyreszt vannak atomi muveletek, masreszt viszonylag ritkan kell a valodi ido a kernelnek. Az utasitasok szama is eleg felrevezeto. Valojaban fene tudja, hogy mi a teljes ara a muveleteknek.

Egy jol megtervezett mikrokernel eseteben amugy is kevesebb szinkronizaciora van szukseg, mert kevesebb idot tolt a processzor a kernelben. Egy nagy kernel mutex borzaszto dolog ha a kerneledben van egy halozati stack, usb stack, fajlrendszerek, es egyeb furcsasagok, de nem olyan nagy gond ha a kerneled valoban csak utemez, processzek kozott mozgat adatot, es a hw nagyon alacsony szintjet (megszakitasok, MMU, stb.) kezeli. A processzor lenyegesen kevesebb idot tolt a kernelben, igy a finomabb szinkronizacio elonyei is elvesznek.

Kevertem a szezont a fazonnal. Mikrokontroller alatt az interrupt frissít, ott ez megy. Ott nincs két szál, az interrupt mindenképpen befejezi.

Meg lehet csinálni szállal is, de trükközni kell. Pointert olvasol ki (64 biten atomi), ami az órára mutat, azt meg egy lépésben frissíted.

> Mikrokontroller alatt az interrupt frissít, ott ez megy.

Persze, de ugyis csak egy magod van, tehat ennyi erovel a megszakitasokat is tilthatnad az eleres elott es utan.
Ha van ket magod akkor meg maris vannak szalaid, tehat spinlock es memory barrier kell.

> Pointert olvasol ki (64 biten atomi), ami az órára mutat, azt meg egy lépésben frissíted.

Csak akkor atomi ha az atomi muveletet hasznalod. A sima load/store eseten ez nem garantalt.
Egyebkent ez sem megoldas mert uj memoriat kell allokalnod hozza. Ezzel ket problemat latok:
1. A memoria allokatorok altalaban szinkronizaciot igenyelnek.
2. Nem tudod, hogy mikor lehet felszabaditani a memoriat. A szal amelyik az idot frissiti nem szabadithatja fel, hiszen egy masik szal meg dolgozhat vele. Az utolso szal ami hasznalja sem tudja, hogy o volt az utolso... Referencia szamlalassal ez is megoldhato, de az ket atomi muveletet jelent amikor elered az idot, avagy ugyanott vagy mintha rendesen szinkronizalnad az elerest.

Viszont mar elegge eltertunk az eredeti tematol... :)

> Egyik ismerős mondta, hogy DMA-nál nincs user space.

Ha van IOMMU akkor lehet kulon user space DMA-nal.

> Szóval a frankó mikrokerneles fájlkezelő felülírhat más procesz címet is a RAM-ban.

A mikrokernel nem azt jelenti, hogy minden processz hozzafer a hw-hez. Az inkabb exokernel jellemzo. Mikrokernelen a driverek kulon processzek amikkel (lehetoleg hatekony) IPC-n keresztul kommunikal minden masik processz.

> Ha pedig a DMA kiakad, vagy az IRQ beakad

Nem jellemzo. Az altalam ismert mikrokernelen a megszakitasokat tovabbra is a kernel vezerli. ISR-t lehet ugyan irni, de csak akkor ajanlott ha nagyon teljesitmeny kritikus. Minden mas esetben a kernel mas csatornan tajekoztatja a drivert es az IRQ maszkolasa kernel hivason keresztul tortenik. Alap esetben minden megszakitas maszkolva van.

> Fagyás mikrokernellel is lesz.

Persze, sokkal fontosabb viszont hogy a hibak altalaban jobban behatarolhatoak mintha mondjuk veletlenul beleirsz a kerneled egy masik adatstrukturajaba.

> Viszont a Linux most sem döglik ki mindig, ha a kernel kód elszáll, mert csak az adott procesz fog repülni.

Ez igy nem igaz. Egy monolitikus kernelben konnyebb olyan hibat csinalni ami csak sokkal kesobb okoz problemat, de akkor mar nehez visszavezetni odaig.

> Milyen többletet ad a mikrokernel?

Egyszerubb a kernel space-ben futo kod. Konnyebb a hibakat izolalni.
Halozati stack, fajlrendszerek, stb. nem valok a kernelbe mert tul nagy a tamadasi felulet es a hibalehetoseg.
User space-ben futo programot konnyebb debugolni.
IOMMU-val a driverek is teljesen szeparalva vannak.
Meglepodnel mennyire keves drivernek kell valojaban DMA tamogatas.

Tapasztalatom szerint a legtobb driver hiba olyan hiba ami barmilyen mas programban is elofordulhatna: memory leak, NULL pointer hasznalata, vegtelen ciklus, deadlock, stb. Ezek a hibak mikrokernel eseten nem szoktak hatalmas problemat okozni es a megszokott eszkozokkel meg lehet oket talalni.