Die achte Version von Patches für den Linux-Kernel mit Unterstützung für die Rust-Sprache

Miguel Ojeda, Autor des Rust-for-Linux-Projekts, schlug die Veröffentlichung von v8-Komponenten zur Entwicklung von Gerätetreibern in der Rust-Sprache zur Prüfung durch Linux-Kernel-Entwickler vor. Dies ist die überarbeitete Version der Patches unter Berücksichtigung der ersten Version, die ohne Versionsnummer veröffentlicht wurde. Die Rust-Unterstützung gilt als experimentell, ist jedoch bereits im Linux-Next-Zweig enthalten, soll in die Herbstversion 5.20/6.0 integriert werden und ist ausgereift genug, um mit der Erstellung von Abstraktionsschichten über Kernel-Subsystemen sowie dem Schreiben von Treibern zu beginnen und Module. Die Entwicklung wird von Google und der ISRG (Internet Security Research Group) finanziert, die Gründerin des Let's Encrypt-Projekts ist und HTTPS und die Entwicklung von Technologien zur Verbesserung der Internetsicherheit fördert.

In der neuen Version:

  • Das Toolkit und eine Variante der Alloc-Bibliothek, die frei von der möglichen Generierung eines „Panik“-Zustands bei Fehlern ist, wurden für die Veröffentlichung von Rust 1.62 aktualisiert. Im Vergleich zur zuvor verwendeten Version hat das Rust-Toolkit die Unterstützung für die in Kernel-Patches verwendete const_fn_trait_bound-Funktionalität stabilisiert.
  • Der Bindungscode ist in ein separates Crate-Paket „Bindings“ aufgeteilt, was die Neuerstellung vereinfacht, wenn Änderungen nur am Hauptpaket „Kernel“ vorgenommen werden.
  • Implementierung des Makros „concat_idents!“ in Form eines prozeduralen Makros umgeschrieben, das nicht an die concat_idents-Funktionalität gebunden ist und die Verwendung von Verweisen auf lokale Variablen ermöglicht.
  • Das Makro „static_assert!“ wurde neu geschrieben und ermöglicht die Verwendung von „core::assert!()“ in jedem Kontext anstelle von Konstanten.
  • Makro „build_error!“ angepasst, um zu funktionieren, wenn der Modus „RUST_BUILD_ASSERT_{WARN,ALLOW}“ für Module eingestellt ist.
  • Eine separate Datei mit den Einstellungen „kernel/configs/rust.config“ hinzugefügt.
  • Die bei Makroersetzungen verarbeiteten „*.i“-Dateien wurden in „*.rsi“ umbenannt.
  • Die Unterstützung für die Erstellung von Rust-Komponenten mit anderen Optimierungsstufen als denen für C-Code wurde eingestellt.
  • fs-Modul hinzugefügt, das Bindungen für die Arbeit mit Dateisystemen bereitstellt. Es wird ein Beispiel für ein einfaches in Rust geschriebenes Dateisystem bereitgestellt.
  • Workqueue-Modul für die Arbeit mit Systemwarteschlangen hinzugefügt (stellt Bindungen über die Kernelstrukturen work_struct und workqueue_struct bereit).
  • Die Entwicklung des kasync-Moduls wurde mit der Implementierung asynchroner Programmiermethoden (async) fortgesetzt. Ein Beispiel für einen in Rust geschriebenen TCP-Server auf Kernebene hinzugefügt.
  • Es wurde die Möglichkeit hinzugefügt, Interrupts in der Sprache Rust mithilfe der Typen „[Threaded]Handler“ und „[Threaded]Registration“ zu verarbeiten.
  • Das prozedurale Makro „#[vtable]“ wurde hinzugefügt, um die Arbeit mit Tabellen mit Funktionszeigern, wie z. B. der Struktur „file_operations“, zu erleichtern.
  • Implementierung bidirektionaler verknüpfter Listen „unsafe_list::List“ hinzugefügt.
  • Anfängliche Unterstützung für RCU (Read-Copy-Update) und Guard-Typ hinzugefügt, um zu prüfen, ob eine Lesesperre an den aktuellen Thread gebunden ist.
  • Funktion Task::spawn() hinzugefügt, um Kernel-Threads zu erstellen und automatisch zu starten. Außerdem wurde die Methode Task::wake_up() hinzugefügt.
  • Es wurde ein Verzögerungsmodul hinzugefügt, mit dem Sie Verzögerungen verwenden können (ein Wrapper über msleep()).

Die vorgeschlagenen Änderungen ermöglichen die Verwendung von Rust als Zweitsprache für die Entwicklung von Treibern und Kernelmodulen. Die Rust-Unterstützung wird als Option dargestellt, die standardmäßig nicht aktiviert ist und nicht dazu führt, dass Rust als erforderliche Build-Abhängigkeit für den Kernel einbezogen wird. Durch die Verwendung von Rust für die Treiberentwicklung können Sie mit minimalem Aufwand sicherere und bessere Treiber erstellen, ohne Probleme wie Speicherzugriff nach der Freigabe, Nullzeiger-Dereferenzierungen und Pufferüberläufe.

Die speichersichere Handhabung wird in Rust zur Kompilierungszeit durch Referenzprüfung, Verfolgung des Objektbesitzes und der Objektlebensdauer (Umfang) sowie durch die Bewertung der Korrektheit des Speicherzugriffs während der Codeausführung gewährleistet. Rust bietet außerdem Schutz vor Ganzzahlüberläufen, erfordert eine obligatorische Initialisierung von Variablenwerten vor der Verwendung, behandelt Fehler in der Standardbibliothek besser, wendet standardmäßig das Konzept unveränderlicher Referenzen und Variablen an und bietet starke statische Typisierung, um logische Fehler zu minimieren.

Source: opennet.ru

Kommentar hinzufügen