Raspberry Pi関連

Raspberry Piで IoT開発

関連記事: デジタル関連写真
関連記事: IoT関連写真

最近 IoT関連がマイブームです
Raspberry Pi関連のブログも書いていきます

Raspberry Pi 3 Model B+ と PiSTARTER

昔 BASIC に慣れ親しんだ思い出もあって PiSTARTERを購入しました
また併せて Raspberry Pi 3 ModelB+ も購入しました
ModelB に比べて若干パワーアップしています
PiSTARTER と RaspberryPi3ModelB+
秋葉原の TSUKUMOで購入 パッケージにも TSUKUMOロゴがプリントされてます
TSUKUMO独占販売の形です
RaspberryPi3ModelB+ 基板
Raspberry Pi 3 ModelB+ の基板です
左上ベリーロゴの付いた部分は無線モジュールで IEEE802.11ac対応 目立つデザインになりました
CPU最高速度が1.2GHzから1.4GHz へ イーサネットもファストイーサからギガビットイーサになり
全体的にパワーアップしています
PiSTARTER 開封状況
PiSTARTERパッケージの内容です
イメージキャラのイラストは 確か「べーしっ君」
PiSTARTERのソフトは microSDカードに入っていて RaspbianOS込みです
PiSTARTERの初回起動の際シリアル番号が求められます シリアルは同梱の許諾書に書かれてます

BASICは プログラムの入門に最適ですが RaspberryPi3とセットで買うと 1万円くらいで
子供の財布にはやっぱり厳しいかな

X68000風 RaspberryPiケース

Raspberry Pi用のケースです 伝説のパソコン X68000 のデザインです
秋葉原の BEEPや TSUKUMOで手に入ります 3000円くらいです
ミニチュアケース HELMETS X68000 for RaspberryPi 2/3
X68000のエミュレータを入れれば完璧ですね
デカシールというのも ガンプラ世代として懐かしい限り

Raspberry Pi 2 Model B

ラズパイ! Raspberry Pi をついに買いました (2016年9月)
Raspberry Pi 2 Model B 1
Raspberry Pi 2 Model B です
あとケースや 追加の USB-LAN USB-WiFi あと OS入れるために 32GBの microSDHCカード
Raspberry Pi 2 Model B 1
本体+ケース+メモリ で合計 12000円くらいでした
10年前は この 1/5くらいの性能の小型Linuxが 5倍くらいの値段だったことを考えると
ここ数年のモバイル性能の伸びのすごさが実感できます
Raspberry Pi 2 Model B 3
組み立ての状況です
ファン付きのケースで ファンへの電源供給に写真位置の GPIO 3.5Vを使ってます
Raspberry Pi 2 Model B 4
利用状況です モバイルバッテリで給電しています
Raspberry Pi 3になると性能向上してますが モバイルバッテリだと供給不足になるようなので
外での利用を想定するなら Raspberry Pi 2 がちょうどよいのではないでしょうか
OSは Raspbianという Linuxディストリビューションを使っていますが
IoT版 Windowsも無償利用可能です

PiCamera利用状況
年末には Raspberry Pi専用カメラモジュールも買いました
Tensorflowで 画像認識の実験をするためです
PiCamera接続状況
専用カメラは Raspberry Pi の専用コネクタに接続します
CPUに直結しているようで 高解像度(808万画素)の動画や画像が撮影できます
低解像度でもよければ USBカメラが手軽に利用できます

2TB超過のハードディスクを扱う(GPT)

2TB以上のハードディスクを扱うには新しめのマザーボードが必要

Linuxでは 従来のfdiskでなく partedというツールを使ってパーティション設定する
とあったので partedをインストールしてみたがうまくいかない

# cat /proc/partitions
major minor  #blocks  name

   8        0  244198584 sda
   8        1   10485688 sda1
   8        2  233712864 sda2
   8       16 1953514584 sdb
   8       17 1953512001 sdb1
   8       48 2930266584 sdd
   8       49 2147483647 sdd1
#
 

3TB HDDを partedでフォーマットしても
USBを挿し直すと sdd1が 2TBサイズと認識されてしまいます

2TB超過のHDDを扱うには parted以前にも必要な条件があります

検証システム
CPU AMD PhenomII X4 905e (2.5GHz 4コア)
マザーボード GA-880GM-USB3 (AMD880G+SB710)
メモリ 16GB
HDD WD30EZRX WD社製 Green 3TB (SATA 6Gbps)
センチュリー 裸族のお立ち台USB3.0 によるUSB接続
OS Gentoo-1.12.14 Linux-3.10.1 x86_64 UTF-8
コンパイラ gcc-4.5.2
Cライブラリ glibc-2.13

3TB以上の HDDを扱うには従来のMBR形式でなく
GPT形式でパーティション情報を扱う必要があります
下記が必要な条件です

その1 : UEFI対応マザーボード
GPT形式の内蔵ディスクから OSをブートするために必要
その2 : OSの対応
Windowsなら 64bit Vista以降が必要 Linuxならカーネルの設定が必要(下記参照)
その3 : GPTフォーマットツール
Linuxなら partedが必要

Linuxのカーネルに必要な設定は GUID Partition Supportです
Linux カーネル GUID Partition Support
USBディスクを挿し直すと パーティション情報が壊れていたのは
この設定が抜けていたためです

GPTが有効になった カーネルでは問題なく partedの設定も反映されました

