ヌードLinux をブートする

2026/06/16 1:03

ヌードLinux をブートする

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

本記事では、不要なコンポーネントを最小限のカーネルから削除し、単一の C プログラムベースの「init」プロセスのみをホストすることで Linux の起動時間を劇的に短縮する方法を紹介します。標準的なディストリビューションが大型の

initrd
イメージ(2163 ファイルを含む約 73MB)を使用し、マルチコアシステムで起動に約 1 分かかるのに対し、このアプローチでは簡易 C プログラムを静的コンパイルしてメッセージを表示し、順序立てたシャットダウンのため
reboot(RB_POWER_OFF)
を呼び出すことで、コンパクトな単一ファイルの
initramfs
を作成します。この技術は、デバイスアクセスが手動でマウントされる仮想化環境(例:KVM/QEMU)と、EFI パーティションおよびユニファイドカーネルイメージを必要とする実機ハードウェアセットアップの両方の起動に対応しています。結果として得られるシステムフットプリントは標準構成と比較して約 2MB に減少しますが、主なメリットは著しく高速な応答時間と攻撃対象領域の縮小です。このプロセスには
make tinyconfig
を使用するなどの特定のビルド手順や、「Initramfs unpacking failed」のような潜在的なデバッグエラーの処理が含まれ、最終的には複雑な起動シーケンスを効率的な埋め込みシステムまたは仮想システム向けに置換することを目的としています。

本文

起動時間を 1 秒未満に短縮:最小限の Linux カーネルでの体験

2026 年 5 月 19 日、従来のオペレーティングシステム全体を起動するのではなく、単一のプロセスのみをホストするためのLinux カーネルを実行し、起動時間を 1 秒未満に短縮した取り組みをご紹介します。

背景と動機

  • 過剰な保護から脱却: 子供の頃はコンピュータが長時間稼働する必要はなく、電源を切って再起動するだけで数秒でディスク内容を読み込める時代でした。
  • SSD 以降の停滞: 2000 年代初期に SSD の登場で一時的に速度が向上しましたが、業界は既存の慣例に従い続ける結果、現在では高性能なマシンでも起動に 1 分かかることが珍しくなくなっています
  • 別のアプローチ: 機能のない状態ではなく、**「極めて少ないもののみ」**を残して Linux カーネルを維持し、その枠内でシステムを実装する試みを始めました。

【更新】 「Rust を用いて最小限の Linux から構築する方法(Building a tiny Linux from scratch)」というリソースを発見しました。これは 1 年前に発表されたもので、私が行うことの多くを実装しており、一読の価値があります。

Hello, World!:最小限の Init プログラム

Linux の起動では、最初の動作として init プログラムが実行されます。これを作るには、以下のような単純な C コードを用意します。

基本例:
init.c

このプログラムはメッセージを表示し、その後コンピュータを再起動(VM をシャットダウン)するだけで、カーネルのパニックを防ぐ設計です。

#include <stdio.h>
#include <stdlib.h>
#include <sys/reboot.h>

int main(int argc, char **argv) {
    fprintf(stderr, "Hello from init.c!");
    reboot(RB_POWER_OFF);
}

単一ファイルの initrd を作成

現代的な Linux は「initrd」や「initramfs」などを活用した複雑な起動プロセスを使いますが、ここでは静的リンク(静的ライブラリを含めた)コンパイルを行い、必要なライブラリを自前で用意して単一ファイルの自分専用の initrdを作成します。

以下のコマンドを実行することで作成可能です:

gcc -static init.c -o init
echo 'init' | cpio -o --format=newc | gzip -c > initrd

起動時の確認ポイント

カーネルメッセージを確認し、以下の点に注意してください。

  • 正常な展開:
    Trying to unpack rootfs image as initramfs...
    と表示され、その後
    Run /init as init process
    とメッセージが出れば成功です。
  • エラーチェック:
    • Initramfs unpacking failed: no cpio magic
      : 形式や圧縮方式が合っていない場合。
    • check access for rdinit=/init failed: -2
      : ファイルが見つからない場合(
      -ENOENT
      )。

