対応状況

Lambda OS は 5 つのターゲットで動きます。**すべての機能が、すべてのターゲットにあるわけではありません。**このページは、どれがどれかを示します。

動いている。実機かエミュレータかは末尾の表を参照
予定設計は決まっており、残作業に入っている
個別汎用の実装は持たない。対象ハードウェア向けにエンゲージメントで実装する(ベアメタルの OS なので、貴社のボードのドライバは書く必要がある)
対応予定なし。設計上の非目標、役割上そこに置かないもの、またはチップの制約

ノードの役割

分散アクターシステムでは、ノードに役割があります。MCU 列の「無」は、実装が追いついていないという意味ではありません。

隔離

x86_64riscv64aarch64RV32
MMU 無し
ARMv6-M
MMU 無し
アクターが非特権で走る ring 3 U-mode EL0 U-mode ¹
カーネルへのゲートは 1 つ int 0x80 ecall svc ecall svc ¹
アクターが別のアクターのメモリに届かない アクター毎のアドレス空間 アクター毎のアドレス空間 アクター毎のアドレス空間 アクター毎の PMP 領域 アクター毎の MPU 領域 ¹
起動時のプローブがそれを検証する #PF ストアフォルト EL0 フォルト ストアフォルト HardFault
アクターがカーネルのメモリにも届かない ³予定予定
プリエンプトを跨いで FP を退避 FXSAVE予定予定 FPU があれば FPU が無い
敵対的バイトコードにも効く隔離

¹ **隔離アクターを持つイメージで。**Cortex-M0+ では、隔離・Wi-Fi・分散が 1 つのイメージに収まり(実測 256 KB 中 208 KB)、制御ループと隔離アクターも 1 つのイメージに収まります。下の Cortex-M0+ のイメージ を参照。 ³ MMU を持つ 3 ターゲットは、いずれもアクター層の共有帳簿——名前レジストリ、pid→コンテキスト表、ロックワード——をカーネルメモリに置いています。FFI は ring 0 から届きますが、ring 3 からは届きません。VM のコア毎の実行状態ブロックも同様に閉じ込め済みで、アクターは 1 つのコアに固定されるため、そのアドレス空間はちょうどそのコアのブロックだけを許し、残りを拒みます。 ⁴ 実機の MMU 無し部品(RP2350 の NAPOT 限定 PMP、RP2040 の数個の MPU 領域)では領域数が少なく deny-by-default にできないため、閉じ込めは「広く許可してから兄弟を拒否する」形になります。アクターは兄弟には届きませんが、カーネルの帳簿には届きます。(bare RV32 の QEMU ビルドの TOR ベース PMP は deny-by-default です。)実機部品での deny-by-default は残作業です。 ⁵ 現状フックはスタブです。プリエンプトを跨いで浮動小数を保持するタスクが無い限り安全、という状態です。 ⁶ **設計上の非目標。**すべてのバイトコードは運用者自身のコンパイラから信頼経路で届く前提です。隔離は堅牢性の境界(バグの封じ込め)であって、マルチテナントの境界ではありません。

スケジューリングとリアルタイム

x86_64riscv64aarch64RV32ARMv6-M
固定優先度プリエンプティブ、タスクはコアに固定
RTOS プリミティブ群(優先度継承、時間付き待ち、デッドライン超過検出、CPU 時間計上、CPU 予約、ウォッチドッグ、RM 解析) デッドラインの組 ⁷予定
デッドラインタイマ:クロックは ns、タイマは次のイベントに合わせて張る
RM で schedulable なタスク集合が、スケジューラ込みで全デッドラインを守る 実機で予定
本物の制御則が、スケジュールされた 1 kHz タスクとしてデッドラインを守る 実機で ⁹ 実機で ⁹
マルチコア 最大 4(ACPI MADT) SBI HSM PSCI CPU_ON 2 コア 2 コア
サブ µs のビジー待ち予定 ⁷ ¹⁰
VM フレームの命令数ウォッチドッグ

