SlideShare a Scribd company logo
1
Linux のユーザーランドを
init から全てまるごと
Golang で書く
Tetsuyuki Kobayashi
2018.4.15 Go Conference 2018 Spring
2
 The latest version of this slide will
be available from here
 http://www.slideshare.net/tetsu.koba/presentati
ons
3
Who am I?
 20+ years involved in embedded systems
 10 years in real time OS, such as iTRON
 10 years in embedded Java Virtual Machine
 Now GCC, Linux, QEMU, Android, …
 Blogs
 https://qiita.com/tetsu_koba
 http://d.hatena.ne.jp/embedded/
 http://kobablog.wordpress.com/(English)
 Twitter
 @tetsu_koba
はじめに
 golang の実行ファイルは自己完結的
 基本ライブラリ (libc に相当するもの )
は自前で持っている
 インストールするときに依存性が少ない
 後、何を追加したら、 Linux
カーネルと golang の実行ファ
イルだけで動かせる?
最小構成を理解するのは
エンジニアリングの基本
 削って削って、残ったものが本質。
 本日の「最小限」の定義
 ホスト名を解決してネットワークに
アクセスできること
 TLS( 暗号化通信 ) はオプション
 現在時刻を UTC で扱えること
 タイムゾーンはオプション
本日話すること
 gokrazy の紹介
 docker での最小限のコンテナの
実験
 最小限のルートファイルシステム
 miminumgo: 最小限の初期化処理
をする go パッケージ
Gokrazy の紹介
Gokrazy とは
 https://gokrazy.org/
 golang だけで Linux のユーザーランドを
構築してくれる
 ラズパイ 3 用のマイクロ SD カードを作成
 init, dhcp, ntp とユーザーのプロセスが実
行される
 WebUI でプロセスの状態が見られる
Gokrazy 動作中のルートファイ
ルシステム
/dev (mount devtmpfs)
/dev/pts (mount devpts)
/etc/hosts (auto generated)
/etc/localtime
/etc/resolv.conf -> /proc/net/pnp
/etc/ssl/ca-bundle.pem
/gokrazy/dhcp
/gokrazy/init
/gokrazy/ntp
/proc (mount proc)
/sys (mount sysfs)
/tmp (mount tmpfs)
/user/hello
Gokrazy の制限
 sh など通常のコマンドは含んでいない
 参考 gobox
 カーネルモジュールをロードするしくみ
は無い
 必要なモジュールはあらかじめカーネル
にビルトインしておく
 デバイスの抜き差しは扱わない
docker での
最小限のコンテナの実験
docker で busybox 一個のファ
イルを動かしてみた
 docker では実マシンでの初期
化処理を自動で行ってくれる
 具体的にそれが何かを実験で調べ
てみた。
 dockerでbusybox一個だけのファイルを含むイメージを作って動かしたらどうなるか
docker が自動生成したファイル
/dev (mount devtmpfs)
/dev/pts (mount devpts)
/etc/hostname
/etc/hosts
/etc/mtab -> /proc/mounts
/etc/resolv.conf
/proc (mount proc)
/sys (mount sysfs)
最小限のルートファイルシステム
最小限のルートファイルシステム
/dev (mount devtmpfs)
/dev/pts (mount devpts)
/etc/hosts (auto generated)
/etc/resolv.conf -> /proc/net/pnp
/proc (mount proc)
/sys (mount sysfs)
/tmp (mount tmpfs)
/etc/hostname が無い場合のデフォルトの hostname は IP アドレスの ASCII 表現
時刻に関して
 最小限では UTC のみが扱える
 ローカルタイムを扱うには /etc/localtime
を追加
 その他のタイムゾーンを扱うには
 /usr/share/zoneinfo/ 以下のファイルが
必要
 または、 runtime.GOROOT 以下に
/lib/time/zoneinfo.zip を置く
TLS( 暗号化通信 ) に関して
 最小限では TLS は扱えない
 /etc/ssl/certs/ 以下のファイルが必要
 ルート証明書だけでも
 /etc/ssl/certs/ca-certificates.crt
minimumgo: 最小限の初期化処理を
してくれる go パッケージ
minimumgo
 最小限の初期化処理をしてくれる
go パッケージを自作した
 ブランク (_) import するだけ
 その golang の実行ファイルを init
として動かせる
 設定はカーネルパラメータで
 ntp サーバの指定
使用例
package main
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe(":80",
http.FileServer(http.Dir("/"))))
}
この golang のプログラムを一個だけ動かしたい場合
使用例
package main
// This should be imported at first
import _ "github.com/tetsu-koba/minimumgo"
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe(":80",
http.FileServer(http.Dir("/"))))
}
minimumgo パッケージを import するだけで、
これを init として動かせる。
minimumgo
 https://github.com/tetsu-koba/minimumgo
 example に ラズパイ用にビルドして
initramfs のイメージを作成して動かす
方法を書きました
最後に
 本セッションの観察や実験を通して、 Linux の
起動時に行っていることが明らかに。
 「 Linux のユーザーランドを golang で init から
まるごと全部書く」 -> 達成。
 minimumgo パッケージは実験用。
 ブラックボックスとして使うのでなくてソー
スコードを参考にしてください。

References
 gokrazy
 Linuxのユーザーランドをinitから全てまるごと
golangで書く
 dockerでbusybox一個だけのファイルを
含むイメージを作って動かしたらどうなるか
 dockerでgolangの実行ファイル1個だけを
含むイメージを作って動かす
 https://github.com/tetsu-koba/minimumgo

25
Q & A
@tetsu_koba
Thank you for listening!

More Related Content

Linuxのユーザーランドをinitから全てまるごとgolangで書く