AtmOS 設計仕様

最終更新: 2026-08-27 統合元: APP_PACKAGE_DESIGN.md / HTTPS_DESIGN.md / network_and_browser_architecture_plan.md


1. アーキテクチャ概要と起動シーケンス

AtmOS は Raspberry Pi 3B+(BCM2837 / Cortex-A53 ×4)向けのベアメタル OS で、 no_std Rust で実装されている。レイヤは下位(ハードウェア直結)から上位(アプリ)へ 積み上がっており、本仕様書も以下の順序で土台から説明する。

主担当モジュール 役割
ブート boot.S, kmain スタック設定・BSS クリア・フレームバッファ確保
メモリ mmu.rs, allocator.rs 恒等マップ MMU・キャッシュ・512MB ヒープ
実行基盤 scheduler.rs, interrupt.rs, timer.rs SMP プリエンプティブスケジューラ・10ms タイマ
デバイス mailbox.rs, draw.rs, dma.rs, usb.rs, sdio.rs GPU FB・DMA 転送・USB(DWC2)・SDIO
入力 keyboard.rs, ime.rs, shortcut_manager.rs キー入力・日本語 IME・ショートカット
ネットワーク net/mod.rs/arp/dhcp/dns/icmp/tcp/udp/http), net_stack.rs, tls.rs, wifi.rs TCP/IP・DHCP・DNS・TLS・WiFi(FMAC)
アプリ層 window_mgr.rs, apps/* ウィンドウ管理・ブラウザ・Note・ターミナル等
言語 os_lib/aura/* Aura 解釈系(AURA.md

起動シーケンス

kmainmain.rs)の初期化順序は依存関係で決まっている。 フレームバッファ確保を MMU 有効化より前に行うのは、GPU と D-Cache のコヒーレンシ問題を避けるため。

キーボードショートカットの全一覧は本ファイル §15「キーボードショートカット」を参照 (ガイドバー fn_bar.rs の実装もこの一覧を単一の真実とする)。本書 §6 は設計意図を述べる。


2. ネットワークスタック アーキテクチャ

設計方針

TCP/IP モデルをベースに、モジュール性・並列性・疎結合を重視した構成。各層は独立したモジュールとして実装し、共通のパケットバッファ管理機構でデータをやり取りする。

各層の構成

第1層: Link Layer(ネットワークインターフェース層) - eth_send(), eth_register_recv_callback() を API として提供 - NIC からの割り込みを受け取り、生のフレームを送受信するハードウェア依存モジュール

第2層: Internet Layer - IPv4: IP ヘッダパース、ルーティング、フラグメンテーション - ARP: IP→MAC 解決、ARP キャッシュテーブル管理 - ICMP: Ping 等の診断・エラー通知 - ip_send(), ip_register_protocol_handler() を API として提供

第3層: Transport Layer - UDP: コネクションレス軽量転送(DNS 等で利用) - TCP: コネクション指向・スライディングウィンドウ・再送制御。ステートマシンで非同期動作 - BSD Socket ライク API + 非同期・イベント駆動インターフェースを提供

第4層: Application Layer - DNS Resolver: UDP モジュールを使用してドメイン名を解決。ping などのユーティリティや各種ネットワークAPIで、指定されたIPアドレスのパースに失敗した場合、本リゾルバを用いたDNS解決(dns_query_a_via_udp)を自動で試みるフォールバック処理が実装されています。これにより、ホスト名指定による透過的な通信が可能となっています。 - HTTP Client: TCP モジュール上。リクエスト生成・レスポンスヘッダ解析・Chunked 転送対応。ブラウザ以外からも再利用可能

実装済み構成(2026-06-02 時点)

API 境界の事前条件検証(疎結合・パニック予防)

アプリ(ブラウザ等)⇄ カーネル内部の境界は ApplicationLayerApi / TcpIpStack::web_getweb_postweb_get_binary に一本化する。この入口で全入力を検証し、通過後はカーネル内部(DNS/TCP/TLS/HTTP パーサ)が 「検証済みの host/path しか来ない」前提で動けるようにする(OS 内部とアプリの疎結合)。

プロセス間通信・バッファ設計(採用方針)


3. ブラウザエンジン アーキテクチャ

コンポーネント構成

Resource Fetcher   HTTP Client API 経由で HTML/CSS/画像を非同期取得・キャッシュ
HTML Parser        バイト列→DOM ツリー構築
CSS Parser         スタイルシート→CSSOM 構築
Layout Engine      DOM + CSSOM →レイアウトツリー・ボックスモデル計算
Paint/Render       レイアウトツリー→AtmOS グラフィック API 呼び出し→描画

実装済み内容(2026-06-02〜06-05)

HTML パーサ改善: - 属性パース強化(引用符付き値、空白を含む属性値、属性値省略) - Void 要素判定拡張(input, meta, link, source など) - コメント・DOCTYPE 等 <!...> の読み飛ばし追加

CSS 対応強化: - css::parse_css() 実装。selector { key: value; } を解析 - セレクタ対応: tag, #id, .class、カンマ区切り、descendant(空白)、child(>) - 複合セレクタ: div.note > p.warn のようなチェーン形式 - specificity(id > class > tag、同点は後勝ち) - 疑似クラス :first-child / :last-child を最小対応 - border-style / border-colornone / dashed / solid)の最小対応 - text-align: center / right の最小対応 - font-weight: boldb/strong タグ・CSS で有効化、1px 重ね描きでシミュレーション) - CSS スタイル継承修正: color / font-size / font-weightflatten_layout 経由で親→子へ伝播

レイアウト拡張: - block コンテナ内の inline フロー(行内配置・折り返し) - br を改行として処理 - box model: margin / padding / border-width / 各辺プロパティをレイアウト計算に反映 - display: inline-block 最小対応 - 幅解決で % / auto / min-width / max-width を反映

ブラウザ UI の境界規約(2026-06-13)

タブモデル: タブごと独立 WebEngine(2026-06-14)

各タブが独立した WebEngine を持つ完全分離方式(URL・描画済み DOM・スクロール・ フォーム入力・履歴がタブごとに保持され、切替でネットワーク再取得しない)。

レイアウトエンジンの座標規約(重要・退行防止)

  1. Y フローカーソル規約: layout_block / layout_inline は、包含ブロックとして渡される Dimensions.content.height を「現在の Y フローカーソル」と解釈し、自身を content.y + content.height に配置する。block 子のレイアウト時は親が cb.content.height = y_cursor を設定してから child.layout(cb) を呼ぶ。
  2. inline 子のスロット確定規則: block コンテナ内の inline / inline-block 子は、親が intrinsic_inline_size() で寸法を計測し、行ボックス内のスロット位置 (x, y, w, h) を確定する。 その後の child.layout(cb) には height = 0 の cb を渡し(規約 1 により子が自分の高さぶん 下へずれるのを防ぐ)、呼び出し後に親が確定したスロット寸法を最終値として再設定する (layout_inline 内の再計算は % 高さを包含高さ 0 基準で解決して潰すため)。 ※ この規則に違反すると「textarea が自分の高さぶん下(画面外)に飛ぶ」バグが再発する (TECHNOTE §7 参照)。
  3. 折返し規則のペア同期: Web ページ本文の行分割は web_engine::flatten_layoutvector_font::get_string_wrapped_size完全に同一の規則'\n' 強制改行・行頭/行末禁則・ 改行時に先頭文字を即消費)を持つ。どちらかを変更したら必ず両方を同期する(<hr> 重なりバグの原因)。 エディタ(textarea)表示の折返しは別規則で、WebEngine::wrap_editor_lines(O(n) 実装)に一元化済み。
  4. ビューポートヒント: parse_and_layoutlayout::set_viewport_hint(w, h) を設定してから レイアウトを実行する。置換要素(textarea 等)の width/height: 100% はこのヒントを基準に解決される。

テーブルレイアウト(2026-06-13 実装)

display: table / table-row-group / table-row / table-cell<table><tr><td><th> に対応 (layout.rs::layout_table)。 - UA デフォルト display を css.rs に追加(table→table、tr→table-row、td/th→table-cell、 thead/tbody/tfoot→table-row-group、th は bold + center) - 行グループ(thead/tbody/tfoot)は build_layout_tree で透過し、行を table の直接の子へ引き上げ - 列幅は各列セルの intrinsic 幅の最大値を基準に、総和が利用幅超過なら比例縮小・ 下回りなら均等加算で幅いっぱいに展開。各行を縦に積み、行内セルを列幅で横並び、 行高さ = セル最大高さに揃える - セルごとの背景色・文字色・text-align・border は通常のブロック要素と同じく適用 - 注意: layout_block と inline フローの box_type マッチはテーブル variant も block 扱いで 網羅すること(未網羅だと早期 return でセルが (0,0) に積み上がる)

テーブル拡張(2026-06-14 実装)

layout_table を「セル index = 列番号」前提からグリッドモデルへ書き換え、占有グリッドで colspan / rowspan を解決。<caption> を本体上部に配置、border-collapse: collapse 時は 隣接セルを 1px 重ねて二重線を解消。

次フェーズ実装予定(優先順)

  1. インクリメンタル / 部分再レイアウト(現在は毎回全再構築のため大ページで重い)
  2. RenderElement のメモリ効率化(巨大構造体の文字列フィールドを参照/インデックス化)
  3. CSS セレクタ拡充(兄弟結合子・属性セレクタ・nth-child)

JavaScript エンジン(2026-06-15〜、os_lib/js/

ブラウザの <script> / onclick を実行する自前の JavaScript エンジン。従来は Aura (Lisp 系)が <script> を実行していたが、本物の JS へ切替(Aura は .aura 用に存続)。


4. HTTPS / TLS 設計

実装方針(2段階)

TLS 実装方式の比較

方式 長所 課題
rustls + ring 系 Rust 中心で保守しやすい no_std + ARM64 ベアメタル適用の調査コスト高
BearSSL C 連携 軽量で組込み実績が多い FFI 境界とメモリ安全の管理が必要
TLS 終端プロキシ 実装が最短 OS 単体の完全性が下がる

→ 第一候補は embedded-tls(rustls 系)。2 週間以内に成立見込みが薄ければ BearSSL 連携へ切り替え。

実装済みコンポーネント

非対応(現時点)


5. EL1/EL0(特権モード)切り分け設計

概要

ARM64 の例外レベルを適切に分離し、カーネル空間および主要サービスを EL1(特権モード)、ユーザープロセスを EL0(非特権モード)で動作させる。

現在の実装状況

以下はすでに実装済み:

main.rs にはテスト用の user_test_normal / user_test_abort が実装済みだが現在は無効化(コメントアウト)。

未完了タスク(TODO.md に記載)

検証計画

QEMU 起動後、UART 出力で以下を確認: 1. USER_TRAMPOLINE: Entering EL0 が出力される 2. SYS_PRINT で文字列が表示される 3. SYS_EXIT でプロセスが正常終了する 4. MMIO への不正アクセスで === DATA ABORT from EL0 === が発生し、OS 全体はハングせず継続する


6. ショートカット・マウストラッカー モジュール設計

背景

main.rs の巨大なメインループにショートカット判定とマウス移動計算がハードコードされており、デグレが頻発していた。これを独立モジュールとして分離した。

shortcut_manager.rs

mouse_tracker.rs

変更内容

main.rs のメインループ内のハードコードされた境界計算を mouse_tracker.move_relative(dx, dy) に置き換え済み。キーボードイベントは shortcut_manager.evaluate() に渡して返ってきたアクションのみ実行。


7. 構造ハードニング(アプリ障害の隔離)

背景

アプリは長らく EL1 カーネル空間で Box<dyn App> として動作し、カーネルと同一ヒープを共有していた。 このためアプリ操作(例: ウィンドウ最大化の連打)で OS 全体がフリーズする事故が発生した。 原因の多くは「効果音ごとのスレッド生成・破棄チャーン」や「リサイズ毎の巨大バッファ再確保」で、 アプリ層の不調がカーネルのヒープ canary を壊していた。これを段階的に是正する。

Phase 1: ウィンドウバッファのリユース(実装済み)

Phase 2: OOM ガード(実装済み)

Phase 3: アプリ描画ウォッチドッグ(実装済み)

Phase 4: EL0 サンドボックス(基盤実装済み・アプリ移行は段階導入)

実装済みの基盤(検証済み):

→ つまり「EL0 で動くコードがフォルトしても OS は落ちない」という核心の安全性は確立している。

EL0 GUI ウィンドウ ABI(実装済み・QEMU 検証済み):

kernel/user_win.rs + syscall.rs に以下を実装。EL0 プロセスは WM・フレームバッファに 直接触れず、システムコール経由でウィンドウを操作する。

syscall 番号 機能
SYS_WIN_CREATE 5 x0=リクエスト構造体 [title_ptr, title_len, w, h] → ハンドル返却。カーネル側に UserApp プロキシを生成し WM に登録
SYS_WIN_BLIT 6 x0=ハンドル, x1=ピクセル列 (ARGB8888, w×h)。カーネルが検証してコピー
SYS_WIN_POLL 7 x0=ハンドル, x1=書込先。入力イベント (Key/Mouse/Closed) を1件取得
SYS_WIN_CLOSE 8 ウィンドウ破棄・レジストリ解放

残作業(段階移行):

  1. 既存アプリ(まず Note)を ABI 上に移植し、専用ヒープ(EL0 用バンプアロケータ)を整備。
  2. フォルト時に WM が当該ウィンドウを Not Responding 化(Phase 3 と統合)。
  3. プロセスごとのページテーブル分離の細粒度化(現在は 2MB ブロック単位の粗い保護)。

移行が完了すると、アプリのバッファオーバーフローや無限ループはカーネルへ波及せず、 MMU 保護で Data Abort になり当該ウィンドウのみが落ちる構造になる。


8. メモリマップとカーネルヒープアロケータ設計

1024MB 物理メモリマップ

物理アドレス範囲 容量 用途・詳細
0x0000_0000 〜 0x0040_0000 4.0 MB ブートローダ予約、例外ベクタテーブル、カーネル本体(.text/.data/.bss)、CPUスタック(4コア×64KB)
0x0040_0000 〜 0x2040_0000 512.0 MB カーネル動的ヒープ領域(TLSF): Webエンジン(DOM/CSS/JS)、プロセス、画像、通信等の専用空間
0x2040_0000 〜 0x3800_0000 380.0 MB SylFS 専用 RAMDisk 物理ストレージ領域: ヒープ消費ゼロで直接マッピング(一時キャッシュ/非多重化)
0x3800_0000 〜 0x4000_0000 128.0 MB GPU / VRAM / MMIO レジスタ領域: フレームバッファ(gpu_mem=128)および BCM2837 MMIO レジスタ

kernel/allocator.rs。512MB のカーネルヒープを管理する。 TLSF (Two-Level Segregated Fit) 方式により最悪計算量 O(1) の確保・解放と有界な断片化制御を実現している。

bump フロンティア + 再利用フリーリスト方式

HEAP_START ──────────────── frontier ──────────────── HEAP_END
   [確保済み/解放済みブロック群]   [未使用 (pristine) 領域]
   ↑ フリーリストで再利用管理      ↑ ポインタ前進だけで確保

破損の検出と封じ込め(多層防御)

機構
canary 全ブロックヘッダに FREE_MAGIC / ALLOC_MAGIC を刻印。alloc/dealloc/走査時に検証
走査ガード フリーリスト walk は上限回数つき(循環参照対策)。不正 next は切り詰め
repair() 破損検出時にヒープを物理走査してフリーリストを再構築(孤立ブロック救済)
integrity_check() 定期診断(USB ポーリングスレッドから実行)。最初の破損の現場を保全ログ
OOM dump 確保失敗時に要求サイズ・再利用プール・pristine 残量をダンプ

9. YouTube動画視聴機能の設計仕様 (H.264+MP3デコード再生、HDMI/PWM同期出力)

本仕様は、外部の中継プロキシを排除し、ラズパイ3B+のベアメタル環境(no_std)のみでインターネットから直接mp4形式のYouTube動画を取得・デコードし、映像と同期した音声をHDMI(I2S)およびイヤホンジャック(PWM)の両系統から完全同期で出力するためのものである。

9.1. デコーダ・デマルチプレクサの設計

9.2. HDMI / PWM デュアルオーディオDMA同期出力

9.3. WebEngine 統合と再生同期ループ


10. システムモニター(プロセスリスト)のUI仕様

不要な列の排除による視認性向上と、詳細情報の確認スペース拡大のための仕様。

10.1. 列構成とレイアウト (src/kernel/window.rs)

10.2. 列ソートおよびマウスクリック判定


11. ターミナル(CUIシェル)のローカルコマンド設計

ターミナル(CUIシェル)はAura言語インタプリタを評価するスレッドと、非同期にキュー(SafeQueue)を介して通信を行っていますが、特定のローカルコマンドはAuraの評価エンジンを通さず、UIスレッド(shell.rs 内の execute_shell_command)で即時に処理して完了(インターセプト)させます。これにより、インタプリタのバグや遅延から遮断された頑健なシェル操作を保証します。

11.1. インターセプト対象のコマンド

  1. clear
  2. history / h

12. アプリケーションウィンドウの起動制御設計

12.1. ウィンドウ状態の解析と決定 (parse_launch_options)

アプリケーション起動時に渡された引数を解析し、初期ウィンドウの表示状態(maximizednormalminimizedfullscreen)およびサイズを動的に決定します。

12.2. ウィンドウサイズ決定優先度 (通常表示 "normal" 状態時)

通常表示状態で起動される場合のウィンドウサイズは、以下の優先順位に従って決定されます。 1. 起動引数でのサイズ直接指定(例: "800x600") 2. アプリケーションマニフェスト(manifest.json)の width および height 定義値 3. システムデフォルトサイズ(一律 500x600


13. ログ出力設計仕様

システム起動時および運用時のコンソールログ(シリアル出力)の視認性を高め、不要なログスパムを防止するための出力規則です。

13.1. ログレベルとプレフィックスの統一

log! マクロ(info!, warn!, error!, debug!)が出力するログのレベルプレフィックスは、大文字5文字幅に統一・アライメントされます。 - [ERROR] : システムエラーや例外(Data Abortなど) - [WARN ] : 警告(フォールバック検知など) - [INFO ] : 各モジュールのマイルストーンや完了ステータス - [DEBUG] : 開発者向けの詳細情報

13.2. モジュール名の括弧表記

ログ出力メッセージの先頭には、括弧で囲んだ大文字のモジュール名(大文字3〜5文字)を明示します。 - [SYS] : システム全体、初期化共通、例外ハンドラ - [GPU] : グラフィック、FrameBuffer、V3D - [MMU] : メモリ管理、ページテーブル - [MEM] : ヒープアロケータ - [FS] : ファイルシステム (SylFS)、ブロックデバイス - [USB] : USB ホストコントローラ (DWC2)、HIDスタック - [AUD] : オーディオエンジン - [SCHED] : スケジューラ、プロセス管理

例: [INFO ] [USB] Device Speed: High Speed (PrtSpd=0)

13.3. サイレントモード(IS_SILENT)の活用

テスト実行時(js, fs, usb などのセルフテスト)や、ファイルシステムの初回マウント時(未フォーマットの空セクタ読み込み時)には、グローバルなサイレントフラグ(kernel::uart::set_silent(true))を一時的に有効化します。これにより、期待される擬似的なエラーログや不要な警告ログがコンソールに出力され、ログが汚れるのを防止します。

13.4. 段階的ブートサマリー表示

kmain (起動時) では、以下の7つの主要ステップに絞り、右端に [OK] を揃えたクリーンなサマリーを表示します。これ以外の不要な詳細ログは info! 以下に落として起動時には非表示にします。 1. Graphics System (FrameBuffer) ................. [OK] 2. Memory System (MMU & Heap) .................... [OK] 3. Core Software Self-Tests (各テストのPASSマーカー) [OK] 4. File System (SylFS) ........................... [OK] 5. Audio Systems ................................. [OK] 6. USB Host Controller & HID Stack ............... [OK] 7. System Scheduler & Interrupts ................. [OK]

13.5. 自動テスト(expect)との互換性

QEMU自動テスト(expect test_browser.sh)が監視する各セルフテストの合格判定文字列(JS_SELFTEST: PASS など)は、サマリー表示の第3ステップの1行の中にすべてテキストとして埋め込む形で出力されます。これにより、テストスクリプトの検知ロジックを壊すことなく、出力行数の削減を実現しています。


14. アプリケーション実行アーキテクチャ

AtmOS のアプリは 静的リンク(モノリシックビルド)+ 仮想マニフェスト の組み合わせ。

  1. ビルド時: src/apps/{name}/ の Rust コードがカーネルと一緒にコンパイルされ kernel8.img に含まれる
  2. 起動時: fs/mod.rs がプリインストールアプリのマニフェスト(manifest.json, main.aura)を SylFS の /apps/{name}/ に動的生成
  3. 実行時: ユーザーがコマンドを入力→シェルが main.aura を評価→os.launch_gui("name")builtins.rs でアプリ判定→静的リンク済み Rust 構造体をインスタンス化してウィンドウにバインド

将来改善案: include_str! でアセットをアプリモジュール自身に持たせ、fs/mod.rs からハードコードを排除(作戦A)。


15. キーボードショートカット

ファンクションキー

キー 機能
ESC モーダル・IME 変換を閉じる
F1 ターミナルへフォーカス(再押下でスライドトグル)

Alt + ファンクション(ウィンドウ管理)

キー 機能
Alt+F1F8 ワークスペース 1〜8 へ移動
Alt+F9 最小化
Alt+F10 通常状態へ復元
Alt+F11 最大化
Alt+F12 全画面(新規ワークスペース)

OS グローバル

キー アクション
Alt+T / Alt+W タブ追加 / 閉じる
Alt+↑ / Alt+↓ タブ切り替え
Alt+O / Alt+S ファイルを開く / 保存
変換(0x79) / 無変換(0x7B) IME ON / OFF

ターミナル入力

Ctrl+A/E(行頭/末)、Ctrl+K(行末削除)、Ctrl+C(クリア)、↑↓(ヒストリ)、Shift+Enter(改行)

エディタ(Note・Emacs 互換)

Ctrl+A/E(行頭/末)、Ctrl+F/B/N/P(移動)、Ctrl+O(Open Line)、Ctrl+S(検索)

IME

Space(変換/次候補)、Enter(確定)、19(番号選択)、Esc(取消)


16. microSD カード永続化設計(SDHOST + SylFS)

ストレージ構成

SDHOST コントローラ

Overlay + 自己修復設計

QEMU テスト

# sdcard.img をオンボード SD スロットとしてアタッチ
-drive file=sdcard.img,if=sd,format=raw

17. ユニットテスト完全隔離実行アーキテクチャ

隔離設計の基本原則

モジュールマッピングとモック・スタブ設計

arm/v1/
├── src/                    ← カーネル本体ソース (no_std / AArch64)
└── tests/                  ← 独立ユニットテストクレート (std / Host)
    ├── Cargo.toml
    └── src/
        ├── lib.rs          ← モジュールマッピング & モック定義
        ├── test_dom.rs
        ├── test_css.rs
        ├── test_js.rs
        ├── test_aura.rs
        ├── test_keyboard.rs
        └── ...             ← 各機能モジュールの独立テスト群

【2026-08-27】物理メモリ 1024MB の区画割りと専用 RAMDisk(ヒープ外直接マッピング)

[ カーネル・スタック 4MB ][ ヒープ 512MB ][ 専用 RAMDisk 380MB ][ GPU / MMIO 128MB ]
0x0000_0000              0x0040_0000     0x2040_0000            0x3800_0000      0x4000_0000

RAMDisk をヒープから動的確保するのをやめ、ヒープ直後の物理空き RAM(0x2040_0000 〜 0x3800_0000を 直接使うようにした(block::RAMDisk::from_raw_memory)。 ヒープ(512MB)を 1 バイトも消費せず丸ごとアプリケーションへ残し、さらに RAMDisk は揮発性メモリのため多重化(ミラーリング)を行わず、380.0MB(100%)全域を実効容量として使用する。

危険な点と、その押さえ方

この配置は 3 つの値の関係だけで決まる。

定義場所 設定値
ヒープの大きさ allocator::KERNEL_HEAP_SIZE 512MB (0x2000_0000)
RAMDisk の開始 ヒープ末尾(__cpu_stacks_end + KERNEL_HEAP_SIZE 0x2040_0000
GPU 境界 mmu::DEVICE_REGION_START 0x3800_0000

どれかがずれると、記憶装置への書き込みがヒープや フレームバッファを壊す。 症状は「どこかが時々壊れる」で、 原因の特定が極めて難しい。

(1) 定数を 1 つにした

main.rsfs/mod.rs が別々に 512 * 1024 * 1024 と 書いていたのを統一し、allocator::KERNEL_HEAP_SIZE を唯一の定義として参照する。

(2) 関係を単体試験で固定した

tests/src/test_memory_layout.rs: - RAMDisk がヒープに重ならない - RAMDisk が GPU 領域を踏まない - 0x0040_0000 起点時の 380.0MB(100%)実効容量と一致する - ヒープが大きすぎても引き算が桁あふれしない - 非多重化(100%)により全 380MB をフル活用できること - 1024MB 物理メモリ全体(0x0000_0000 〜 0x4000_0000)が 1 バイトの隙間もなく連続していること

(3) 起動時のログを出力

[FS] Dedicated RAMDisk allocated from 0x20400000 to 0x38000000 (380 MB)

確認

単体テスト test_memory_layout.rs 全件 PASS、make all クリーン、実機・QEMU ともに正常起動。