# parted /dev/sdd
GNU Parted 3.1
/dev/sdd を使用
GNU Parted へようこそ! コマンド一覧を見るには 'help' と入力してください。
(parted) rm 1
(parted) unit s
(parted) mkpart
パーティションの名前?  []? ext3
ファイルシステムの種類?  [ext2]? ext3
開始? 2048s
終了? 5860533101s
(parted) print
モデル: USB 3.0 LucidPort USB300 (scsi)
ディスク /dev/sdd: 5860533168s
セクタサイズ (論理/物理): 512B/4096B
パーティションテーブル: gpt
ディスクフラグ:

番号  開始   終了         サイズ       ファイルシステム  名前  フラグ
 1    2048s  5860533101s  5860531054s  ext3              ext3

(parted) quit
通知: 必要であれば /etc/fstab を更新するのを忘れないようにしてください。
#
 

USB HDDを挿し直してもパーティションサイズは正しく認識されます

# cat /proc/partitions
major minor  #blocks  name

   8        0  244198584 sda
   8        1   10485688 sda1
   8        2  233712864 sda2
   8       16 1953514584 sdb
   8       17 1953512001 sdb1
   8       48 2930266584 sdd
   8       49 2930265527 sdd1
#
 

UML (User Mode Linux) 構築

仮想化 – UML (User Mode Linux)

過去の Software Design を読み返していたら UMLを紹介する記事がありました
最近の自己課題となっている仮想化環境実現の選択肢になるかと考え
最新の Linuxカーネルで試してみたらちゃんと動作したので その紹介をします

Software Design 2002-02
UMLとは User Mode Linuxの略でつまり
既に動いている Linuxシステム上で 別の Linuxカーネルを動かせます
いわゆる JAIL環境です ゲストとしての Linuxは割り当てられたリソース範囲内で動作します

ホストシステム構成K/caption>

CPU AMD PhenomII X4 905e (2.5GHz 4コア)
メモリ 16GB
OS Gentoo-1.12.14 Linux-3.7.8 x86_64 UTF-8
コンパイラ gcc-4.5.2
Cライブラリ glibc-2.13

ゲストシステムとしても 同じ最新のカーネル Linux-3.7.8 を使いました

構築 UML utilities

ゲスト用 Linuxカーネルと OSディスクイメージ を別途作成する必要ありますが
その前に ゲストLinuxを制御するツールをインストールします

まず制御ツールは UML Utilities というパッケージです
パッケージシステムを使っている Linuxならすぐインストールできると思います
ここでは 手動ビルドによるインストールを行います

UML Downloads Page
UMLのダウンロードページから ソースファイルを拾ってきて
以下のようにビルドします

$ tar -xjf uml_utilities_20070815.tar.bz2
$ cd tools-20070815
 

configureがないので Makefileを直接修正して必要な設定を行います
デフォルトでは 必要な tunctlツールがビルドされないのでこれを対象に加えます
Makefile の SUBDIR に tunctl エントリを追加します

TUNCTL = $(shell [ -e /usr/include/linux/if_tun.h ] && echo tunctl)

SUBDIRS = lib jail jailtest humfsify mconsole moo port-helper $(TUNCTL) \
        uml_net uml_switch watchdog umlfs tunctl
UMLVER = $(shell date +%Y%m%d)
TARBALL = uml_utilities_$(UMLVER).tar.bz2
BIN_DIR = /usr/bin

ifeq ($(shell uname -m),x86_64)
LIB_DIR = /usr/lib64/uml
else
LIB_DIR = /usr/lib/uml
endif

CFLAGS = -g -Wall
#CFLAGS = -g -O2 -Wall

export BIN_DIR LIB_DIR CFLAGS

 

なお インストール先のディレクトリを修正するなら
Makefile の BIN_DIR や LIB_DIR も修正してください
jail/Makefile の SBIN_DIR も修正が必要です

$ CC=gcc make
〜
make[1]: ディレクトリ `/home/admin/tools-20070815/mconsole' に入ります
gcc -g -Wall   -c -o uml_mconsole.o uml_mconsole.c
gcc -g -Wall -o uml_mconsole uml_mconsole.o ../lib/libuml.a -lreadline -lncurses
/usr/binutils/2.21/x86_64/bin/x86_64-gnu-linux-ld: cannot find -lncurses
collect2: ld はステータス 1 で終了しました
make[1]: *** [uml_mconsole] エラー 1
make[1]: ディレクトリ `/home/admin/tools-20070815/mconsole' から出ます
make: *** [all] エラー 2
 

ホスト環境では libncurses がないためエラーとなっていますが
libncursestw が代わりにあるためそれをリンクするように指示します
mconsole/Makefile の LIBS を修正します

BIN = uml_mconsole
OBJS = $(BIN).o
CFLAGS ?= -g -Wall
LIBS = ../lib/libuml.a -lreadline -lncursestw

BIN_DIR ?= /usr/bin

all : $(BIN)

$(BIN) : $(OBJS)
        $(CC) $(CFLAGS) -o $(BIN) $(OBJS) $(LIBS)

clean : 
        rm -f $(BIN) $(OBJS) *~

install : $(BIN)
        install -d $(DESTDIR)$(BIN_DIR)
        install -s $(BIN) $(DESTDIR)$(BIN_DIR)
 
$ CC=gcc make
set -e ; for dir in lib jail jailtest humfsify mconsole moo port-helper  uml_net uml_switch watchdog umlfs; do make -C $dir all; done
make[1]: ディレクトリ `/home/admin/tools-20070815/lib' に入ります

〜

gcc -g -Wall -D_FILE_OFFSET_BITS=64 -I/usr/local/include -o uml_mount uml_mount.o -lfuse
make[1]: ディレクトリ `/home/admin/tools-20070815/umlfs' から出ます
make[1]: ディレクトリ `/home/admin/tools-20070815/tunctl' に入ります
gcc -g -Wall   -c -o tunctl.o tunctl.c
gcc -g -Wall -o tunctl tunctl.o
make[1]: ディレクトリ `/home/admin/tools-20070815/tunctl' から出ます
$
 

