feat: ajouter character_device_in_rust.rs avec miscdev #10

Merged
florian.richer merged 1 commit from openclaw/kernel_module_learn:feat/char-device-rust-miscdev into main 2026-03-21 20:20:58 +01:00
Member

Version Rust du character device utilisant l'API miscdevice kernel 6.19.

Basé sur samples/rust/rust_misc_device.rs (source officielle kernel 6.19).

Avantages vs C

  • Pas de gestion manuelle des numéros majeurs, class_create, device_create
  • Mutex via new_mutex! + pin_data (safe, pinned)
  • KVVec<u8> pour le buffer — alloué dynamiquement, pas de taille fixe sur la pile
  • Cleanup automatique via PinnedDrop sur FloDevData
  • InPlaceModule + try_pin_init! pour initialisation correctement pinnée

Références

Notes

MiscDeviceRegistration::register() crée /dev/flodev automatiquement.

Compile sur kernel 6.19.8. Non testé à l'exécution (desync nixpkgs/OS).

Ref #1

Version Rust du character device utilisant l'API `miscdevice` kernel 6.19. Basé sur [`samples/rust/rust_misc_device.rs`](https://elixir.bootlin.com/linux/v6.19/source/samples/rust/rust_misc_device.rs) (source officielle kernel 6.19). ## Avantages vs C - Pas de gestion manuelle des numéros majeurs, `class_create`, `device_create` - `Mutex` via `new_mutex!` + `pin_data` (safe, pinned) - `KVVec<u8>` pour le buffer — alloué dynamiquement, pas de taille fixe sur la pile - Cleanup automatique via `PinnedDrop` sur `FloDevData` - `InPlaceModule` + `try_pin_init!` pour initialisation correctement pinnée ## Références - [`kernel::miscdevice`](https://elixir.bootlin.com/linux/v6.19/source/rust/kernel/miscdevice.rs) - [`kernel::iov`](https://elixir.bootlin.com/linux/v6.19/source/rust/kernel/iov.rs) - [`kernel::fs::Kiocb`](https://elixir.bootlin.com/linux/v6.19/source/rust/kernel/fs/kiocb.rs) ## Notes `MiscDeviceRegistration::register()` crée `/dev/flodev` automatiquement. Compile sur kernel 6.19.8. Non testé à l'exécution (desync nixpkgs/OS). Ref #1
Version Rust du character device utilisant l'API miscdev kernel.

Avantages vs C :
- Pas de gestion manuelle des numéros majeurs, class_create, device_create
- Mutex intégré via kernel::sync::Mutex (pas besoin de DEFINE_MUTEX)
- Vérification de dépassement de buffer à la compilation (slice bounds)
- Cleanup automatique via Drop

Note: miscdev::Registration::new_pinned() crée /dev/flodev automatiquement.
Le buffer est protégé par un Mutex<([u8; 256], usize)>.

[DRAFT - non testé à la compilation, API miscdev Rust à vérifier sur linux_latest]
openclaw force-pushed feat/char-device-rust-miscdev from 0d479195d3 to 1ce0126a43 2026-03-21 19:38:17 +01:00 Compare
Author
Member

@florian.richer PR mise à jour pour kernel 6.19 :

  • IoBufferReader/IoBufferWriter remplacés par UserSliceReader/UserSliceWriter depuis kernel::uaccess (changement introduit ~6.14)

Toujours à tester à la compilation — si miscdev::Registration::new_pinned ou la signature de Operations::read/write a encore changé en 6.19, dis-moi l'erreur de compilation et je corrige.

@florian.richer PR mise à jour pour kernel 6.19 : - `IoBufferReader`/`IoBufferWriter` remplacés par `UserSliceReader`/`UserSliceWriter` depuis `kernel::uaccess` (changement introduit ~6.14) Toujours à tester à la compilation — si `miscdev::Registration::new_pinned` ou la signature de `Operations::read`/`write` a encore changé en 6.19, dis-moi l'erreur de compilation et je corrige.
florian.richer changed title from feat: ajouter character_device_in_rust.rs avec miscdev to WIP: feat: ajouter character_device_in_rust.rs avec miscdev 2026-03-21 19:52:17 +01:00
openclaw force-pushed feat/char-device-rust-miscdev from 1ce0126a43 to 2a3509e0ed 2026-03-21 19:57:36 +01:00 Compare
Author
Member

@florian.richer PR mise à jour — réécriture complète basée sur samples/rust/rust_misc_device.rs (source officielle kernel) :

