Spis treści:
- Brian Cantrill
- Czym jest system operacyjny
- Jak ewoluowały systemy operacyjne
- UNIX i języki wysokiego poziomu
- Systemy operacyjne w latach 80. i 90. XX wieku
- Systemy operacyjne w latach 2000.
- Co jest takiego wyjątkowego w języku Rust
- Czy można napisać system operacyjny w języku Rust
- Dlaczego spodziewam się hybrydowych systemów operacyjnych C i C – Rust

Bezpłatny kurs Pythona ➞ Mini kurs dla początkujących i doświadczonych programistów. 4 ciekawe projekty w portfolio, komunikacja na żywo z prelegentem. Kliknij i dowiedz się, czego możesz się nauczyć w tym kursie.
Dowiedz się więcej
Na konferencji QCon Brian Cantrill przedstawił powody, dla których wielu programistów systemowych preferuje język Rust. Omówił również perspektywy wykorzystania Rusta w rozwoju nowoczesnych systemów operacyjnych. Rust oferuje takie zalety, jak bezpieczeństwo pamięci i wysoka wydajność, co czyni go idealnym wyborem do programowania systemowego. W swoim wystąpieniu Cantrill podkreślił, że Rust rozwiązuje wiele problemów, z którymi borykają się programiści, i otwiera nowe możliwości tworzenia niezawodnych i wydajnych rozwiązań programistycznych.
W tym artykule przedstawiliśmy główne idee i wnioski z wystąpienia. Przeanalizowaliśmy kluczowe punkty i omówiliśmy ich znaczenie. Czytelnicy będą mogli zapoznać się z najważniejszymi zagadnieniami i uzyskać przydatne informacje na podstawie treści wystąpienia.
Jeśli zadajesz pytanie, czy wszystkie systemy operacyjne powinny zostać przepisane w Ruście, zgodnie z zasadą nagłówków Betteridge'a, możesz oczekiwać odpowiedzi „nie”. Istnieje jednak wiele argumentów przemawiających za odpowiedzią „tak”. W tym artykule wyjaśnię, dlaczego warto rozważyć tę koncepcję i dlaczego w tytule użyłem znaku zapytania zamiast wykrzyknika. Rust, dzięki swojemu bezpieczeństwu i wydajności, ma potencjał, aby znacząco poprawić jakość systemów operacyjnych. Ten język programowania zapewnia ochronę przed wyciekami pamięci i wyścigami danych, co jest ważnym aspektem w rozwoju złożonych systemów. Należy również wziąć pod uwagę rosnącą społeczność programistów Rusta i jego aktywny rozwój, co może prowadzić do pojawienia się nowych narzędzi i bibliotek upraszczających tworzenie systemów operacyjnych. Dlatego warto rozważyć potencjał Rusta w tym obszarze i to, jak może on zmienić podejście do tworzenia systemów operacyjnych.
Czym jest system operacyjny
Na pierwszy rzut oka pytanie o to, czym jest oprogramowanie, może wydawać się proste. Jednak, aby zrozumieć ten temat, ważne jest, aby rozważyć definicję oprogramowania. Na przykład algorytm Euklidesa nie jest uważany za oprogramowanie, ponieważ został opracowany przed pojawieniem się komputerów. Oprogramowanie to zestaw instrukcji, który steruje działaniem komputera i wykonuje określone zadania. Oprogramowanie obejmuje zatem aplikacje, systemy operacyjne i inne komponenty, które umożliwiają użytkownikom interakcję z urządzeniami i wykonywanie różnych operacji.
System operacyjny (OS) działa na sprzęcie. Nie ogranicza się jednak do urządzeń fizycznych, ponieważ można go wdrożyć w chmurze na maszynach wirtualnych. W związku z tym kwestia wyboru i konfiguracji systemu operacyjnego staje się bardziej złożona i wymaga starannego podejścia.
System operacyjny to oprogramowanie, które zarządza zasobami sprzętowymi komputera i umożliwia uruchamianie aplikacji innych firm. Jeśli system operacyjny przestanie działać, wszystkie uruchomione procesy i aplikacje również przestaną działać. Prawidłowa konfiguracja i wsparcie systemu operacyjnego odgrywają kluczową rolę w stabilności i wydajności systemu, co podkreśla znaczenie regularnych aktualizacji i konserwacji.
System operacyjny zawiera jądro, które zapewnia pełny dostęp do zasobów procesora, pamięci i innego sprzętu. Jednak jądro nie jest jedynym składnikiem systemu operacyjnego. Biblioteki, polecenia i demony również odgrywają ważną rolę, zapewniając funkcjonalność i interakcję między użytkownikiem a systemem. Biblioteki zapewniają niezbędne funkcje aplikacjom, polecenia umożliwiają użytkownikom zarządzanie systemem, a demony działają w tle, wykonując różne zadania i zapewniając wsparcie procesów. Wszystkie te elementy razem zapewniają stabilne i wydajne działanie systemu operacyjnego.
Jak ewoluowały systemy operacyjne
Symulacje systemów operacyjnych zaczęto tworzyć w języku asemblera zaraz po II wojnie światowej. Jednak pierwszy pełnoprawny system operacyjny powstał w 1961 roku – był to MCP, napisany w języku ESPOL. Platforma MCP została opracowana dla komputera Burroughs B5000, który pomimo innowacyjnych technologii nie zdobył należnego mu miejsca na rynku z powodu niepraktyczności komercyjnej.
W 1964 roku w Massachusetts Institute of Technology (MIT) podjęto próbę rozwinięcia koncepcji wielozadaniowości, co doprowadziło do stworzenia CTSS, wielozadaniowego systemu operacyjnego. System ten był w stanie efektywnie rozdzielać zasoby sprzętowe między różne programy i użytkowników. Rezultatem projektu był system znany jako Multics, który stał się znaczącym krokiem naprzód w dziedzinie systemów operacyjnych i wielozadaniowości.
Twórcy Multics dążyli do idealnego rozwiązania, ale napotkali na to, co powszechnie nazywa się syndromem drugiego systemu. Postanowili przepisać niemal wszystkie komponenty projektu od podstaw, co doprowadziło do jego znacznego rozrostu. W rezultacie termin ukończenia projektu był stale przesuwany.
System operacyjny został opracowany w języku programowania PL/I. Kompilację tego języka powierzono firmie outsourcingowej, ale projekt zakończył się niepowodzeniem. W rezultacie, aby pokonać powstałe trudności, zespół naukowców opracował nowy język o nazwie EPL i kontynuował rozwój systemu opartego na nim.
W 1969 roku Bell Labs, jeden z kluczowych uczestników projektu, dostrzegł jego nieoczekiwany charakter i postanowił z niego zrezygnować. W rezultacie pracownik Bell Labs, Ken Thompson, wykorzystał osiągnięcia projektu do stworzenia UNIX-a, systemu operacyjnego przeznaczonego dla minikomputera PDP-7. UNIX stał się podstawą wielu nowoczesnych systemów operacyjnych i miał znaczący wpływ na rozwój technologii komputerowych.
UNIX i języki wysokiego poziomu
Wiele osób błędnie uważa, że system operacyjny UNIX został stworzony w języku C, ale to nieprawda. W rzeczywistości UNIX został opracowany w całości w języku asemblera. W przeciwieństwie do twórców Multics, zespół, który stworzył UNIX, uniknął syndromu drugiego systemu. Najpierw stworzyli działający komponent, a następnie skupili się na pisaniu dla niego dokumentacji. Ta metodologia rozwoju przyczyniła się do powstania bardziej stabilnego i wydajnego systemu operacyjnego, czyniąc UNIX podstawą wielu współczesnych systemów.
W 1969 roku w Bell Labs opracowano język programowania B. Służył on do pisania różnych programów narzędziowych dla systemu operacyjnego UNIX, a także do tworzenia języka asemblera. Język B był ważnym krokiem w ewolucji programowania i położył podwaliny pod powstanie bardziej złożonych języków, takich jak C, który następnie znacząco wpłynął na rozwój oprogramowania i systemów.
Twórcy UNIX-a zmagali się z niewystarczającą wydajnością języka B. Chociaż wierzyli, że system operacyjny można stworzyć w języku wysokiego poziomu, B okazał się nieodpowiednią opcją. Głównym problemem był brak adresowalności bajtowej, który ograniczał możliwości rozwoju i optymalizacji systemu.
Język programowania C został opracowany na początku lat 70. XX wieku. Pierwsza wersja języka nie zawierała struktur, które wprowadzono dopiero w 1973 roku na potrzeby jądra systemu operacyjnego UNIX. W tym okresie dodano pola bitowe, co znacznie rozszerzyło możliwości języka i poprawiło jego funkcjonalność. Język C stał się podstawą rozwoju wielu innych języków programowania i wywarł znaczący wpływ na współczesne programowanie.
Język programowania rozwijał się stopniowo, co jest zarówno jego zaletą, jak i wadą. Jedną z wad, moim zdaniem, jest brak logicznej operacji XOR. Jeden z twórców języka twierdził, że XOR nie nadaje się do wykonywania obliczeń na zasadzie zwarcia, co mnie zastanawia. To ograniczenie może komplikować rozwój i optymalizację algorytmów wymagających użycia operacji logicznych.
Język programowania C ewoluował, a wprowadzono makra, które są jedną z kluczowych funkcji podobnych do tych w Rust. Preprocesory również odgrywają znaczącą rolę w tym procesie. Chociaż preprocesory nie zawsze są preferowane przez wielu programistów, są niezbędnymi narzędziami dla systemów takich jak DTrace i ZFS. Te cechy rozszerzają funkcjonalność języka i umożliwiają tworzenie bardziej złożonych i wydajnych rozwiązań.
Systemy operacyjne w latach 80. i 90. XX wieku
W latach 80. XX wieku język programowania C zdominował rozwój systemów operacyjnych i większość systemów operacyjnych była na nim oparta. Jednak w latach 90. XX wieku pojawił się trend w kierunku programowania obiektowego, co doprowadziło do poglądu, że systemy operacyjne oparte na C są przestarzałe. Oczekiwano, że zostaną zastąpione systemami napisanymi w Javie i C++. Jednak próby te zakończyły się niepowodzeniem, częściowo z powodu zjawiska znanego jako syndrom drugiego systemu.
W latach 90. XX wieku, gdy Gil Amelio pełnił funkcję dyrektora generalnego Apple, firma aktywnie promowała system Mac OS Copland, ale nigdy nie udało jej się go wypuścić na rynek. W tym czasie konkurenci z Doliny Krzemowej obserwowali zmagania Apple, licząc na bankructwo firmy i możliwość przejęcia jej aktywów po niskiej cenie. Ten okres stał się krytyczny dla firmy, ponieważ musiała ona stawić czoła poważnym wyzwaniom finansowym i technicznym, które zadecydowały o jej przyszłym losie na rynku technologicznym.