なお ビルドにあたって fuse が必要になるので
fuse関連のエラーが出た場合はそこを疑ってください

次にインストールですが インストール先を変更するには
先に Makefile の BINDIR や jail/Makefile の SBINDIR を手修正します
デフォルト /usr/bin /usr/sbin /usr/libか/usr/lib64 のままでほぼ問題ないです

$ su
# make install
set -e ; for dir in lib jail jailtest humfsify mconsole moo port-helper  uml_net uml_switch watchdog umlfs; do make -C $dir install; done
make[1]: ディレクトリ `/home/admin/tools-20070815/lib' に入ります
make[1]: `install' に対して行うべき事はありません.

〜

install -s uml_mount /usr/bin
make[1]: ディレクトリ `/home/admin/tools-20070815/umlfs' から出ます
make[1]: ディレクトリ `/home/admin/tools-20070815/tunctl' に入ります
install -d /usr/bin
install -s tunctl /usr/bin
make[1]: ディレクトリ `/home/admin/tools-20070815/tunctl' から出ます
#
 

bin/ 以下 sbin/ 以下には下記プログラムがインストールされます

bin/:
humfsify  tunctl        uml_mkcow  uml_mount  uml_switch
jailtest  uml_mconsole  uml_moo    uml_net    uml_watchdog

sbin/:
jail_uml
 

構築 ディスクイメージ

ゲストLinuxの動作用として Gentoo stage3 ベースのシステムを準備します
Gentoo amd64 Downloads Page
UMLはエミュレータではありませんので
ホストシステムと同じアーキテクチャの システムイメージが必要です
ここでは 検証環境と同じ amd64 の tarball をダウンロードしました

下記のように 1GB の EXT3ディスクイメージを作って tarballを展開します

$ dd if=/dev/zero of=uml_gentoo_st3_20120605 bs=1048576 count=1024
1024+0 レコード入力
1024+0 レコード出力
1073741824 バイト (1.1 GB) コピーされました、 1.25505 秒、 856 MB/秒
$ mke2fs -j uml_gentoo_st3_20120605
mke2fs 1.41.12 (17-May-2010)
uml_gentoo_st3_20120605 is not a block special device.
Proceed anyway? (y,n) y
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
65536 inodes, 262144 blocks
13107 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376

Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 22 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
$ su
Password:
# mount -t ext3 -o loop uml_gentoo_st3_20120605 /mnt/target
# cd /mnt/target
# tar -xjpf ~admin/stage3-amd64-20130130.tar.bz2
# ls
bin   dev  home  lib32  lost+found  mnt  proc  run   sys  usr
boot  etc  lib   lib64  media       opt  root  sbin  tmp  var
#
 

ファイルシステムへの書き込みのために root権限を使いましたが
Gentooのシステムは書き込めました

ゲストファイルシステムの設定を続けます etc/fstab をカスタマイズします

#/dev/BOOT              /boot           ext2    noauto,noatime          1 2
#/dev/ROOT              /               ext3    noatime                 0 1
/dev/ubda               /               ext3    noatime,defaults        0 1
proc                    /proc           proc    defaults                0 1
#/dev/SWAP              none            swap    sw                      0 0
#/dev/cdrom             /mnt/cdrom      auto    noauto,ro               0 0
#/dev/fd0               /mnt/floppy     auto    noauto                  0 0
 

SWAPも無効化してます ルートディレクトリの /dev/ubda は仮想ファイルシステムで
UBD(UML Block Device)です ホスト側のシステムイメージを UMLで扱えます
/dev/udba を作成しておく必要があります 下記の通りです

# mknod /mnt/target/dev/udba c 98 0
#
 

UBDは メジャー番号 98 です
複数のシステムイメージを扱うなら MAKEDEVスクリプトでまとめて作る方法もあります

次は ネットワークを設定です SSHでログインできるようにします
まず ネットワークの設定です ゲスト側 etc/conf.d/net に設定するだけです

config_lo0="127.0.0.1 netmask 255.0.0.0 brd 127.255.255.255"
config_eth0="192.168.255.254 netmask 255.255.255.0"
routes_eth0="default via 192.168.255.1"
 

今回の UML構築にあたっては TUN/TAP仮想ネットワークを利用した
下記のネットワークで構築します
UML TUN/TAPネットワーク構成
ゲスト側の eth0インターフェース と ホスト側の tap0インターフェース が通信します
その通信ネットワークとして動作するのが TUN仮想ネットワークです

ホストLinux側で IPv4のルーティングを有効化すれば
家庭内LANとの通信も可能になるので UMLサーバを外部と通信させることも可能です
(ホスト側で echo 1 > /proc/sys/net/ipv4/ip_forward  を実行する)

TUN/TAPを使わない別の方法としては uml_switch を使った仮想ネットワークが考えられますが
家庭内LANとの通信はできない 閉じたネットワークとなります

また start/stopスクリプトの net.eth0 がゲスト起動時にサービス開始され
eth0 を初期化するようにします

# ln -s /etc/init.d/net.lo /mnt/target/etc/init.d/net.eth0
#
 

続いて SSHログインできるようにするための設定ですが
まず ログイン用アカウントを作成するところから必要です
chrootを使って ゲスト側のイメージにルートディレクトリを変更して作業します

# chroot /mnt/target /bin/bash
# useradd admin -m -g users -G wheel -s /bin/bash
# passwd admin
新しいパスワード:
よくないパスワード: 短かすぎます
よくないパスワード: 簡単すぎます
新しいパスワードを再入力してください:
passwd: パスワードは正しく更新されました
# passwd root
新しいパスワード:
よくないパスワード: 短かすぎます
よくないパスワード: 簡単すぎます
新しいパスワードを再入力してください:
passwd: パスワードは正しく更新されました
# id admin
uid=1000(admin) gid=100(users) groups=100(users),10(wheel)
#
 

ゲスト側のイメージに adminアカウントが作成されました
admin権限にスイッチして SSHの設定作業します

# su admin
$ mkdir ~/.ssh
$ cd !!:1
$ ssh-keygen -t rsa -f uml_admin
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in uml_admin.
Your public key has been saved in uml_admin.pub.
The key fingerprint is:
eb:57:3a:**:**:**:**:**:**:**:**:**:e2:ff:fb:67 admin@phenom
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|  o.*o+.o + E    |
| . .=Xo.+=.+     |
+-----------------+
$ ls
uml_admin  uml_admin.pub
$ cat uml_admin.pub > authorized_keys
$ chmod 600 authorized_keys
$
 

SSHの RSAログイン用のキーを作って設定しました
最後に ゲストシステムの起動時に sshdが起動する設定をいれます

$ exit
# ln -s /etc/init.d/sshd /etc/runlevels/default/sshd
#
 

ゲストファイルシステムのマウントまで解除して完成です
なお SSHのプライベートキー uml_admin ファイルは SSHログインに必要なので
ホストシステム側に退避しておきます

# exit
# cp /mnt/target/home/admin/.ssh/uml_admin ~admin/
# umount -d /mnt/target
#
 

これで ゲストシステムが起動したとき SSHログインできるはずです

構築 Linuxカーネル

Linuxのカーネルは ゲストLinux用 に構築する必要があります
構築についても単純で makeオプションに ARCH=um を指定するだけです

ただし ビルド用のディレクトリは ホスト側カーネル構築用ディレクトリと
別に作る必要はあります

早速 実施してみます Linuxカーネルのソースを展開したディレクトリで

$ make CC=gcc NM=nm AR=ar LD=ld OBJCOPY=objcopy ARCH=um mrproper
$ make CC=gcc NM=nm AR=ar LD=ld OBJCOPY=objcopy ARCH=um menuconfig
 

UML専用のメニュー項目がいくつか見えます
UML Linux Kernel Config 1
ほとんどの選択肢は 初期状態のままで大丈夫です
ポイントとなる箇所を 下記画面キャプチャで紹介します
UML Linux Kernel Config 2
UML-specific options の Host filesystem はここでは無効化しています
Host filesystemとは ゲストシステム側からホスト側のディレクトリをマウントする便利機能です

ゲストシステムを他人に渡して使ってもらうような サーバレンタル用途を考えているなら
ホストシステムファイルの参照権限を渡さないほうがよいでしょう
UML Linux Kernel Config 3
UML Charcter Devices で ゲスト側の起動コンソールを設定できます

ゲスト側ブートコンソールとなるのが Default main console channel initialization の部分で
fd:0,fd:1 という指定は 標準出力と標準入力を使ってください という意味です

その下の xterm という指定は コンソールログイン端末の指定です
ブート完了時に xtermが開いてログインプロンプトが表示されます
ただし検証環境は Xサーバを動かしてないモニタレスサーバなので xtermは立ち上がりません
UML Linux Kernel Config 4
Block devices では Virtual block device というのが重要です
これにより 先ほどのOSイメージを扱う ubd仮想デバイスが使えるようになります
UML Linux Kernel Config 5
UML Network Devices でネットワークデバイス関連の設定が可能です
TUN/TAP経由でホスト側と仮想ネットワーク接続するので TUN/TAPの設定が必要です
また複数のゲストLinuxを仮想ネットワーク接続する場合 Daemon transportが必要です
UML Linux Kernel Config 6
最後 File systemsですが
デフォルトでは ext2 と ext3 が無効化されていたので 有効化しました
OSイメージのファイルシステムや 必要性に応じて判断してください

以上でカーネルのコンフィグを終了して ビルド開始します

scripts/kconfig/mconf arch/x86/um/Kconfig

#
# configuration written to .config
#


*** End of the configuration.
*** Execute 'make' to start the build or try 'make help'.

$ make CC=gcc NM=nm AR=ar LD=ld OBJCOPY=objcopy ARCH=um
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf --silentoldconfig arch/x86/um/Kconfig

〜

  LD [M]  drivers/net/slip/slhc.ko
  CC      drivers/net/slip/slip.mod.o
  LD [M]  drivers/net/slip/slip.ko
  CC      drivers/net/tun.mod.o
  LD [M]  drivers/net/tun.ko
  CC      fs/autofs4/autofs4.mod.o
  LD [M]  fs/autofs4/autofs4.ko
  CC      fs/binfmt_misc.mod.o
  LD [M]  fs/binfmt_misc.ko
  CC      fs/isofs/isofs.mod.o
  LD [M]  fs/isofs/isofs.ko
  CC      sound/soundcore.mod.o
  LD [M]  sound/soundcore.ko
$ ls -l linux
-rwxr-xr-x 2 deer wheel 43645642 Mar  5 23:08 linux
$
 

linux という実行形式ファイルができています
これが UMLで動作する Linuxカーネル本体です

この linuxコマンド自体は ホストシステム側から起動しますが
それ以外 System.map カーネルモジュール はゲストシステムへ転送する必要があります

$ su
Password:
# mount -t ext3 ~admin/uml_gentoo_st3_20120605 /mnt/target
# cp System.map /mnt/target/boot/
# make CC=gcc NM=nm AR=ar LD=ld OBJCOPY=objcopy ARCH=um INSTALL_MOD_PATH=/mnt/target modules_install
  INSTALL arch/um/drivers/hostaudio.ko
  INSTALL block/cfq-iosched.ko
  INSTALL crypto/ansi_cprng.ko
  INSTALL crypto/krng.ko
  INSTALL crypto/rng.ko
  INSTALL drivers/block/loop.ko
  INSTALL drivers/block/nbd.ko
  INSTALL drivers/net/dummy.ko
  INSTALL drivers/net/ppp/ppp_generic.ko
  INSTALL drivers/net/slip/slhc.ko
  INSTALL drivers/net/slip/slip.ko
  INSTALL drivers/net/tun.ko
  INSTALL fs/autofs4/autofs4.ko
  INSTALL fs/binfmt_misc.ko
  INSTALL fs/isofs/isofs.ko
  INSTALL sound/soundcore.ko
  DEPMOD  3.7.8
# umount -d /mnt/target
# exit
$
 

これで INSTALL_MOD_PATH配下の lib/modules/ にカーネルモジュールが入りました
ちなみにゲストファイルシステム側に linux カーネル本体を入れる必要はありません

ゲストLinux起動

ゲストLinux 起動の前に ホスト側のネットワークインターフェース作成します

$ su
Password:
# tunctl -t tap0 -u 500
Set 'tap0' persistent and owned by uid 500
# ifconfig tap0 192.168.255.1 netmask 255.255.255.0 up
# ifconfig tap0
tap0      Link encap:Ethernet  HWaddr 36:d1:e7:3d:75:44  
          inet addr:192.168.255.1  Bcast:192.168.255.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

#
 

tunctl時に -u で ゲストシステムを起動するユーザの UIDを指定する必要がありました
(そうしないと ゲストLinuxの起動時に eth0 が up状態にできませんでした)
tap0 は使い終わったら tunctl -d tap0 で削除できます


ともかくホスト側に 192.168.255.0/24 のネットワークが構築されました
ホスト側の準備は以上です

ゲストLinuxを起動してみます

$ ~/linux-3.7.8/linux ubd0=~/uml_gentoo_st3_20120605 eth0=tuntap,tap0 mem=96M
Core dump limits :
        soft - 0
        hard - NONE
Checking that ptrace can change system call numbers...OK
Checking syscall emulation patch for ptrace...OK
Checking advanced syscall emulation patch for ptrace...OK
Checking for tmpfs mount on /dev/shm...OK
Checking PROT_EXEC mmap in /dev/shm/...OK
Checking for the skas3 patch in the host:

〜

 * Initializing random number generator ...
 [ ok ]
INIT: Entering runlevel: 3
 * Bringing up interface eth0
 *   192.168.255.254 ...
 [ ok ]
 *   Adding routes
 *     default via 192.168.255.1 ...
 [ ok ]
 * Mounting network filesystems ...
 [ ok ]
 * Generating dsa host key ...
Generating public/private dsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_dsa_key.
Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub.
The key fingerprint is:
e2:da:53:06:1e:d5:97:b9:6e:e1:3a:94:4c:4c:9a:48 root@localhost
The key's randomart image is:
+--[ DSA 1024]----+
|         .   o   |
|      E . o +    |
|     . o = . .   |
|      + o o o    |
|     ..oSo + .   |
|     ...o + +    |
|      .o . o     |
|     o.   o      |
|    . ..   .     |
+-----------------+
 [ ok ]
 * Generating rsa host key ...
Generating public/private rsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_rsa_key.
Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub.
The key fingerprint is:
6e:f1:ea:e7:bc:23:f1:d5:78:f7:4d:88:a5:a9:b3:a1 root@localhost
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|                 |
|              .  |
|        S    B . |
|       ..o  * + o|
|        oooo . oo|
|       ..+*.    o|
|       .E+==     |
+-----------------+
 [ ok ]
 * Starting sshd ...
 [ ok ]
 * Starting local
bash: no job control in this shell
 

初回起動のため SSHのサンプル鍵ペアが自動作成されてますが 使うことはありません
既に SSHの鍵ペアは作成済のためです

また ゲストLinux側のコンソールは起動プロセスが完了した後 プロンプトがなくなりました
Xが動くホストシステムなら xtermが何枚か開いて ログインプロンプトが出るはずです

ホストLinuxから TUN/TAP経由で SSHログインしてみましょう

$ ssh -i uml_admin admin@192.168.255.254
The authenticity of host '192.168.255.254 (192.168.255.254)' can't be established.
RSA key fingerprint is 6e:f1:ea:**:**:**:**:**:**:**:**:**:**:a9:b3:a1.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.255.254' (RSA) to the list of known hosts.
Password:
admin@localhost ~ $
 

ゲストシステムに SSHログインすることができました
ここまでできれば 残りのシステム構築は SSH経由で可能です

admin@localhost ~ $ uname -a
Linux localhost 3.7.8 #1 Tue Mar 5 23:08:40 JST 2013 x86_64 UML User Mode Linux GNU/Linux
admin@localhost ~ $ ifconfig -a
eth0: flags=4163  mtu 1500
        inet 192.168.255.254  netmask 255.255.255.0  broadcast 192.168.255.255
        ether 0a:ea:b7:27:57:6f  txqueuelen 1000  (Ethernet)
        RX packets 75  bytes 7145 (6.9 KiB)
        RX errors 0  dropped 6  overruns 0  frame 0
        TX packets 44  bytes 6456 (6.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 5  

lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 0  (Local Loopback)
        RX packets 4  bytes 344 (344.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 4  bytes 344 (344.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

admin@localhost ~ $ cat /proc/cpuinfo
processor       : 0
vendor_id       : User Mode Linux
model name      : UML
mode            : skas
host            : Linux phenom 3.7.8 #9 SMP Tue Feb 26 19:37:43 JST 2013 x86_64
bogomips        : 2505.11

admin@localhost ~ $  cat /proc/meminfo
MemTotal:          90912 kB
MemFree:           68276 kB
Buffers:            1248 kB
Cached:            11476 kB
SwapCached:            0 kB
Active:             9484 kB
Inactive:           7116 kB
Active(anon):       3908 kB
Inactive(anon):       20 kB
Active(file):       5576 kB
Inactive(file):     7096 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:          3892 kB
Mapped:             3820 kB
Shmem:                52 kB
Slab:               4412 kB
SReclaimable:       2448 kB
SUnreclaim:         1964 kB
KernelStack:         240 kB
PageTables:          884 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       45456 kB
Committed_AS:      10880 kB
VmallocTotal:   534134768 kB
VmallocUsed:           0 kB
VmallocChunk:   534134768 kB
admin@localhost ~ $
 

ゲストシステムには 1CPUしか割り当てられないので
シングルCPUマシンのように表示されます

メモリは ゲスト起動時に mem=96M と割り当てられた通りです

次に ネットワークの接続性です

admin@localhost ~ $ ping 192.168.0.254
PING 192.168.0.254 (192.168.0.254) 56(84) bytes of data.
64 bytes from 192.168.0.254: icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from 192.168.0.254: icmp_seq=2 ttl=64 time=0.041 ms
^C
--- 192.168.0.254 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1007ms
rtt min/avg/max/mdev = 0.041/0.041/0.042/0.006 ms
admin@localhost ~ $ ping 192.168.0.1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
^C
--- 192.168.0.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1007ms
admin@localhost ~ $
 

ホストLinuxとは疎通しますが ホームゲートウェイとはつながりません
なぜでしょうか?
ホームゲートウェイに 192.168.255.0/24 へのルーティング設定が必要です
ゲストファイルシステムの設定のところで説明した ネットワーク図を見ればわかりますが

インターネットと接続するためには 上記ルーティングの追加と
ゲストシステムへの DNS設定が必要となります
また レンタルサーバとして他人に提供する場合にセキュリティ考慮が必要です
家庭内LAN 192.168.0.0/24 が覗けないように DMZ化する検討が必要です
ホストシステム側 tap0 に対するファイアウォール設定で実現できます

最後に ゲストシステムのシャットダウンですが
ゲストシステムがフリーズした場合など ホストシステムから制御する方法があります
uml_mconsole コマンドが使えます ホストシステム側から下記のように操作します

$ cd ~/.uml
$ ls
yJ4qJG
$ uml_mconsole yJ4qJG
(yJ4qJG) int
(yJ4qJG) quit
$
 

yJ4qJG と見えているのは UNIXドメインソケットです
このソケットを通じてゲストシステムを制御できます
int と入力するとゲストシステムが終了するのを確認できます

最後に

UMLを使うことで 仮想マシンに近い環境を構築できることを確認しました

ただし User Mode と冠がついているのとは実際は異なり
(カーネルは 一般ユーザ権限でビルドできますが)
ファイルシステムの作成 や TUN/TAPインターフェースの生成に root権限が必要です
(ファイルシステムについては UML用のイメージを探すなどの代替策は考えられます)

ALSA環境の構築して Linux上で音楽を鳴らす

Linuxの音声再生環境を整える

ALSA (Advanced Linux Sound Architechture) は Linux用のサウンドAPI群です

1999年頃 前身である OSS(Open Sound System)が普及するまでは
サウンドボード毎にドライバも異なり再生環境を構築するのは特殊な作業でした

アプリケーションが OSSに対応し始めると一気に Linuxのサウンド環境が改善し
今まで「無音状態」だった Linuxシステムにマルチメディアという魅力が付与されたのです

Linux-2.6では ALSAがカーネルに取り込まれ標準機能となると
Windowsと同じように「何も意識しなくても再生環境は整っている」状況までなりました
ALSAが一気に普及できたのは OSSよりも高機能な上
OSS互換APIを持っていたため アプリケーションの移行がスムーズに進んだためです

ここでは 下記の検証環境で ALSAの環境構築までをレポートします

検証環境
CPU AMD Turion-MT37 2GHz
メモリ DDR-400 1.5GB
サウンド SoundBlaster Live! Value
OS Linux-2.6.39
GCC gcc-4.6.2
alsa-lib alsa-lib-1.0.25
alsa-utils alsa-utils-1.0.25
awesfx awesfx-0.5.1d

ALSAパッケージ構成とインストール

ALSA関連のパッケージは複数に別れています
ALSA公式ページ で配布されている各パッケージの役割を整理すると

パッケージ

alsa-firmware

特定のサウンドボード向けファームウェア
alsa-driver

ドライバ本体 Linux-2.6以降は不要
alsa-oss

liboss ALSA自体が既にOSSエミュレーションするので通常不要
alsa-plugins

追加プラグイン 通常不要
alsa-lib

基本ライブラリ libasound 必要
alsa-utils

alsamixer や aplay などの基本アプリ

Linux-2.6以上であれば alsa-lib と alsa-utils のみで十分です

alsa-lib は下記のオプションでインストールしました

$ ./configure --prefix=/usr/local
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a BSD-compatible install... /bin/install -c

〜

config.status: creating include/config.h
config.status: executing depfiles commands
Creating asoundlib.h...
$ make
〜
$ su
〜
# make install
〜
#
 

aserverコマンドや libasoundライブラリがインストールされます

alsa-utils は下記オプションでインストールしました

$ ./configure --prefix=/usr/local --disable-xmlto --with-udev-rules-dir=/etc/udev/rules.d --with-asound-state-dir=/var/state
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p

〜

config.status: creating po/POTFILES
config.status: creating po/Makefile
config.status: executing depfiles commands
$ make
〜
$ su
〜
# make install
〜
#
 

こちらは基本ツールがメインで bin/ 以下に下記のツールがインストールされます

aconnect  alsamixer  amidi   aplay      arecord      aseqdump  iecset
alsaloop  alsaucm    amixer  aplaymidi  arecordmidi  aseqnet   speaker-test
 

音楽再生 MIDI再生 録音 設定ツール が一通り揃っています
speaker-test で音声が鳴るのを確認したら ALSA関連のインストールは完了です
後は mpg123など libasound対応のアプリを好きなだけインストールしましょう

$ speaker-test

speaker-test 1.0.25

Playback device is default
Stream parameters are 48000Hz, S16_LE, 1 channels
Using 16 octaves of pink noise
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 128 to 32768
Period size range from 32 to 32768
Using max buffer size 32768
Periods = 4
was set period_size = 8192
was set buffer_size = 32768
 0 - Front Left
^C
$
 

もし SoundBlasterシリーズの音源カードを利用されているなら
MIDI再生の環境も整えてしまいましょう

ほとんどの SoundBlasterシリーズのカードは「サウンドフォント」をサポートしていて
ハードウェアでMIDIを鳴らすことができます
最近はゲーム等でも MIDIを鳴らす機会が減ってしまいましたが
SoundBlasterシリーズの魅力の一つとして このサウンドフォントサポートが挙げられます

ここでは サウンドフォントをシステムに読み込むための asfxloadをインストールして
実際にサンプルMIDIを演奏するところまでを紹介します
asfxloadは awesfxパッケージに含まれています
ソースコードを展開して configure 〜 make 〜 make install します

$ ./configure --prefix=/usr/local --with-sfpath=/usr/local/share/sounds/sf2
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p

〜

config.status: creating etc/Makefile
config.status: creating include/config.h
config.status: executing depfiles commands
$ make
Making all in awelib

〜

gcc -g -O2 -o sfxtest sfxtest.o seq.o  awelib/libawe.a /usr/local/lib/libasound.so -lrt -lm -ldl -lpthread   -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,/usr/local/lib
make[1]: Leaving directory `/home/deer/admin/Alsa/awesfx-0.5.1d'
$ su
# make install
〜
#
 