⁷ プリミティブ群はアーキ非依存のコードとしてスケジューラにあり、どのターゲットでもコンパイルされます。**x86_64・riscv64・aarch64 は、この一式を起動して走らせています。**RP2350 はデッドライン充足の 2 タスクを起動します(タスク表の上限が 8 で、一式は 12 要るため)。RP2040 は 1 つも起動していません。 ⁸ **5 つのターゲットすべてが 2 コア目以降を起こします。**x86 は INIT-SIPI-SIPI、riscv64 は SBI HSM の hart_start、aarch64 は PSCI の CPU_ON、両 Pico は SIO FIFO のハンドシェイク(RP2350 は実機で確認済み)。 ⁹ control()(ソフトフロートのカスケード PID + 四元数)が、スケジュールされたタスクとして片方のコアで 1 kHz で走り、もう片方がネットワークを回します。RP2350:1,741,824 ジョブ中、超過 0 回(周期 948.9〜1056.5 µs)、ミッションも動くフル配送飛行。RP2040:113,664 ジョブ中、超過 0 回(周期 998〜1002 µs)——264 KB に両方は載らないため VM ミッション無しの計測ビルド。±2 µs はジッタでなく 1 µs タイマの分解能の床です。 ¹⁰ RP2040 のカウンタは µs 分解能の TIMER です。チップの制約であり、下限は 1 µs です。

アクター

