Rust for Linux: Linux device driver development in Rust
Meyer, Elias (2024)
Meyer, Elias
2024
Tietotekniikan DI-ohjelma - Master's Programme in Information Technology
Informaatioteknologian ja viestinnän tiedekunta - Faculty of Information Technology and Communication Sciences
This publication is copyrighted. You may download, display and print it for Your own personal use. Commercial use is prohibited.
Hyväksymispäivämäärä
2024-10-01
Julkaisun pysyvä osoite on
https://urn.fi/URN:NBN:fi:tuni-202405155888
https://urn.fi/URN:NBN:fi:tuni-202405155888
Tiivistelmä
The development of Linux began in the 90s. At the time, C was the most powerful and modern programming language. However, C's origins go back to the 1970s, which is reflected particularly into the cumbersome and error-prone software development, which in turn leads to the constant discovery of new security vulnerabilities.
Rust is a modern systems programming language which aims to improve on the weaknesses of C and C++, especially in terms of memory management, while maintaining the performance advantage. In recent years, large IT companies have begun to take an interest in Rust after realizing its advantages. In addition to efficiency, these include a high level of abstraction, which speeds up software development. The security in memory management prevents security vulnerabilities by preventing buffer overflows. A good memory management also allows for easy and efficient concurrency. Rust's modern development environment with package management, a built-in linter and a documentation creation tool facilitates software development.
Officially, Rust support was added into Linux in December 2022 in version 6.1. There is no intention to rewrite Linux, but only to make it possible for new device drivers to be written in Rust. Linux developers hope that the modern programming language will make it easier to maintain new drivers, reduce security problems and encourage new developers to contribute to Linux.
The purpose of this thesis was first to evaluate and implement a device driver using Rust for an embedded system of Wapice Ltd. Unfortunately, due to the lack of a needed API on Linux, it was not yet economically feasible. Linux still lacks many interfaces which allow device drivers to be easily written in Rust \- currently, the device driver author has to create the interfaces very likely themself. For this reason, the purpose of this thesis shifted to exploring the scope of Rust support in the form of a literature review: what has already been written in Rust so far, and what benefits and problems have been identified in _Rust for Linux_.
The work presents six existing device drivers written in Rust and collects both the advantages and disadvantages reported by their authors. The device drivers are very different from each other: there are a few block device drivers such as the NVMe driver, a network device driver for a physical ethernet controller, an inter process communication bus for Android called the Binder, as well as GPU drivers for Apple and Nvidia graphics cards. The work will compare the differences between these drivers and the corresponding C drivers, if available. For example, for the NVMe driver the efficiency between the Rust and C versions of the driver are compared while for the Binder driver both the efficiency and the object file size are compared. This paper also presents two identified major challenges raised by _Rust for Linux_, and discusses their possible and most likely solutions.
The literature review shows that when implemented in Rust, the drivers are slightly slower than their C counterparts, and the size comparison shows that the device drivers implemented in Rust are slightly larger. However, the differences are not significant compared to the advantages of Rust, making it an excellent choice for programming device drivers on Linux. Linuxin kehitys aloitettiin 90-luvulla, jolloin C oli tehokkain ja modernein ohjelmointikieli. C sai kuitenkin alkunsa jo 70-luvulla, mikä näkyy ohjelmistokehityksen kankeutena sekä virhealttiutena käytettäessä C:tä. Virhealttius näkyy esimerkiksi jatkuvasti löytyvinä tietoturvaongelmina.
Rust on moderni järjestelmäohjelmointikieli, joka pyrkii parantamaan C:n ja C++:n heikkouksia etenkin muistinhallinnan suhteen, säilyttäen kuitenkin näiden kielien edun suorituskyvyssä. Monien etujensa ansiosta Rust on viime vuosina alkanut herättää yhä useamman suuren tietotekniikka-alan yrityksen mielenkiinnon. Etuihin lukeutuu tehokkuuden lisäksi korkea abstraktiotaso, joka nopeuttaa ohjelmistokehitystä. Muistinhallinnan varmuus taas ennaltaehkäisee puskurien ylivuotoja, jotka ovat usein tietoturva-aukkojen perimmäisiä syitä. Hyvä muistinhallinta myös mahdollistaa käyttäjille helpompaa ja tehokkaampaa rinnakkaisuutta, koska suurin osa rinnakkaisuusongelmista on pohjimmiltaan muistinhallintaongelmia. Moderni kehitysympäristö pakettienhallinnan sekä sisäänrakennetun koodin jäsentely- ja dokumentaatiotyökalun kanssa helpottaa omalta osaltaan ohjelmistokehitystä Rustilla.
Virallisesti Rust-tuki tuli Linuxiin joulukuussa 2022 versiossa 6.1. Linuxia ei ole tarkoitus kirjoittaa uudelleen, vaan tuen on tarkoitus ainoastaan mahdollistaa uusien laiteajurien kehittäminen Rustilla. Linuxin kehittäjät toivovat modernin ohjelmointikielen helpottavan uusien laiteajurien ylläpitoa, vähentävän niissä esiintyviä tietoturvaongelmia ja herättää uusien kehittäjien kiinostusta Linuxiin.
Työn tarkoitus oli aluksi arvioida laiteajurin kehitystä Wapice Oy:n sulautettuun järjestelmään Rustilla ja toteuttaa se. Valitettavasti Linuxin Rust-tuen puutteellisuuden vuoksi sen tekeminen ei ollut vielä taloudellisesti hyödyllistä. Linuxista puuttuu vielä monia rajapintoja, joiden avulla laiteajureita voidaan helposti kehittää Rustilla - nykyisellään laiteajurin tekijä joutuu hyvin todennäköisesti tekemään rajapinnat itse. Tästä syystä työn tarkoitus siirtyi Rust-tuen laajuuden tutkimiseen kirjallisuuskatsauksen muodossa: mitä kaikkea tähän mennessä ollaan jo tehty Rustilla Linuxiin ja mitä hyötyjä tai ongelmia Rustissa ollaan havaittu Linuxin suhteen.
Työssä esitellään kuusi olemassa olevaa Rustilla kirjoitettua laiteajuria ja kootaan niiden tekijöiden raportoimia kokemuksia niin eduista kuin haitoistakin. Laiteajurit ovat keskenään hyvin erilaisia: mukaan mahtuu muun muassa muutamia lohkolaiteajureita kuten NVMe-ajuri, verkkolaiteajuri Ethernet-ohjaimelle, Androidin prosessikommunikaatioväylänä toimiva Binder sekä lisäksi Applen ja Nvidian näytönohjainajureita. Työssä vertaillaan näiden ajurien eroja vastaaviin C:llä kirjoitettuihin ajureihin, mikäli sellaiset ovat saatavilla. Esimerkiksi NVMe-ajurissa vertaillaan ajurien välistä tehokkuutta, kun taas Binder-ajurissa vertaillaan sekä tehokkuutta että objektitiedoston kokoa. Tässä työssä esitellään myös kaksi suurta Rust-tuen esille tuomaa ongelmaa Linuxissa ja keskustellaan niiden mahdollisista ja todennäköisimmistä ratkaisuista.
Kirjallisuuskatsauksessa käy ilmi, että Rustilla toteutettuna ajurit ovat hieman vastaavia C-toteutuksiaan hitaampia. Kokovertailussa selviää, että Rustilla tehdyt laiteajurit ovat hieman suurempia. Erot eivät kuitenkaan ole merkittäviä Rustin muihin etuihin verrattuna, mikä tekee Rustista erinomaisen vaihtoehdon laiteajurien ohjelmointiin Linuxissa.
Rust is a modern systems programming language which aims to improve on the weaknesses of C and C++, especially in terms of memory management, while maintaining the performance advantage. In recent years, large IT companies have begun to take an interest in Rust after realizing its advantages. In addition to efficiency, these include a high level of abstraction, which speeds up software development. The security in memory management prevents security vulnerabilities by preventing buffer overflows. A good memory management also allows for easy and efficient concurrency. Rust's modern development environment with package management, a built-in linter and a documentation creation tool facilitates software development.
Officially, Rust support was added into Linux in December 2022 in version 6.1. There is no intention to rewrite Linux, but only to make it possible for new device drivers to be written in Rust. Linux developers hope that the modern programming language will make it easier to maintain new drivers, reduce security problems and encourage new developers to contribute to Linux.
The purpose of this thesis was first to evaluate and implement a device driver using Rust for an embedded system of Wapice Ltd. Unfortunately, due to the lack of a needed API on Linux, it was not yet economically feasible. Linux still lacks many interfaces which allow device drivers to be easily written in Rust \- currently, the device driver author has to create the interfaces very likely themself. For this reason, the purpose of this thesis shifted to exploring the scope of Rust support in the form of a literature review: what has already been written in Rust so far, and what benefits and problems have been identified in _Rust for Linux_.
The work presents six existing device drivers written in Rust and collects both the advantages and disadvantages reported by their authors. The device drivers are very different from each other: there are a few block device drivers such as the NVMe driver, a network device driver for a physical ethernet controller, an inter process communication bus for Android called the Binder, as well as GPU drivers for Apple and Nvidia graphics cards. The work will compare the differences between these drivers and the corresponding C drivers, if available. For example, for the NVMe driver the efficiency between the Rust and C versions of the driver are compared while for the Binder driver both the efficiency and the object file size are compared. This paper also presents two identified major challenges raised by _Rust for Linux_, and discusses their possible and most likely solutions.
The literature review shows that when implemented in Rust, the drivers are slightly slower than their C counterparts, and the size comparison shows that the device drivers implemented in Rust are slightly larger. However, the differences are not significant compared to the advantages of Rust, making it an excellent choice for programming device drivers on Linux.
Rust on moderni järjestelmäohjelmointikieli, joka pyrkii parantamaan C:n ja C++:n heikkouksia etenkin muistinhallinnan suhteen, säilyttäen kuitenkin näiden kielien edun suorituskyvyssä. Monien etujensa ansiosta Rust on viime vuosina alkanut herättää yhä useamman suuren tietotekniikka-alan yrityksen mielenkiinnon. Etuihin lukeutuu tehokkuuden lisäksi korkea abstraktiotaso, joka nopeuttaa ohjelmistokehitystä. Muistinhallinnan varmuus taas ennaltaehkäisee puskurien ylivuotoja, jotka ovat usein tietoturva-aukkojen perimmäisiä syitä. Hyvä muistinhallinta myös mahdollistaa käyttäjille helpompaa ja tehokkaampaa rinnakkaisuutta, koska suurin osa rinnakkaisuusongelmista on pohjimmiltaan muistinhallintaongelmia. Moderni kehitysympäristö pakettienhallinnan sekä sisäänrakennetun koodin jäsentely- ja dokumentaatiotyökalun kanssa helpottaa omalta osaltaan ohjelmistokehitystä Rustilla.
Virallisesti Rust-tuki tuli Linuxiin joulukuussa 2022 versiossa 6.1. Linuxia ei ole tarkoitus kirjoittaa uudelleen, vaan tuen on tarkoitus ainoastaan mahdollistaa uusien laiteajurien kehittäminen Rustilla. Linuxin kehittäjät toivovat modernin ohjelmointikielen helpottavan uusien laiteajurien ylläpitoa, vähentävän niissä esiintyviä tietoturvaongelmia ja herättää uusien kehittäjien kiinostusta Linuxiin.
Työn tarkoitus oli aluksi arvioida laiteajurin kehitystä Wapice Oy:n sulautettuun järjestelmään Rustilla ja toteuttaa se. Valitettavasti Linuxin Rust-tuen puutteellisuuden vuoksi sen tekeminen ei ollut vielä taloudellisesti hyödyllistä. Linuxista puuttuu vielä monia rajapintoja, joiden avulla laiteajureita voidaan helposti kehittää Rustilla - nykyisellään laiteajurin tekijä joutuu hyvin todennäköisesti tekemään rajapinnat itse. Tästä syystä työn tarkoitus siirtyi Rust-tuen laajuuden tutkimiseen kirjallisuuskatsauksen muodossa: mitä kaikkea tähän mennessä ollaan jo tehty Rustilla Linuxiin ja mitä hyötyjä tai ongelmia Rustissa ollaan havaittu Linuxin suhteen.
Työssä esitellään kuusi olemassa olevaa Rustilla kirjoitettua laiteajuria ja kootaan niiden tekijöiden raportoimia kokemuksia niin eduista kuin haitoistakin. Laiteajurit ovat keskenään hyvin erilaisia: mukaan mahtuu muun muassa muutamia lohkolaiteajureita kuten NVMe-ajuri, verkkolaiteajuri Ethernet-ohjaimelle, Androidin prosessikommunikaatioväylänä toimiva Binder sekä lisäksi Applen ja Nvidian näytönohjainajureita. Työssä vertaillaan näiden ajurien eroja vastaaviin C:llä kirjoitettuihin ajureihin, mikäli sellaiset ovat saatavilla. Esimerkiksi NVMe-ajurissa vertaillaan ajurien välistä tehokkuutta, kun taas Binder-ajurissa vertaillaan sekä tehokkuutta että objektitiedoston kokoa. Tässä työssä esitellään myös kaksi suurta Rust-tuen esille tuomaa ongelmaa Linuxissa ja keskustellaan niiden mahdollisista ja todennäköisimmistä ratkaisuista.
Kirjallisuuskatsauksessa käy ilmi, että Rustilla toteutettuna ajurit ovat hieman vastaavia C-toteutuksiaan hitaampia. Kokovertailussa selviää, että Rustilla tehdyt laiteajurit ovat hieman suurempia. Erot eivät kuitenkaan ole merkittäviä Rustin muihin etuihin verrattuna, mikä tekee Rustista erinomaisen vaihtoehdon laiteajurien ohjelmointiin Linuxissa.