configureではサウンドフォント配置先を /usr/local/share/sounds/sf2/ としました
インストールされるコマンドは 下記のとおりです

asfxload  aweset  gusload  setfx  sf2text  sfxload  sfxtest  text2sf
 

サウンドフォントは SoundBlasterのドライバCDなどに含まれている
8mbgmsfx.sf2 を使いました ファイル名の通りGM準拠で8MBの容量があります
サウンドフォントディレクトリに 8mbgmsfx.sf2 をコピーして asfxloadでシステムにロードします

# ls /usr/local/share/sounds/sf2/
8mbgmsfx.sf2  default-2m.bnk    test.bnk       xgmap.bnk
README-bank   emu8m.bnk         xgdefault.bnk  xgsfx.bnk
ch12msup.bnk  setfx-sample.cfg  xgdrum.bnk
# cat /proc/asound/Live/wavetableD1
Device: Emu10k1
Ports: 4
Addresses: 17:0 17:1 17:2 17:3
Use Counter: 0
Max Voices: 64
Allocated Voices: 0
Memory Size: 134217728
Memory Available: 134213632
Allocated Blocks: 1
SoundFonts: 0
Instruments: 0
Samples: 0
Locked Instruments: 0
Locked Samples: 0
# asfxload /usr/local/share/sounds/sf2/8mbgmsfx.sf2
# cat /proc/asound/Live/wavetableD1
Device: Emu10k1
Ports: 4
Addresses: 17:0 17:1 17:2 17:3
Use Counter: 0
Max Voices: 64
Allocated Voices: 0
Memory Size: 134217728
Memory Available: 126786844
Allocated Blocks: 527
SoundFonts: 1
Instruments: 1849
Samples: 526
Locked Instruments: 1849
Locked Samples: 526
#
 