Erreurs corrigées :

  • kernel::file / kernel::miscdevkernel::miscdevice + imports corrects
  • Arc/ArcBorrowPin<KBox<Self>> (pattern officiel)
  • Operations → trait MiscDevice avec #[vtable]
  • IoBufferReader/IoBufferWriterIovIterDest/IovIterSource + Kiocb
  • ModuleInPlaceModule + try_pin_init!
  • Buffer [u8; 256]KVVec<u8> + new_mutex!

À tester à la compilationKVVec et simple_read_from_buffer sont présents en 6.19 mais leur disponibilité hors arbre peut varier selon la config kernel (CONFIG_RUST=y requis).

@florian.richer PR mise à jour — réécriture complète basée sur `samples/rust/rust_misc_device.rs` (source officielle kernel) : **Erreurs corrigées :** - `kernel::file` / `kernel::miscdev` → `kernel::miscdevice` + imports corrects - `Arc`/`ArcBorrow` → `Pin<KBox<Self>>` (pattern officiel) - `Operations` → trait `MiscDevice` avec `#[vtable]` - `IoBufferReader`/`IoBufferWriter` → `IovIterDest`/`IovIterSource` + `Kiocb` - `Module` → `InPlaceModule` + `try_pin_init!` - Buffer `[u8; 256]` → `KVVec<u8>` + `new_mutex!` **À tester à la compilation** — `KVVec` et `simple_read_from_buffer` sont présents en 6.19 mais leur disponibilité hors arbre peut varier selon la config kernel (`CONFIG_RUST=y` requis).
openclaw force-pushed feat/char-device-rust-miscdev from 2a3509e0ed to f0b0edb3ba 2026-03-21 20:01:58 +01:00 Compare
openclaw force-pushed feat/char-device-rust-miscdev from f0b0edb3ba to 2ac674924d 2026-03-21 20:03:35 +01:00 Compare
Author
Member

@florian.richer Récap des 2 derniers patchs :

Patch 1 — Réécriture complète pour kernel 6.19
La première version utilisait une ancienne API. Réécriture basée sur samples/rust/rust_misc_device.rs :

  • kernel::miscdevice (pas miscdev) → source
  • InPlaceModule + try_pin_init! à la place de Module + Box
  • MiscDevice trait avec #[vtable]
  • read_iter/write_iter avec Kiocb + IovIterDest/IovIterSourcesource
  • KVVec<u8> + new_mutex! + Pin<KBox<Self>>

Patch 2 — Suppression du impl Drop sur CharDeviceModule
#[pin_data] génère un trait interne MustNotImplDrop qui interdit un impl Drop direct sur la struct. Suppression du Drop de CharDeviceModule — le message de déchargement reste dans PinnedDrop de FloDevData.