x86_64riscv64aarch64RV32ARMv6-M
型付きメールボックス(send / recv / msg_from / msg_a / msg_b
msg_tag予定予定
send_remote — 別の機械のアクターを宛先にする ¹¹
動的 spawn(オーケストレータの機構) ¹² ¹²
監視(monitorMSG_DOWN → 再生成。オーケストレータの機構) ¹² ¹²
ローカルの名前レジストリ(register_name / whereis ¹³ ¹³ ¹³ ¹³
(node, pid) によるアドレッシング(node_ip / send_node / reply_node予定予定予定予定
双方向バッファ ABI(FFI 越しのポインタ)予定 TCP + ファイル ファイルのみ予定予定
フレームスキップによる障害復帰(エッジノード) ¹⁴ ¹⁴
ノードを跨いだ監視・再供給(エッジノードの障害復帰)予定 ¹⁴予定 ¹⁴予定 ¹⁴予定 ¹⁴予定 ¹⁴
分散名前レジストリ(name → node, pid)予定 ¹⁵予定 ¹⁵予定 ¹⁵予定 ¹⁵予定 ¹⁵
ホットコードアップグレード(走行中の差し替え) ¹⁶ ¹⁶ ¹⁶ ¹⁶ ¹⁶
GC・クロージャ・動的型付け

¹¹ ノードイメージ(隔離+無線+分散)で動きます。無線を積まないイメージでは、FFI は登録されていますが送り先がありません。 ¹² 役割上、載せません。動的生成と監視は、多数のアクターを 1 チップに抱えて管理するための機構です。エッジノードは 1〜2 個を持ち、協調はネットワークで行います。 ¹³ 役割上、載せません。これはローカルの「名前 → タスク index」レジストリで、アクターが多数いるオーケストレータで「consumer は常に index 1」の脆さを消すためのものです。2 アクターのエッジノードでは self() で役割が分かります。分散で必要なのはこれではなく、下の分散名前レジストリです。 ¹⁴ エッジノードに合った障害復帰。オーケストレータ型の監視(動的生成)ではありません。暴走したフレームは VM のウォッチドッグが巻き戻し、ハードウェアフォルトを起こしたフレームはカーネルがスキップして、アクターの進捗を保ったまま次のフレームから再開させます。実機で、飛行中のフォルト注入に対してドローンが飛び続けることを確認済み。ノードを跨いだ監視は、未実装です。 ¹⁵ いまは (node_ip, pid) と well-known ポートで、宛先を手で指定しています。「そのアクターがどのノードに居るか」を解決する分散レジストリは、ローカルの名前レジストリを移しても埋まりません。別の機構です。 ¹⁶ バイトコードは起動時に差し替えます(下記)。走行中のコード入れ替えは対応予定がありません。

ネットワークとストレージ

x86_64riscv64aarch64RV32ARMv6-M
同一のネットワークスタック(Ethernet → DNS、TCP クライアント+サーバ) Wi-Fi 上 ¹⁷ Wi-Fi 上 ¹⁷
NIC ドライバ e1000 virtio-net virtio-net CYW43439 CYW43439
割り込み駆動の受信予定 ¹⁸予定 ¹⁸ ¹⁹ ¹⁹
TCP:再送・輻輳制御・高速再送・SACK・3 接続 ²⁰ ²⁰ ²⁰ ²⁰ ²⁰
受信時のチェックサム検証(UDP / TCP) ²¹ ²¹ ²¹ ²¹ ²¹
機械を跨ぐアクターメッセージ ¹⁷ ¹⁷
ブロックデバイス+再起動を跨ぐファイルシステム予定 virtio-blk virtio-blk個別個別
バイトコードを起動時に配送(焼き込みでなく) UART + TFTP ²² UART UART予定予定

¹⁷ **実機で。**Pico W(RP2040)と Pico 2 W(RP2350)のどちらでも、非特権・ハードウェア隔離のアクターの隣でネットワークスタックが特権タスクとして走り、すべてが 1 つのイメージに入っています。 ¹⁸ ドライバに割り込みフックはありますが、割り込みコントローラからそこへ配線されていません。ネットワークタスクがカードをポーリングします。 ¹⁹ CYW43439 には、CPU に配線された受信割り込みがありません。チップの制約です。フレームは、ドライバが要求したときにバスから出てきます。 ²⁰ 同時 3 接続。各接続がシーケンス状態・再送キュー・ウィンドウを自分で持ち、4-tuple 全体で多重分離します(RFC 793)。輻輳制御は接続毎の cwnd / ssthresh とスロースタート。重複 ACK 3 回で高速再送。SACK は双方向でネゴシエートし、順序外の到着を捨てずに保持します。ウィンドウスケーリングは提示しますが、こちら側のシフトは 0 です——大きな受信バッファを持たないためです。再送タイマは 400 ms から 3 s 上限で倍々、20 秒沈黙した接続は畳みます。 ²¹ TCP と UDP のチェックサムは、送信時に擬似ヘッダ込みで計算し、受信時に検証します。合わない TCP セグメントは捨て、UDP は送信側が付けていれば検証します(値 0 は「省略」の意味で、IPv4 はそれを許しています)。IPv4 ヘッダと ICMP のチェックサムも検証します。 ²² TFTP による取得は QEMU の fw_cfg に依存しており、実機の x86 では動きません。

Cortex-M0+ のイメージ

**隔離・Wi-Fi・分散は、1 つのイメージに収まります。**実測で 256 KB 中 208 KB、48 KB の余り。カーネルは 107 KB で、MPU 分割が要求する 128 KB の下です。無線のファームウェア(224 KB)は flash からチップへ直接ストリームされるので、そもそもホストの SRAM に載りません。

ノード(隔離+無線+分散)飛行制御(ミッションアクター)
ミッションが非特権・MPU 隔離 ²³
Wi-Fi 上のネットワークスタック HIL リンク
機械を跨ぐアクターメッセージ
ネイティブのカスケード PID 制御ループと安全包絡線(カーネル内)

²³ ミッション — アップロードされる案件ごとの飛行計画 — が唯一の Lambda C アクターで、非特権・ハードウェア隔離です。**RP2040(MPU)と RP2350(PMP)の両方で。**安全包絡線と制御ループはネイティブで、カーネル内にあるので、バグったミッションはそこに一切届きません。アクター対アクターより強い隔離です。**境界を実証するまで、ミッションは起動されません。**プリフライトのチェックが非特権からカーネルメモリへのストアを試み、ハードウェアがそれを拒否しなければ、基板は中止してミッションを起動しません。全チェックが READY になると、基板は人間が発進を許可するまで待ちます。両方の基板が、実機で Wi-Fi 越しに HIL シミュレータ相手の配送ミッションを完走しました。

実機とエミュレータ

ターゲット実機エミュレータ
x86_64 AMD Ryzen ノート PC、実 UEFI ファームウェア、4 コアQEMU
RV32(MMU 無し) Raspberry Pi Pico 2 / Pico 2 W(RP2350、RISC-V、ソフトフロート)QEMU
ARMv6-M(MMU 無し) Raspberry Pi Pico W(RP2040)QEMU 経路なし
riscv64QEMU
aarch64QEMU

実測値(1 kHz のデッドライン成績、制御則の WCET=Cortex-M0+ で 190 µs・Hazard3 で 98 µs)は、上の実機の行から出ています。エミュレータの行が証明するのは機構であって、タイミングではありません。