SoundFontsの項がカウントアップされているのがわかります
(サウンドフォントはメモリの許す限り複数ロードできますが 検証環境では試してません)
また MIDI用のポートが 17:0 17:1 17:2 17:3 と 4つあることもわかります
ではサンプルとしてどこからか拾ってきた ワルキューレの伝説 を鳴らしましょう

$ aplaymidi -p 17:0 LEGENDofVALKYRIE.mid
$
 

サウンドが鳴れば 無事にMIDI環境が動作しています
asfload のロードはシステム起動時に実行する必要があるため 起動スクリプト等に組込んで完成です

8bit 16bit 時代では高価な MIDI専用機を購入しなければ手に入らなかった
MIDI再生環境が 今やLinux上で再現できてしまいます 感慨深いものです
MIDI Roland SD-20
一方 ハードウェア音源の例では 上記 Roland SD-20 のようなものが挙げられます
最近の MIDI再生機器も小型化され USB接続可能となるなどの進化を遂げており
(通常 MIDI機器は専用のMIDIインターフェースで音源ボードと接続する)
実際筆者はこの SD-20を所持していて クリアな発声などそれなりの魅力もありますが
やはり ハードウェア音源はお金持ち向けという印象がぬぐえません

ちなみに Windows+DirectXは ソフトウェア音源上で MIDIを演奏する動作になってます
従って安物のオンボードサウンドチップでも 何も考えずにMIDIが鳴ります
(MIDI再生に必要なリソースは CPUが負担しているため
SoundBlasterご利用なら MIDI出力をサウンドフォント用ポートに切り替えたほうがよいでしょう)


