sync
This commit is contained in:
parent
48f640b55d
commit
440a2fa01f
28 changed files with 1849 additions and 96 deletions
131
20-dev/00-rust/10-no_std/Untitled.md
Normal file
131
20-dev/00-rust/10-no_std/Untitled.md
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
Ты задал отличный вопрос, который вскрывает один из самых интересных нюансов системного программирования.
|
||||
|
||||
Действительно, **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/)
|
||||
|
|
@ -21,6 +21,10 @@ methods:
|
|||
.enumerate()
|
||||
.saturating_sub()
|
||||
.try_fold()
|
||||
.append() // по &mut ссылке
|
||||
.extend() // ownership (removes obj in parantheses)
|
||||
.flatten()
|
||||
.then_some()
|
||||
|
||||
|
||||
crates:
|
||||
|
|
@ -33,8 +37,8 @@ traits:
|
|||
|
||||
```
|
||||
|
||||
|Префикс|Что делает (Технический смысл)|Пример|Стоимость (Cost)|
|
||||
|---|---|---|---|
|
||||
|as_|View / Borrow. Бесплатное преобразование типа, работающее с ссылкой.|as_bytes()|Нулевая (Zero-cost)|
|
||||
|to_|Clone / Allocate. Создает новую копию данных (тяжелая операция).|to_string(),to_vec()|Аллокация памяти|
|
||||
|into_|Consume. Потребляет (съедает) переменную. После этого старая переменная недоступна.|into_iter()|Обычно дешево (перемещение указателя)|
|
||||
| Префикс | Что делает (Технический смысл) | Пример | Стоимость (Cost) |
|
||||
| ------- | ----------------------------------------------------------------------------------- | -------------------- | ------------------------------------- |
|
||||
| as_ | View / Borrow. Бесплатное преобразование типа, работающее с ссылкой. | as_bytes() | Нулевая (Zero-cost) |
|
||||
| to_ | Clone / Allocate. Создает новую копию данных (тяжелая операция). | to_string(),to_vec() | Аллокация памяти |
|
||||
| into_ | Consume. Потребляет (съедает) переменную. После этого старая переменная недоступна. | into_iter() | Обычно дешево (перемещение указателя) |
|
||||
|
|
|
|||
4
20-dev/00-rust/20-dictionary/books.md
Normal file
4
20-dev/00-rust/20-dictionary/books.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Beej's Guide to Network Programming.
|
||||
High Performance Browser Networking
|
||||
Rust in Action
|
||||
TCP/IP Illustrated, Vol. 1: The Protocols
|
||||
75
20-dev/00-rust/50-rust-gdb/cheat-sheet.md
Normal file
75
20-dev/00-rust/50-rust-gdb/cheat-sheet.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
Конечно. Вот сжатая шпаргалка для **rust-gdb** (или чистого GDB), оптимизированная под твой стиль работы (терминал, эффективность, понимание процессов).
|
||||
|
||||
### 🚀 Запуск и База
|
||||
```bash
|
||||
rust-gdb target/debug/my_app # Запуск с отладочными символами
|
||||
rust-gdb --args target/debug/my_app arg1 arg2 # Запуск с аргументами
|
||||
```
|
||||
|
||||
### 🎮 Управление (Control Flow)
|
||||
| Команда | Сокр. | Описание |
|
||||
| :--- | :--- | :--- |
|
||||
| `run` | `r` | Запустить программу с начала |
|
||||
| `continue` | `c` | Продолжить выполнение до следующей точки |
|
||||
| `next` | `n` | **Шагнуть через** (выполнить строку, не заходя в функции) |
|
||||
| `step` | `s` | **Шагнуть внутрь** (зайти внутрь функции на этой строке) |
|
||||
| `finish` | `fin` | Выполнить функцию до конца и вернуться на уровень выше |
|
||||
| `quit` | `q` | Выйти из GDB |
|
||||
|
||||
### 🛑 Точки останова (Breakpoints)
|
||||
| Команда | Описание |
|
||||
| :--- | :--- |
|
||||
| `break main` | Остановиться на входе в `main` |
|
||||
| `break 42` | Остановиться на строке 42 текущего файла |
|
||||
| `break utils.rs:15` | Остановиться в файле `utils.rs` на строке 15 |
|
||||
| `break is_prime if n == 13` | **Условный брейкпоинт** (остановиться, только если n = 13) |
|
||||
| `info break` | Показать список всех точек |
|
||||
| `delete 1` | Удалить точку останова номер 1 |
|
||||
| `clear` | Удалить точку на текущей строке |
|
||||
|
||||
### 🕵️ Инспекция данных
|
||||
| Команда | Сокр. | Описание |
|
||||
| :--- | :--- | :--- |
|
||||
| `print x` | `p` | Вывести значение переменной `x` |
|
||||
| `print/x x` | `p/x` | Вывести в **HEX** (шестнадцатеричном) виде |
|
||||
| `print/t x` | `p/t` | Вывести в **BIN** (двоичном) виде (полезно для битмасок!) |
|
||||
| `display x` | | Автоматически выводить `x` при каждом шаге |
|
||||
| `undisplay 1` | | Перестать следить (по ID из `info display`) |
|
||||
| `info locals` | | Показать все локальные переменные в текущем скоупе |
|
||||
| `ptype x` | | Показать точный тип переменной `x` |
|
||||
|
||||
### 🖥 Визуальный режим (TUI)
|
||||
Это то, что делает GDB похожим на IDE в терминале.
|
||||
* **`Ctrl + X`, `A`** (или команда `layout src`) — Включить TUI (код + консоль).
|
||||
* **`Ctrl + X`, `2`** — Добавить окно ассемблера (код + asm + консоль).
|
||||
* **`Ctrl + L`** — Перерисовать экран (если поплыл вывод).
|
||||
* **`Up`/`Down`** — Скролить код (пока фокус на коде).
|
||||
* **`Ctrl + P` / `Ctrl + N`** — История команд (как в bash).
|
||||
|
||||
### 🛠 Продвинутые фишки
|
||||
* **`backtrace` (`bt`)**: Показать стек вызовов (кто вызвал эту функцию). Критично при панике.
|
||||
* **`frame 2` (`f 2`)**: Прыгнуть в стек-фрейм #2 (в функцию, которая вызвала текущую), чтобы посмотреть её переменные.
|
||||
* **`set var x = 10`**: **Изменить** значение переменной прямо во время выполнения (для тестов "а что если").
|
||||
* **`watch x`**: Остановиться, когда значение `x` **изменится** (hardware watchpoint). Супер для поиска багов, когда "кто-то портит память".
|
||||
|
||||
### 💡 Пример сессии
|
||||
```gdb
|
||||
# 1. Ставим брейк на функцию
|
||||
b miller_rabin
|
||||
# 2. Запускаем
|
||||
r
|
||||
# 3. Включаем красивый вид
|
||||
layout src
|
||||
# 4. Смотрим аргумент
|
||||
p n
|
||||
# 5. Идем по шагам
|
||||
n
|
||||
n
|
||||
# 6. Заходим в mod_pow
|
||||
s
|
||||
# 7. Смотрим биты степени
|
||||
p/t exp
|
||||
```
|
||||
|
||||
$X \cdot X \cdot X \dots$
|
||||
|
||||
1
20-dev/terms.md
Normal file
1
20-dev/terms.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
**Hexagonal Architecture** (также "порты и адаптеры") с четкой экономией зависимостей: `bin → api → api-core → domain ← infrastructure ← entity`. Это не просто модное разделение — это оборона от **технического долга**.
|
||||
Loading…
Add table
Add a link
Reference in a new issue