hyperion/20-dev/00-rust/10-no_std/Untitled.md
2025-12-28 19:00:03 +03:00

131 lines
No EOL
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Ты задал отличный вопрос, который вскрывает один из самых интересных нюансов системного программирования.
Действительно, **Moss kernel** (и некоторые другие проекты вроде *Hubris* от Oxide) используют `async/await` прямо внутри ядра. Это не противоречие, а смена подхода к тому, что такое «многозадачность ядра».
Давай разберем, почему они так сделали и почему это отличается от того `async`, который мы используем в вебе.
### 1. Ядро — это и есть «самый большой асинхронный рантайм»
Подумай, что делает ядро ОС:
1. Ждет нажатия клавиши (прерывание).
2. Ждет, пока диск дочитает сектор (DMA).
3. Ждет пакета от сетевой карты.
Традиционные ядра (Linux, Windows) решают это через сложную систему прерываний, колбэков, workqueues и конечных автоматов, написанных вручную на C. Это сложно читать и легко ошибиться.
**В чем идея Moss:**
Вместо того чтобы писать эти конечные автоматы (state machines) вручную, они используют Rust-компилятор.
* `async fn read_disk()` в ядре Moss — это не запуск Tokio. Это способ сказать компилятору: «сгенерируй для меня state machine, которая приостановится, пока контроллер диска не пришлет прерывание».
* Это позволяет писать драйверы так, будто код выполняется линейно, хотя на самом деле он разбит на микро-кусочки, ожидающие железа.
### 2. Async в ядре != Async в вебе
В Moss нет «тяжелого» рантайма типа Tokio.
* **В вебе (Tokio):** Рантайм использует потоки ОС (threads), work-stealing, и сложные очереди, чтобы утилизировать все ядра CPU.
* **В ядре (Moss/no_std):** `Executor` — это часть планировщика ядра. Он очень примитивный.
* Когда драйвер делает `.await`, он просто говорит планировщику: «Не буди меня, пока не сработает вот это прерывание».
* Это **Cooperative Multitasking** (кооперативная многозадачность) внутри ядра. Это *дешевле*, чем создавать отдельный поток ядра (kernel thread) для каждого драйвера.
### 3. Почему это круто (Best Practices & Philosophy)
Использование `async` в ядре решает проблему **Complexity Management**.
* **Без async:** Ты пишешь обработчик прерывания, который ставит флаг, потом таймер, который проверяет флаг, потом функцию, которая доделывает работу... Код размазан по файлу.
* **С async:** Ты пишешь:
```rust
// Псевдокод драйвера в Moss
async fn handle_packet() {
let header = nic.wait_for_header().await; // Ждем железо
let data = nic.dma_read(header.len).await; // Ждем DMA
process(data);
}
```
Логика линейна. Компилятор сам нарежет это на состояния. Это безопаснее и понятнее.
### Резюме для менти
То, что Moss написан на async — это **не про производительность** (как в Nginx/Tokio), а про **эргономику кода драйверов**.
* Они используют `async/await` как синтаксический сахар для управления сложными конечными автоматами железа.
* Для твоих задач (Backend/Systems Tools) правило остается прежним: если ты не пишешь ядро или встроенное ПО для микроконтроллера (Embedded Rust), выбирай инструмент по задаче (I/O -> Async, CPU -> Sync).
В ядре они *вынуждены* быть асинхронными, потому что железо асинхронно по своей природе. Rust просто дал им удобный синтаксис для этого.
[1](https://github.com/hexagonal-sun/moss-kernel)
[2](https://www.reddit.com/r/rust/comments/1p2dhex/moss_a_rust_linuxcompatible_kernel_in_about_26000/)
[3](https://news.ycombinator.com/item?id=46012803)
[4](https://www.alm.com/press_release/alm-intelligence-updates-verdictsearch/?s-news-13792569-2025-11-28-moss-a-rust-based-linux-compatible-kernel-developed-in-26000-lines-of-code)
[5](https://prohoster.info/en/blog/novosti-interneta/proekt-moss-razvivaet-linux-sovmestimoe-yadro-na-yazyke-rust)
[6](https://rust-lang.github.io/async-book/01_getting_started/02_why_async.html)
[7](https://www.reddit.com/r/rust/comments/130hcbc/how_does_async_rust_work/)
[8](https://news.ycombinator.com/item?id=20738606)
[9](https://www.youtube.com/watch?v=RVFI1NRhhCg)
[10](https://www.wyeworks.com/blog/2025/02/25/async-rust-when-to-use-it-when-to-avoid-it/)
[11](https://os.phil-opp.com/async-await/)
[12](https://kobzol.github.io/rust/2025/01/15/async-rust-is-about-concurrency.html)
[13](https://www.osnews.com/story/143918/moss-a-linux-compatible-kernel-written-in-rust/)
[14](https://news.ycombinator.com/item?id=46077481)
[15](https://www.reddit.com/r/rust/comments/1ax32ot/how_is_asynchronous_programming_implemented_under/)
[16](https://www.reddit.com/r/rust/comments/1gvmtok/asyncawait_is_real_and_can_hurt_you/)
[17](https://www.facebook.com/nixcraft/posts/moss-is-a-unix-like-linux-compatible-kernel-written-in-rust-and-aarch64-assembly/1272741511551520/)
[18](https://without.boats/blog/why-async-rust/)
[19](https://news.ycombinator.com/item?id=22729461)
[20](https://www.reddit.com/r/rust/comments/ec1bnu/what_are_the_common_use_cases_of_async_await/)
Это отличный вопрос, который показывает, что ты начинаешь мыслить архитектурно.
**Короткий ответ: В Redox OS изначально не было `async/await`, но сейчас он внедряется — но иначе, чем в Moss.**
В Moss `async/await` — это **основа ядра** (монолитный подход к драйверам внутри ядра). В Redox OS — это **инструмент для драйверов в userspace** и оптимизации системных вызовов (через `io_uring`).
Вот подробности, почему так и в чем разница:
### 1. Архитектура диктует инструменты
* **Moss Kernel:** Это (в основном) монолитный подход в плане исполнения драйверов. Драйверы работают в пространстве ядра. Чтобы они не блокировали ядро, используется кооперативная многозадачность через `async`.
* **Redox OS:** Это **микроядро**.
* Драйверы — это обычные процессы (userspace daemons).
* Файловая система — это процесс.
* Сетевой стек — это процесс.
* Ядро очень маленькое, его задача — перекладывать сообщения (Message Passing) между процессами.
### 2. Как работает Redox (Схемы vs Async)
В Redox все построено на концепции **URL Schemes** (`file:`, `tcp:`, `http:`).
Изначально Redox использовал блокирующие системные вызовы. Процесс делает `read()`, ядро блокирует его, посылает сообщение драйверу, ждет ответа.
**Почему это стало проблемой?**
В userspace-драйверах это неудобно. Если драйвер сетевой карты обрабатывает 1000 пакетов, ему нужно либо 1000 потоков (дорого), либо сложный event loop (сложно).
**Что изменилось (2024-2025):**
Redox активно внедряет поддержку асинхронности, вдохновляясь Linux `io_uring`.
1. **Userspace Drivers:** Драйверы в Redox начинают переписывать на `async/await`, чтобы они могли эффективно обрабатывать очереди сообщений от ядра, не плодя потоки.
2. **Kernel Interface:** Ядро учится принимать "пачки" запросов асинхронно, чтобы уменьшить оверхед на переключение контекста (syscall overhead), который в микроядрах всегда высок.
### 3. Сравнение подходов (Mental Model)
| Характеристика | Moss Kernel | Redox OS |
| :--- | :--- | :--- |
| **Где живет Async?** | Внутри ядра (Kernel Space). | В драйверах (User Space) + интерфейс ядра. |
| **Роль Async** | Замена прерываниям и сложным State Machines железа. | Оптимизация Message Passing между процессами. |
| **Аналогия** | Как JavaScript в браузере (Single thread, non-blocking). | Как микросервисы (gRPC), которые общаются асинхронно. |
### Вывод для тебя
Redox не *написан* на async так тотально, как Moss. Redox — это про изоляцию. Но он *использует* async там, где это нужно для производительности I/O.
Если ты хочешь поковырять **"Async в ядре"** — смотри Moss или **Embassy** (для embedded).
Если хочешь понять **"Async в системной архитектуре"** (как построить ОС из микросервисов) — смотри Redox.
[1](https://www.redox-os.org/news/io_uring-3/)
[2](https://www.reddit.com/r/rust/comments/1ax32ot/how_is_asynchronous_programming_implemented_under/)
[3](https://users.rust-lang.org/t/state-of-async-await-unrestrained-cooperation-is-not-cooperative/131119)
[4](https://news.ycombinator.com/item?id=22729461)
[5](https://news.ycombinator.com/item?id=22727985)
[6](https://www.redox-os.org/news/io_uring-5/)
[7](http://wiki.osdev.org/Message_Passing)
[8](https://os.phil-opp.com/async-await/)
[9](https://www.webpronews.com/redox-os-roadmap-rust-driven-speed-boosts-to-challenge-linux/)
[10](https://docs.redoxengine.com/basics/data-exchange-with-redox/process-async-traffic-with-child-queues/)
[11](https://www.youtube.com/watch?v=0HwrZp9CBD4)
[12](https://stackoverflow.com/questions/7931537/whats-the-difference-between-asynchronous-non-blocking-event-base-architectu)
[13](https://www.osnews.com/story/29463/a-complete-rewrite-of-the-redox-kernel/)
[14](https://github.com/redox-os/drivers)
[15](https://news.ycombinator.com/item?id=21657744)
[16](https://news.ycombinator.com/item?id=18274235)
[17](https://www.redox-os.org/news/this-week-in-redox-25/)
[18](https://www.redox-os.org/news/io_uring-4/)
[19](https://github.com/bendudson/EuraliOS)
[20](https://www.reddit.com/r/rust/comments/128048k/asyncawait_in_action_rustbased_kernel_with/)