トラブル事例

筆者の検証環境のみの特殊事例かもしれませんが 当初下記エラーが出て困っていました

$ aplay -L
Segmentation fault
$
 

で全く音声が鳴らないという事象です
原因を調査した結果 「-lライブラリ にて実行時リンクするライブラリに対して 動的リンクも行い長いシンボル名を dlopen() dlsym() dlclose() 繰り返すと不正終了する」
といった 日本語で表現するのも難しいほど 理解不能な現象でした

下記検証プログラム t_main.c で Segmentation fault が再現されました

#include 
#include 

int main ()
{
  int i;
  void *handle = NULL;
  void *target = NULL;

  for ( i = 0; i != 10; i++ ) {
    handle = dlopen ( "libz.so", RTLD_NOW );
    if ( handle )
      target = dlsym ( handle, "long___________long" );
    else
      printf ( "failed dlopen()\n" );
    dlclose ( handle );
    printf ( "count=%d\n", i );
  }
  return ( 0 );
}
 

/usr/local/lib/libz.so を実行時リンクする下記のバイナリを作って実行すると

$ gcc -lz -ldl -o t_main t_main.c
$ ./t_main
count=0
count=1
Segmentation fault
$
 

カーネルの問題なのか glibcの問題なのか判りません 検証環境のみの現象かもしれません
alisa-lib が丁度この条件に引っかかったようでしたので
src/dlmisc.c の snd_dlopen() 関数部分を修正して対策しました

 51 void *snd_dlopen(const char *name, int mode)
 52 {
 53         return dlopen(name, mode);
 54 #ifndef PIC
 55         if (name == NULL)
 56                 return &snd_dlsym_start;
 57 #else
 58 #ifdef HAVE_LIBDL
 59         if (name == NULL) {
 60                 static const char * self = NULL;
 61                 if (self == NULL) {
 62                         Dl_info dlinfo;
 63                         if (dladdr(snd_dlopen, &dlinfo) > 0)
 64                                 self = dlinfo.dli_fname;
 65                 }
 66                 name = self;
 67         }
 68 #endif
 69 #endif
 70 #ifdef HAVE_LIBDL
 71         return dlopen(name, mode);
 72 #else
 73         return NULL;
 74 #endif
 75 }
 