補足: 多数のファイルを圧縮したい場合は、以下のコマンドを使用します。

(cd $SOURCE_DIR; find . | cpio -o -H newc) | gzip -c > $OUTPUT_FILE

仮想環境(QEMU/KVM)での動作検証

実際にハードウェアで動かす前に、実験用に KVM または QEMU を使用してシミュレーションを行います。カーネルと initrd のみをコマンドラインからブートさせる設定です。

カーネルの準備

システムのカーネルをコピーし、所有者権限を変更します(または自前でビルド):

sudo cp /boot/vmlinuz .
sudo chown $USER:$GROUP vmlinuz

KVM での起動テスト

以下のコマンドで仮想システムを起動し、標準出力ログから

Hello from init.c!
を確認します。

kvm -m 1G -nographic -kernel vmlinuz \
    -initrd initrd -append "console=ttyS0"

期待されるログ:

[    0.000000] Linux version 6.8.0-...
...
[    0.493923] Trying to unpack rootfs image as initramfs...
[    0.712522] ...
[    0.816634] Run /init as init process
Hello from init.c!          <-- ここです!
[    0.819849] reboot: Power down

デバイスと永続ストレージのアクセス

ファイルシステムなしでも、永続的なストレージへのアクセスは可能です。そのためには起動時に

/dev
マウントが必要です。

devtmpfs のマウントと読み取りテスト

C コード内で

mount("devtmpfs", "/dev")
を呼び出し、
/dev/sda
にアクセスしてデータを読み取る実装となります。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mount.h>
// ... その他のヘッダ

int main(int argc, char **argv) {
    fprintf(stderr, "Hello from init.c!\n");
    
    // /dev を devtmpfs マウント
    mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);

    // ディスクイメージを開く
    int fd = open("/dev/sda", O_RDWR);
    uint32_t buffer[2];
    read(fd, buffer, sizeof(buffer));
    close(fd);

    fprintf(stderr, "Read %08x %08x\n",
        ntohl(buffer[0]), ntohl(buffer[1]));

    reboot(RB_POWER_OFF);
}

注意: 実際のコードではエラーハンドリングや

errno
の確認は必須ですが、ここでは簡潔さのために省略しました。

テスト環境での実行

ランダムデータを生成したイメージファイル(

diskimage
)を用意し、KVM で起動します。

dd if=/dev/random of=diskimage bs=1K count=1K

gcc -static -o init init.c 
echo 'init' | cpio -o --format=newc | gzip -c > initrd

kvm -m 1G -nographic -kernel vmlinuz \
    -initrd initrd -append "console=ttyS0" \
    -no-reboot -hda diskimage

結果として、ブートからディスク読み取りまでの時間が1 秒未満となりました。

実ハードウェアへのインストール手順

USB メモリに EFI ブートを追加し、実際に動作させるための手順です。注意深く操作してください(データ破損のリスクがあります)。

1. USB ドライブの初期化

  • USB を接続し、
    lsblk
    でドライブを特定します(例:
    /dev/sda
    )。
  • 重要: パーティションテーブルをゼロ化する前に注意を払いましょう。
# パーティションテーブルと既存データをリセット (データ消去に注意!)
dd if=/dev/zero of=/dev/sda bs=1M count=1

# パーティション編集ツール起動
sudo cfdisk /dev/sda

cfdisk での設定:

  • フォーマット形式:
    dos
  • パーティション 1: 512M, タイプ
    EFI
    (Hex ID ef) → ブート可能にマーク
  • パーティション 2: 残り全て, タイプ
    Linux
    (Hex ID 83)

2. ファイルシステムの作成

sudo mkfs.fat -F 32 /dev/sda1      # EFI パーティション
sudo mkfs.ext3 /dev/sda2           # ルートパーティション(今回は ext3)

注意: UEFI は

