Miguel Ojeda, der Autor des Projekts Rust-for-Linux, hat den Entwicklern des Linux-Kernels die Veröffentlichung der Version 6 von Komponenten vorgeschlagen, die zur Entwicklung von Gerätetreibern in Rust dienen. Dies ist die siebte Ausgabe der Patches, die auf der ersten Version basiert, die ohne Versionsnummer veröffentlicht wurde. Die Unterstützung von Rust wird als experimentell betrachtet, ist aber bereits in den linux-next Branch integriert und ausreichend entwickelt, um mit der Schaffung von Abstraktionsschichten über den Kernel-Subsystemen sowie der Erstellung von Treibern und Modulen zu beginnen. Die Entwicklung wird von Google und der ISRG (Internet Security Research Group) finanziert, die das Projekt Let’s Encrypt ins Leben gerufen hat und die Förderung von HTTPS und der Entwicklung von Technologien zur Verbesserung der Internetsicherheit unterstützt.
In der neuen Version:
- Das Toolkit und die alloc-Bibliothek, die von möglichen "panic"-Zuständen bei Fehlern befreit sind, wurden auf die Version Rust 1.60 aktualisiert, in der die Unterstützung des Modus "maybe_uninit_extra" stabilisiert wurde, der in den Patches für den Kernel verwendet wird.
- Die Möglichkeit, Tests aus der Dokumentation auszuführen (Tests, die gleichzeitig als Beispiele in der Dokumentation verwendet werden), wurde hinzugefügt, indem während der Kompilierung von API-gebundenen Tests in KUnit-Tests umgewandelt wird, die beim Booten des Kernels ausgeführt werden.
- Es wurden Anforderungen angenommen, laut denen Tests keine Warnungen des Linters Clippy erzeugen dürfen, ebenso wie der Code für den Kernel in Rust.
- Eine erste Implementierung des Moduls „net“ mit Netzwerkfunktionen wurde vorgeschlagen. Der Code in Rust hat Zugriff auf Netzwerkstrukturen des Kernels wie „Namespace“ (basierend auf der Kernelstruktur „struct net“), SkBuff (struct sk_buff), TcpListener, TcpStream (struct socket), Ipv4Addr (struct in_addr), SocketAddrV4 (struct sockaddr_in) und deren Äquivalente für IPv6.
- Die erste Unterstützung für asynchrones Programmieren (async) wurde in Form des Moduls kasync implementiert. Beispielsweise kann asynchroner Code zum Umgang mit TCP-Sockets erstellt werden: async fn echo_server(stream: TcpStream) -> Result { let mut buf = [0u8; 1024]; loop { let n = stream.read(&mut buf).await?; if n == 0 { return Ok(()); } stream.write_all(&buf[..n]).await?; } }
- Ein net::filter-Modul wurde hinzugefügt, um Netzwerkpaketfilter zu manipulieren. Ein Beispiel rust_netfilter.rs mit der Implementierung eines Filters in Rust wurde hinzugefügt.
- Die Implementierung eines einfachen Mutex smutex::Mutex, der keine Bindung (Pinning) erfordert, wurde hinzugefügt.
- Eine NoWaitLock-Sperre wurde hinzugefügt, die niemals zu einer Wartezeit führt. Im Falle einer Sperrung durch einen anderen Thread wird stattdessen ein Fehler beim Versuch, die Sperre zu erwerben, ausgegeben, anstatt den Aufrufer zu stoppen.
- Ein RawSpinLock wurde hinzugefügt, das mit raw_spinlock_t im Kernel identifiziert ist und für Abschnitte verwendet wird, die nicht im Wartezustand sein dürfen.
- Ein Typ ARef für Referenzen auf Objekte, die ein Referenzzählmechanismus (always-refcounted) verwenden, wurde hinzugefügt.
- Im Backend rustc_codegen_gcc, das die Nutzung der libgccjit-Bibliothek aus dem GCC-Projekt als Code-Generator in rustc ermöglicht, wurde die Möglichkeit der Compiler-Rollierung (Bootstrapping) von rustc implementiert. Hierbei wird die Fähigkeit verstanden, den Code-Generator auf Basis von GCC in rustc zu verwenden, um den Compiler rustc selbst zu erstellen. Darüber hinaus wurden im aktuellen GCC 12.1 Korrekturen in libgccjit aufgenommen, die für die korrekte Funktion von rustc_codegen_gcc erforderlich sind. Es wird an der Bereitstellung der Möglichkeit gearbeitet, rustc_codegen_gcc über das Tool rustup zu installieren.
- Der Fortschritt in der Entwicklung des GCC-Frontends gccrs wird festgestellt, das einen Rust-Compiler auf Basis von GCC implementiert. Derzeit arbeiten zwei Entwickler im Vollzeitmodus an gccrs.
Wir erinnern daran, dass die vorgeschlagenen Änderungen die Möglichkeit bieten, Rust als zweite Sprache für die Entwicklung von Treibern und Kernelmodulen zu verwenden. Die Unterstützung von Rust wird als Option vorgestellt, die nicht standardmäßig aktiviert ist und nicht dazu führt, dass Rust zu den obligatorischen Build-Abhängigkeiten des Kernels gehört. Die Verwendung von Rust zur Treiberentwicklung ermöglicht es, mit minimalem Aufwand sichere und qualitativ hochwertige Treiber zu erstellen, die von Problemen wie dem Zugriff auf freigegebenen Speicher, Dereferenzierung von Nullzeigern und Bufferüberläufen befreit sind.
Die sichere Verwaltung von Speicher in Rust erfolgt während der Kompilierung durch Überprüfung von Referenzen, das Verfolgen des Eigentums an Objekten und das Management der Lebensdauer von Objekten (Sichtbarkeiten). Außerdem bewertet Rust die Korrektheit des Zugriffs auf den Speicher zur Laufzeit. Rust bietet auch Mechanismen zum Schutz vor Überläufen bei Ganzzahlen, verlangt die obligatorische Initialisierung von Variablen vor ihrer Verwendung, behandelt Fehler in der Standardbibliothek besser und wendet das Konzept der Unveränderlichkeit (immutable) für Referenzen und Variablen standardmäßig an. Zudem bietet es eine starke statische Typisierung zur Minimierung logischer Fehler.
Quelle: opennet.ru