53行目にあるように いきなり return dlopen(name, mode); で返るように修正しました
name= にあたる部分の /usr/local/lib/libasound.so.2 が長い名前だったことが
今回の不具合に該当してしまったようです

$ aplay -L
null
    Discard all samples (playback) or generate zero samples (capture)
default:CARD=Live
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    Default Audio Device
sysdefault:CARD=Live
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    Default Audio Device
front:CARD=Live,DEV=0
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    Front speakers
rear:CARD=Live,DEV=0
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    Rear speakers
center_lfe:CARD=Live,DEV=0
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    Center and Subwoofer speakers
surround40:CARD=Live,DEV=0
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    4.0 Surround output to Front and Rear speakers
surround41:CARD=Live,DEV=0
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Live,DEV=0
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Live,DEV=0
    SB Live! Value [CT4670], ADC Capture/Standard PCM Playback
    5.1 Surround output to Front, Center, Rear and Subwoofer speakers
iec958:CARD=Live,DEV=0
    SB Live! Value [CT4670], Multichannel Capture/PT Playback
    IEC958 (S/PDIF) Digital Audio Output
$
 

aplay -L も正しく結果を返すようになり 音楽も鳴りました

 

IPv6サーバツール

各種サービスの IPv6対応状況について

ここもちょっとずつ 更新して情報を集める予定です
特に UNIX系は自分が実際に試してみたものをレポートしています