/EFI/BOOT/BOOTX64.EFI
ファイルが必要ですが、一部の環境ではブートローダスタブで自動取得される場合があります。ここでは明示的にファイルを確保しました。

3. ユニファイドカーネルの作成と配置

カーネル (

vmlinuz
) と initrd (
initrd
) を
ukify
ツールを使って結合し、EFI ファイルとして配置します。

sudo apt install systemd-ukify systemd-boot-efi
ukify build --linux=vmlinuz --initrd=initrd

# 作成された EFI カーネルをコピー
sudo mount /dev/sda1 /mnt
sudo mkdir -p /mnt/EFI/BOOT
sudo cp vmlinuz.unsigned.efi /mnt/EFI/BOOT/BOOTX64.EFI
sudo umount /mnt

これで USB メモリにブート可能なシステムが完成します。再起動直後に写真撮影のために

sleep(5)
を追加した例などはありますが、実質的な動作は以下のようになります:

[    0.816634] Run /init as init process
Hello from init.c!          <-- 起動完了の表示

マイクロカーネル(Tiny Kernel)のビルド

既存のカーネルをコピーするだけでなく、より小さく安全な独自のミニマルな Linux カーネルをビルドすることも可能です。

ビルドプロセス

git clone https://github.com/torvalds/linux.git
cd linux
make tinyconfig       # 基本設定でほぼ機能しないため
make menuconfig       # 必要な機能を手動で有効化
make -j 8             # コンパイル(結果約 1~2MB)

重要な構成オプション (
menuconfig
)

以下の項目について確認・設定が必要です:

  • General setup
    • ロカルバージョン名:
      tiny
      に設定。
    • Initramfs/Initrd サポート:
      gzip
      で圧縮されたもののみ残す。
    • コンパイル最適化: サイズ重視 (
      -Os
      )。
    • 多ユーザー/グループ機能: 無効化(セキュリティ向上)。
    • printk
      : 有効にしておく(起動エラーの原因調査に必須)。
  • Processor type and features
    • SMP (シンメトリックマルチプロセッシング) を有効。コア数制限を設ける。
    • クラスタースケジューラなどは無効化。
  • Block Layer
    • ブロックデバイス (
      /dev/sda
      ) アクセスは必須(有効)。
    • 自動ロードやマウント時書き込みは不可にする。
  • Executable File Formats
    • ELF バイナリ: 有効。
    • Shell スクリプト (
      #!
      ) 解析: 無効化(シェルがないため)。
  • Device Drivers
    • /dev
      マウント用
      devtmpfs
      : 必須(有効)。
    • TTY: 必須(有効)。
    • シリアルドライバ (8250/16550): QEMU エミュレーション用に有効。
  • File Systems
    • ext3, ext4: 有効化(将来の拡張用)。
    • FAT/vFAT/exFAT: EFI パーティション読み取り用に有効化。
  • UEFI Stub の設定順序
    • ACPI と UEFI runtime サポート、EFI stub support を順番に有効にする必要がある。

これをやる価値はあるか?

このアプローチには明確なメリットがあります:

  1. スリムさ: より多くの空間を確保でき、起動速度が向上します。
  2. 攻撃 표면の削減: 利用していないカーネル機能やライブラリがないため、セキュリティが向上する可能性があります。
  3. 単一ファイル化:
    ukify
    と組み合わせることで、ブート時に外部への依存関係を持たせず、たった一つのファイルでシステムを動作させられます。
  4. カスタマイズ性: 自身の環境に最適化された微小なカーネルを構築できます。

まとめ: 最小限のシステムにおいて、いかにして必要な機能だけを確実につなげるかは、技術的な挑戦であり興味深い冒険です。

次号: '森林のための木' — 最小主義的システムにおける構造化データの冒険へ続く…

同じ日のほかのニュース

一覧に戻る →

2026/06/16 5:00

LinkedIn の雇用オファーに含まれた裏口