Firma Sun Microsystems opracowała system operacyjny Spring w języku C++. Jako student natknąłem się na płytę CD z Springiem i próbowałem zainstalować go na swoim komputerze, ale system się nie uruchamiał. Problem polegał na tym, że miałem tylko 32 MB pamięci RAM, podczas gdy instalacja wymagała co najmniej 128 MB. Dzisiaj jest to porównywalne z 2 TB pamięci RAM.
Stworzenie systemu operacyjnego w Javie okazało się niemożliwe. Głównym powodem jest brak typu danych bez znaku w tym języku, co znacznie komplikuje interakcję systemu ze sprzętem.
Systemy operacyjne w latach 2000.
Od czasu pojawienia się Linuksa pisanie systemów operacyjnych w C stało się standardem branżowym. Wielu programistów próbowało stworzyć jądro systemu operacyjnego w C++, ale większość tych prób zakończyła się niepowodzeniem. Projekt Haiku stanowi wyjątek, ale był to przede wszystkim projekt hobbystyczny i nigdy nie osiągnął poziomu poważnych systemów.
Na początku XXI wieku Java i C++ były uważane za główne języki programowania. W kolejnych latach pojawiły się języki takie jak Ruby, Python i JavaScript, koncentrujące się na przyspieszeniu procesu rozwoju. Jednak pomimo ich popularności, nikt nie podjął się stworzenia systemu operacyjnego w Ruby lub Pythonie, co podkreśla specyficzne zastosowanie tych języków i ich ograniczenia w kontekście programowania systemowego.
JavaScript początkowo nie był zbyt popularny, ale jego użycie znacznie wzrosło w 2006 roku. Wtedy programiści zdali sobie sprawę, że przeglądarki zaczęły obsługiwać pełnoprawny język, który pozwala na tworzenie wydajnych aplikacji internetowych. Dla mnie JavaScript to rodzaj zakamuflowanego Lispa, dostosowanego do działania w przeglądarce, ale z uproszczoną strukturą składniową, bez nadmiaru nawiasów. Język ten stał się podstawą dla programistów internetowych, otwierając nowe horyzonty w tworzeniu interaktywnych i dynamicznych stron internetowych. W latach 2010. programiści systemowi poszukiwali języka programowania, który łączyłby wysoką wydajność języka C z wygodnymi narzędziami dostępnymi w innych językach. Kluczowymi cechami, których szukali, były takie funkcje, jak metoda split() i obsługa wyrażeń regularnych, które uprościłyby przetwarzanie ciągów znaków i operacje regularne. Stworzenie takiego języka byłoby znaczącym krokiem naprzód w rozwoju oprogramowania, zapewniającym równowagę między wydajnością a łatwością tworzenia. JavaScript dał początek wielu interesującym osiągnięciom. Jednym z nich był wydajny silnik V8, który umożliwia wykonywanie kodu JavaScript po stronie serwera. Następnie pojawił się Node.js, który otworzył nowe horyzonty w tworzeniu aplikacji po stronie serwera. Pomimo mojej sympatii do JavaScript, jego użycie w oprogramowaniu systemowym może być trudne. Niektórzy pracownicy Bell Labs dołączyli do zespołu Google i opracowali język programowania Go. Język ten jest wolny od wielu niedociągnięć JavaScript, ale ma swoje własne unikalne cechy. Go oferuje silniejsze typowanie, co zmniejsza błędy kompilacji i poprawia wydajność. Ponadto obsługuje programowanie współbieżne, co czyni go idealnym wyborem do tworzenia aplikacji o dużym obciążeniu.
W swojej prezentacji programista Google, Adin Scannell, zauważył, że możliwe jest stworzenie jądra systemu operacyjnego za pomocą Go. Jednak, podobnie jak JavaScript, Go ma wspólny problem: śmieciarki. Te mechanizmy zarządzania pamięcią mogą znacznie spowolnić programy systemowe, czyniąc je nieefektywnymi w tworzeniu systemów operacyjnych. Dlatego programiści powinni wziąć pod uwagę te ograniczenia, wybierając języki programowania do takich zadań.
Co wyróżnia Rust
Napisałem ponad sto tysięcy linii kodu w C++ i nie planuję powrotu do tego języka. Ostatnio coraz bardziej pociąga mnie Rust, ponieważ łączy on wysoką wydajność i bezpieczeństwo, co czyni go idealnym wyborem do tworzenia oprogramowania systemowego. Rust oferuje nowoczesne podejście do zarządzania pamięcią, co znacznie zmniejsza prawdopodobieństwo wystąpienia błędów. Te wartości czynią go atrakcyjnym dla programistów, którzy chcą tworzyć niezawodne i wydajne aplikacje.
Jedną z kluczowych cech języka programowania Rust jest koncepcja własności. Rust statycznie określa, kto jest właścicielem danego zasobu, co zapewnia wysoki poziom bezpieczeństwa pamięci. Kompilator zarządza alokacją i dealokacją pamięci, robiąc to automatycznie po zakończeniu korzystania z zasobu. Jeśli kompilator nie może ustalić właściciela pamięci, korzysta z mechanizmu pożyczania. Takie podejście zapobiega wyciekom pamięci i zapewnia, że jeden program nie może nadpisać pamięci innego. W ten sposób Rust zapewnia bezpieczeństwo i wydajność pracy z zasobami, co czyni go atrakcyjnym wyborem do tworzenia niezawodnych aplikacji.
Rust ma wiele funkcji, które bardzo mi się podobają. Ten język programowania oferuje bogaty zestaw możliwości, które pozwalają programistom efektywnie rozwiązywać problemy. Jedną z jego kluczowych cech jest system zarządzania pamięcią, który zapewnia bezpieczeństwo i zapobiega wyciekom. Warto również zwrócić uwagę na jego potężne narzędzia współbieżności, dzięki którym Rust jest idealnym wyborem do tworzenia aplikacji o wysokiej wydajności. Co więcej, jego przyjazna dla użytkownika składnia i obsługa programowania funkcyjnego czynią go atrakcyjnym dla programistów na każdym poziomie umiejętności. Rust pozwala na tworzenie niezawodnego i wydajnego kodu, co niewątpliwie jest jednym z powodów jego popularności wśród programistów.
Typy algebraiczne to potężne narzędzie do obsługi błędów w programowaniu. Działają podobnie do unii w języku C, oferując wydajne mechanizmy pracy z różnymi stanami danych. Korzystanie z typów algebraicznych pozwala programistom na bezpieczniejsze i bardziej przejrzyste zarządzanie błędami, poprawiając czytelność i łatwość utrzymania kodu. Prawidłowo stosowane typy algebraiczne mogą znacząco poprawić jakość oprogramowania, minimalizując prawdopodobieństwo nieoczekiwanych awarii i upraszczając debugowanie.
Makra higieniczne to potężne narzędzie w rozwoju języków programowania. W przeciwieństwie do języka C, gdzie nie są używane, w innych językach, takich jak Rust czy Lisp, makra higieniczne pozwalają tworzyć bezpieczniejszy i bardziej przewidywalny kod. Jedną z głównych zalet takich makr jest minimalizowanie prawdopodobieństwa kolizji nazw, co upraszcza proces pisania i utrzymywania kodu oprogramowania. Możliwość dostępu do makr higieny jako abstrakcyjnego drzewa składniowego wraz z resztą kodu otwiera przed programistami nowe horyzonty, umożliwiając bardziej złożone i elastyczne rozwiązania.
Interfejs funkcji zewnętrznych Rusta został starannie zaprojektowany, umożliwiając bezproblemową integrację kodu C z programami Rusta i odwrotnie. Ta interoperacyjność między językami zapewnia większą elastyczność i rozszerzalność, dzięki czemu Rust jest idealnym wyborem dla programistów, którzy chcą wykorzystać istniejący kod C w nowych aplikacjach.
Słowo kluczowe unsafe służy do wyłączania bezpieczeństwa pamięci, umożliwiając wykonywanie operacji, które w innym przypadku byłyby zabronione przez kompilator. To słowo kluczowe daje programistom możliwość bezpośredniego zarządzania pamięcią i optymalizacji kodu, ale wymaga ostrożnego użycia, ponieważ może wprowadzać błędy i luki w zabezpieczeniach. Użycie opcji unsafe pozwala na tworzenie aplikacji o wysokiej wydajności, ale ważne jest, aby wziąć pod uwagę ryzyko związane z bezpieczeństwem i stabilnością programu.
Czy można napisać system operacyjny w Rust?
Rust to język programowania idealny do tworzenia systemów operacyjnych. Od 30 lat programiści poszukują narzędzia, które zapewni bezpieczeństwo pamięci i wysoką wydajność. Rust łączy te cechy, umożliwiając tworzenie niezawodnych i wydajnych systemów. Dzięki systemowi zarządzania pamięcią i silnemu typowaniu, Rust minimalizuje ryzyko związane z błędami, co czyni go doskonałym wyborem do programowania systemowego. W tym kontekście Rust otwiera nowe horyzonty przed programistami dążącymi do tworzenia nowoczesnych i bezpiecznych systemów operacyjnych.
Pierwszą znaną próbą stworzenia systemu operacyjnego był Weenix. Projekt ten został stworzony przez studenta Zachary'ego Espiritu w ramach jego pracy dyplomowej. W swoich badaniach szczegółowo opisuje trudności i wyzwania, z jakimi spotkał się podczas procesu tworzenia. Weenix był ważnym krokiem w zrozumieniu zasad tworzenia systemów operacyjnych i otworzył nowe horyzonty dla dalszych badań w tej dziedzinie.
Od 2015 roku zaczęły pojawiać się małe systemy operacyjne oparte na języku programowania Rust, takie jak Redox, Tock, IntermezzOS, BlogOS, QuiltOS i Rux. Spośród nich IntermezzOS i BlogOS to projekty edukacyjne, a Tock został opracowany z myślą o urządzeniach IoT. Te systemy operacyjne świadczą o rosnącym zainteresowaniu Rustem w dziedzinie programowania systemowego i jego potencjale w tworzeniu bezpiecznych i wydajnych platform.
Niestety, te systemy operacyjne nie są kompatybilne binarnie z Linuksem, co uniemożliwia uruchomienie większości aplikacji linuksowych. Dlatego uważam, że podejście hybrydowe jest optymalnym rozwiązaniem do tworzenia systemów operacyjnych w Rust. Takie podejście pozwala na integrację najlepszych praktyk i możliwości na różnych platformach, zapewniając wsparcie dla niezbędnych programów i rozszerzając funkcjonalność systemu.
Dlaczego z niecierpliwością czekam na hybrydowe systemy operacyjne C i Rust
Jestem bardzo optymistycznie nastawiony do perspektyw języka programowania Rust. Jestem przekonany, że można go skutecznie zastosować w rozwoju systemów operacyjnych, w tym oprogramowania układowego, rozszerzeń jądra i różnych komponentów systemu operacyjnego. Jednak w praktyce mogą pojawić się poważne wyzwania wymagające uwagi i znalezienia rozwiązań. Rust oferuje szereg zalet, takich jak bezpieczeństwo pamięci i wysoka wydajność, co czyni go atrakcyjnym wyborem do programowania systemowego.
Rust zapewnia kompatybilność z systemami napisanymi w C, co jest jedną z jego kluczowych cech. Ta kompatybilność otwiera szerokie horyzonty dla programistów, pozwalając im zintegrować Rust z istniejącymi projektami i wykorzystać jego zalety, takie jak bezpieczeństwo pamięci i wydajność. Takie podejście prowadzi do bardziej niezawodnych i wydajnych aplikacji, dzięki czemu Rust staje się atrakcyjnym wyborem w przypadku tworzenia oprogramowania systemowego.
Sprawdź dodatkowe materiały:
- Facebook* jest zardzewiały: dlaczego korporacje powinny wspierać język Rust
- Problem trzech testerów na rozmowie kwalifikacyjnej
- Obowiązkowa lektura. 7 nowych artykułów w języku angielskim na temat FreeBSD, NetBSD i OpenBSD