サービス対応状況 システム
ソフトウェア 状況 コメント
Linuxカーネル CONFIG_IPV6=y から始まる各種オプションが必要
FreeBSDカーネル options INET6 を指定するだけ
Windowsカーネル WindowsXP SP1以降ならカーネルに組み込まれてます
各ネットワークの設定で IPv6を有効化するだけ
サービス対応状況 UNIX
ソフトウェア サービス IPv6対応 コメント
TCP Wrappers hosts.allow と
hosts.deny による
TCPアクセス制御

IPv6版のパッケージが必要
ビルドするのにコツが要る
DHCP DHCPサーバ ISC-DHCPでは DHCPv4 と DHCPv6 とで
それぞれ別の設定とプロセス起動が必要
BIND DNSサーバ named.confに IPv6設定が必要
OpenSSH 暗号化通信 特に追加オプション等不要
OpenLDAP データベース o 特に追加オプション等不要
Postfix メール配送 o 特に追加オプション等不要
Dovecot メール o 特に追加オプション等不要
Apache Webサーバ 特に追加オプション等不要
MySQL データベース 非対応 IPv4射影IPv6に対応できるか未検証
PostgreSQL データベース 特に追加オプション等不要
Oracle データベース 未確認 Oracle11g ExpressEdition がうまく動作せず未確認

IPv6トップへ戻る