## 日本語訳: 提供されたテキストは、読めるコンテンツではなく完全に破損したバイナリデータからなるものであり、ニュース、事実、エンティティ(製品名、日付、組織など)、または論理的構造は一切含んでいません。入力内に理解可能な単語や文が存在しないため、背景コンテキスト、将来の予測、または潜在的な影響を特定することはできません。その結果、特定の数字を抽出したり、IT 記事のための妥当な箇条書きを生成したり、意味のある要約を導き出すことは不可能であり、このデータは修復されるまで、あるいは正当なテキストで置換されるまでは静的ノイズとして機能し、分析に価値を持ちません。

2026/06/16 7:37

Wi-Fi スマート電球に内蔵された禁書図書館

## 日本語翻訳: 「Banned Book Library」プロジェクトは、安価な WiFi スマートボールを分散型で検閲耐性のある禁書アーカイブに変換し、不安定なクラウドサービスよりもローカルコントロールを重視し、Cory Doctorow の情報レジリエンス哲学と整合性を保ちます。ESP32C3 チップの限られた 4MB フラッシュストレージに対処し、外部メモリカード用の困難なハンダ付けを避けるために、開発者は Arduino IDE と ESP-IDF を用いてファームウェアをカスタマイズしました。具体的にはパーティションテーブルを変更して電子書籍用にスペースを割り当てるよう修正するとともに、Tasmota(ソースコードの複雑さから放棄された)に見られる平文で認証情報を格納するというセキュリティリスクを回避しています。本デバイスは、カスタム「safeboot」復旧メカニズムを備え、禁書理由とともに書籍リストを表示する Web インターフェースを内蔵しており、GPIO ピンを通じて LED の色温度を制御できる管理パネルも含まれています。DNS 劫奪を用いたキャプティブポータルを実装し、あらゆるデバイスからユーザーをローカルアーカイブへ誘導することで、物理的に分散されたネットワークによる情報レジリエンスを実現しています。今後のアップデートでは、AnalogWrite を用いた精密な RGB/ホワイト色制御や、ファイル共有のためのメッシュネットワーキングへの実験が含まれます。結局のところ、このプロジェクトは一般的なスマートホーム技術を堅牢なインフラストラクチャに転換し、日常のデバイスが重大なアーカイブ機能を受け持ち得ることを示すとともに、小容量というハードウェアの制約を特徴へと高め、保管者に最も重要な作品のみを選定するよう促しています。

2026/06/16 0:13

イロフ 1.0

## Japanese Translation: iroh ネットワークは、それ以前の 65 バージョンに続く初となる安定リリースとしてのバージョン 1.0 を正式にローンチし、インターネット全体で安全な localhost のように動作する革命的な「key でダイヤル」システムを導入します。このマイルストーンでは、不安定な IP アドレスをユーザーが制御するキーに置き換え、複雑なルーティングに依存せずにデバイス間での直接かつ暗号化された接続を可能にします。ネットワークは巨大なスケーラビリティを実証しており、たった 30 日で 2 億以上のエンドポイントを作成し、安全な動画ストリーミングやエージェント間の通信、大規模言語モデルのトレーニングなど、多様な用途に数百万のデバイスを支えています。IETF のドラフトや QUIC マルチパスといったオープン標準を基盤とし、ローカルフースト設計によりインターネット接続がなくても堅牢なコネクティビティを提供します。開発者にとっての大きな影響として、Python、Node.js、Swift、Kotlin への公式 FFI サポートが追加され、安定した異言語間通信が保証されています。特に、1.0 API はエンドポイント間の通信がマイナーバージョンの変更や使用されるプログラミング言語に関係なく確保されることを保証します。さらに、デバイス同士の直接転送によりクラウドホップが 95% 削減され、データエグレスコストの大幅な低下が可能となるだけでなく、Bluetooth Low-Energy など新たなトランSPORT を実装できます。前マイナーバージョンを使用しているユーザーは、2026 年 12 月 31 日(パブリックリレーサポート終了日)までにアップグレードすることを推奨され、安定性を維持するためです。問題が発生している場合は、バグレポートの前に更新して問題が持続するかを確認してください。