@florian.richer Récap des 2 derniers patchs : **Patch 1 — Réécriture complète pour kernel 6.19** La première version utilisait une ancienne API. Réécriture basée sur [`samples/rust/rust_misc_device.rs`](https://elixir.bootlin.com/linux/v6.19/source/samples/rust/rust_misc_device.rs) : - `kernel::miscdevice` (pas `miscdev`) → [source](https://elixir.bootlin.com/linux/v6.19/source/rust/kernel/miscdevice.rs) - `InPlaceModule` + `try_pin_init!` à la place de `Module` + `Box` - `MiscDevice` trait avec `#[vtable]` - `read_iter`/`write_iter` avec `Kiocb` + `IovIterDest`/`IovIterSource` → [source](https://elixir.bootlin.com/linux/v6.19/source/rust/kernel/iov.rs) - `KVVec<u8>` + `new_mutex!` + `Pin<KBox<Self>>` **Patch 2 — Suppression du `impl Drop` sur `CharDeviceModule`** `#[pin_data]` génère un trait interne `MustNotImplDrop` qui interdit un `impl Drop` direct sur la struct. Suppression du `Drop` de `CharDeviceModule` — le message de déchargement reste dans `PinnedDrop` de `FloDevData`.
openclaw force-pushed feat/char-device-rust-miscdev from 2ac674924d to 5b4d74b503 2026-03-21 20:14:54 +01:00 Compare
Author
Member

@florian.richer Dernier patch — ajout de ARef<Device> + dev_info! :

Ce qui a changé :

  • Ajout de dev: ARef<Device> dans FloDevData (récupéré via misc.device() dans open)
  • Remplacement de tous les pr_info! par dev_info!(me.dev, ...) — les logs sont maintenant préfixés avec le nom du device (flodev:) au lieu d'un simple [module_name]
  • kernel::sync::aref::ARef et kernel::device::Device ajoutés aux imports

Pourquoi dev_info! plutôt que pr_info! ?
Comme dans le sample officiel (rust_misc_device.rs), dev_info! préfixe le message avec le device concerné — plus utile pour debugger quand plusieurs devices sont actifs. pr_info! n'a pas ce contexte.


Explication de iov.copy_from_iter_vec(&mut inner.buf, GFP_KERNEL) :

Copie les données depuis l'espace utilisateur (passées via write()) dans le KVVec<u8> kernel :

  • iov — itérateur sur les données userspace du write()
  • copy_from_iter_vec — lit depuis iov et appende dans le vecteur (vérifie les pointeurs userspace automatiquement)
  • GFP_KERNEL — flag d'allocation mémoire (allocation normale, peut dormir)
  • inner.buf.clear() juste avant — remplace le contenu plutôt que d'appender

Équivalent Rust de copy_from_user(buf, user_buf, len) en C, mais safe par construction.

@florian.richer Dernier patch — ajout de `ARef<Device>` + `dev_info!` : **Ce qui a changé :** - Ajout de `dev: ARef<Device>` dans `FloDevData` (récupéré via `misc.device()` dans `open`) - Remplacement de tous les `pr_info!` par `dev_info!(me.dev, ...)` — les logs sont maintenant préfixés avec le nom du device (`flodev:`) au lieu d'un simple `[module_name]` - `kernel::sync::aref::ARef` et `kernel::device::Device` ajoutés aux imports **Pourquoi `dev_info!` plutôt que `pr_info!` ?** Comme dans le sample officiel ([`rust_misc_device.rs`](https://elixir.bootlin.com/linux/v6.19/source/samples/rust/rust_misc_device.rs)), `dev_info!` préfixe le message avec le device concerné — plus utile pour debugger quand plusieurs devices sont actifs. `pr_info!` n'a pas ce contexte. --- **Explication de `iov.copy_from_iter_vec(&mut inner.buf, GFP_KERNEL)` :** Copie les données depuis l'espace utilisateur (passées via `write()`) dans le `KVVec<u8>` kernel : - `iov` — itérateur sur les données userspace du `write()` - `copy_from_iter_vec` — lit depuis `iov` et appende dans le vecteur (vérifie les pointeurs userspace automatiquement) - `GFP_KERNEL` — flag d'allocation mémoire (allocation normale, peut dormir) - `inner.buf.clear()` juste avant — remplace le contenu plutôt que d'appender Équivalent Rust de `copy_from_user(buf, user_buf, len)` en C, mais safe par construction.
Author
Member

@florian.richer Explication de iov.simple_read_from_buffer(kiocb.ki_pos_mut(), &inner.buf) :

Copie les données du buffer kernel vers l'espace utilisateur (appelé lors d'un read()) en tenant compte de la position courante dans le fichier :

  • iov — itérateur de destination vers l'espace utilisateur
  • simple_read_from_buffer — helper kernel qui gère automatiquement :
    • Le calcul de combien de bytes il reste à lire (len - offset)
    • Le retour de 0 si on est déjà en fin de buffer (EOF)
    • La mise à jour de la position après la lecture
  • kiocb.ki_pos_mut() — pointeur vers la position courante dans le fichier (l'offset), passé en &mut pour être mis à jour après la lecture
  • &inner.buf — slice du buffer kernel source

Équivalent Rust du pattern C classique :

if (*offset >= size_of_msg) return 0;
if (copy_to_user(user_buf, msg + *offset, length)) return -EFAULT;
*offset += length;

Mais en une seule ligne safe, sans gestion manuelle des bornes ni copy_to_user explicite.

@florian.richer Explication de `iov.simple_read_from_buffer(kiocb.ki_pos_mut(), &inner.buf)` : Copie les données du buffer kernel vers l'espace utilisateur (appelé lors d'un `read()`) en tenant compte de la position courante dans le fichier : - `iov` — itérateur de destination vers l'espace utilisateur - `simple_read_from_buffer` — helper kernel qui gère automatiquement : - Le calcul de combien de bytes il reste à lire (`len - offset`) - Le retour de `0` si on est déjà en fin de buffer (EOF) - La mise à jour de la position après la lecture - `kiocb.ki_pos_mut()` — pointeur vers la position courante dans le fichier (l'offset), passé en `&mut` pour être mis à jour après la lecture - `&inner.buf` — slice du buffer kernel source Équivalent Rust du pattern C classique : ```c if (*offset >= size_of_msg) return 0; if (copy_to_user(user_buf, msg + *offset, length)) return -EFAULT; *offset += length; ``` Mais en une seule ligne safe, sans gestion manuelle des bornes ni `copy_to_user` explicite.
florian.richer changed title from WIP: feat: ajouter character_device_in_rust.rs avec miscdev to feat: ajouter character_device_in_rust.rs avec miscdev 2026-03-21 20:20:50 +01:00
florian.richer deleted branch feat/char-device-rust-miscdev 2026-03-21 20:20:58 +01:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
JustForFun/kernel_module_learn!10
No description provided.