sstea備忘録

日々のPCライフのメモ、備忘録、及びそれに類推する何か。
記載内容に間違い等を発見された場合はコッソリ教えてください... → sstea<a>aol.jp (<a> を @ に変えてください)


RaspberryPi

Raspberry Pi で音を出してみる

手元に USBスピーカー(iBUFFALO BSSP25U)があったので、それを接続し Raspberry Pi から音を出してみたいと思います。

◆Raspberry Pi にUSBスピーカーを接続
まずUSBスピーカーを接続し、認識しているか確認します。
$ cat /proc/asound/cards
 0 [ALSA           ]: bcm2835 - bcm2835 ALSA
                      bcm2835 ALSA
 1 [MicroII        ]: USB-Audio - Audio Advantage MicroII
                      C-Media INC. Audio Advantage MicroII at usb-bcm2708_usb-1.3, full speed

ちゃんと認識しています。
が、USB-Audio が二つ目になっているので、このままではUSBスピーカーからは音は出ません。

/etc/modprobe.d/alsa-base.conf の snd-usb-audio の行をコメントアウトします。
#options snd-usb-audio index=-2

いったん、モジュールをアンロードし、再ロードします。
$ sudo alsa unload
$ sudo modprobe snd_usb_audio
$ sudo modprobe snd_bcm2835

USB-Audio が一つ目になっているのを確認します。
$ cat /proc/asound/cards
 0 [MicroII        ]: USB-Audio - Audio Advantage MicroII
                      C-Media INC. Audio Advantage MicroII at usb-bcm2708_usb-1.3, full speed
 1 [ALSA           ]: bcm2835 - bcm2835 ALSA
                      bcm2835 ALSA

◆Raspberry Pi にしゃべってもらう

まずは、AquesTalk Pi (http://www.a-quest.com/products/aquestalkpi.html) から aquestalkpi-20130827.tar.gz をダウンロードしてきます。

それを raspberry pi 上で展開します。
$ mkdir /home/pi/local/
$ cd /home/pi/local/
$ tar xvzf aquestalkpi-20130827.tar.gz
下記を実行。
$ aquestalkpi/AquesTalkPi hello | aplay
しゃべったー!!

$ mkdir /home/pi/local/bin/
$ cd /home/pi/local/bin/
talk.sh という名前のシェルスクリプトを書いてみました。
#!/bin/sh

TALK=/home/pi/local/aquestalkpi/AquesTalkPi

${TALK} -s 120 "$*" | aplay 2> /dev/null

上記をコピペするなり、curl コマンドで取るなりします。
$ curl -O http://sstea.blog.jp/raspi/script/talk.sh
実行権限を付与します。
$ chmod 755 talk.sh
引数で渡した言葉をしゃべってくれるという簡単なシェルスクリプトです。ちゃんと動いてます。
$ ./talk.sh hello

今度は、時間をお知らせしてくれるシェルスクリプトを書いてみます。

jihou.sh
#!/bin/sh

time=`date "+%-H時、%-M分、%-S秒になりました"`

/home/pi/local/bin/talk.sh ${time}

上記をコピペするなり、curl コマンドで取るなりします。
$ curl -O http://sstea.blog.jp/raspi/script/jihou.sh
実行権限を付与します。
$ chmod 755 jihou.sh
今の時間を知らせてくれます。
$ ./jihou.sh

これで、毎時間の5分前にお知らせ、というような事も cron に登録すれば出来るようになりました。
$ crontab -e
とし、末尾に下記を追加して終了します。
  55 * * * * /home/pi/local/bin/jihou.sh

◆Raspberry Pi で音楽を鳴らす
Music Player Daemon (MPD) をインストールします。
$ sudo apt-get install mpd mpc

以前に作成した /etc/init.d/init-ramdisk に追記しておきます。
#!/bin/sh
### BEGIN INIT INFO
# Provides:       init-ramdisk
# Required-Start: $local_fs
# Required-Stop:  $local_fs
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
### END INIT INFO

chmod 775 /var/log
mkdir -p /var/log/ConsoleKit/
mkdir -p /var/log/fsck/
mkdir -p /var/log/apt/
mkdir -p /var/log/ntpstats/
mkdir -p /var/log/samba/
mkdir -p /var/log/mpd/
chown root.ntp /var/log/ntpstats/
chown root.adm /var/log/samba/
touch /var/log/lastlog
touch /var/log/wtmp
touch /var/log/btmp
touch /var/log/mpd/mpd.log
chown root.utmp /var/log/lastlog
chown root.utmp /var/log/wtmp
chown root.utmp /var/log/btmp

music ディレクトリに適当な音楽ファイルを放り込む。
(デフォルトだと /var/lib/mpd/music/)

曲登録。
$ mpc update
$ mpc ls | mpc add
再生。おぉー、音楽、鳴りました。
$ mpc play
次の曲。
$ mpc next
設定とかもいろいろあります。詳細は "mpc help" で。
$ mpc volume 80
$ mpc repeat on

ここで一つ問題が。
mpd で音楽再生中に AquesTalk Pi でおしゃべりさせようとしても、しゃべってくれません。。。

/etc/mpd.conf の下記をコメントアウトすると音楽再生中でもおしゃべりしてくれました。声、少し小さい気がしますが。
audio_output {
    type        "alsa"
    name        "My ALSA Device"
#    device        "hw:0,0"    # optional
    format        "44100:16:2"    # optional
    mixer_device    "default"    # optional
    mixer_control    "PCM"        # optional
    mixer_index    "0"        # optional
}
ついでに下記をコメントアウトすることで、ベロベロ出てたエラーもなくなりました。
#bind_to_address   "localhost"


    次回は、ジョイスティックを繋いで操作出来るようにしてみたいと思います。


◆おまけ1
MPD にはスマホからでもアクセスできます。
世の中では MPD クライアントソフトがたくさん作られていて、スマホ用のアプリも例外なくあります。

自分もいくつか試してみて、Droid MPD Client が自分には合ってそうだったので、Xperia Z3 に入れています。

◆おまけ2
USBスピーカーを接続したまま電源入れると、起動時にプツプツ言って、立ち上がらない時がありました。

何でか結構悩みましたが、電力足りてないのか
/boot/config.txt の末尾に下記を追加したら安定しました。
safe_mode_gpio=4
max_usb_current=1


Raspberry Pi のディスクイメージを一から作る

前回カーネルも差し替えたので、以前の記事を見ながらディスクイメージのバックアップを取ろうかと思ったのですが、以前に構築した Linux Mint の仮想環境で、VirtualBox が(なぜか)ホスト側に挿した microSD カードリーダをうまく認識してくれませんでした。
仕方がないので、ディスクイメージをコネコネして、パーティションのリサイズやら何やらを行なったディスクイメージを作成することにしました。
gparted でリサイズしようと思ったんですが、アレ?イメージファイルだと、何故かリサイズ出来ないですね。。。

ちなみに、前回カーネルを差し替えたものに加えて、
NTP設定不要デーモンの停止、RAMディスクの使用、SWAPの停止、を行なっています。
SD使用量の節約のため日本語化等は見送りました。
ディスク使用量は半分弱といったところです。
$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root        3671884 1623100   1849424  47% /
devtmpfs          219996       0    219996   0% /dev
tmpfs              44836     336     44500   1% /run
tmpfs               5120       0      5120   0% /run/lock
tmpfs              89660       0     89660   0% /run/shm
/dev/mmcblk0p1     57288   10200     47088  18% /boot
tmpfs              32768       0     32768   0% /tmp
tmpfs              32768     112     32656   1% /var/log

◆ディスクイメージのベースの作成
"Win32 Disk Imager" を使用して、microSD のディスクイメージを Read し、仮想環境からも見える共有フォルダに入れておきます。以下、仮想環境の Linux Mint での操作になります。
(以下、ディスクイメージを rpi.img というファイル名で取得したとして記載しています。)
$ fdisk -l /media/sf_shared/rpi.img
ディスク /media/sf_shared/rpi.img: 3951 MB, 3951034368 バイト
ヘッド 255, セクタ 63, シリンダ 480, 合計 7716864 セクタ
Units = セクタ数 of 1 * 512 = 512 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスク識別子: 0x0009bf4f

                デバイス ブート    始点      終点  ブロック   Id  システム
/media/sf_shared/rpi.img1          8192    122879    57344    c  W95 FAT32 (LBA)
/media/sf_shared/rpi.img2        122880   7716863  3796992   83  Linux

まずは、作成するディスクイメージのサイズを決めます。
今回は4GBのmicroSDをしようしているので、半分の2GBにしてみようと思います。

まず、空のファイルをイレモノとして作ります。
元のサイズの半分にした値
  (7716863 + 1) / 2 = 3858432
をcountに指定します。
$ export IMGFILE=/media/sf_shared/new.img

$ dd if=/dev/zero of=${IMGFILE} count=3858432 bs=512
これで、単にゼロ埋めされた2GBのファイルが出来上がりました。
# ちなみに、fdisk の表示される値と単位を合わせる意味で bs=512 としていますが、
# bs を(8倍の) 4096 とかにした方が、ファイルの作成時間は短くなります。
# その場合、count は(8分の1の)482304 とする必要があります。
# 詳細は↓おまけ1参照

パーティションテーブルを作成し、パーティションを2つ作成します。
fdisk コマンドで対話モードで設定しても全然問題ないんですが、表現が難しいので下記のようなコマンドにしておきます。(凄く見にくいですが、$'\n' が改行と思ってください。)
$ echo o$'\n'w | fdisk ${IMGFILE}
$ echo n$'\n'p$'\n'$'\n'8192$'\n'122879$'\n'w | fdisk ${IMGFILE}
$ echo n$'\n'p$'\n'$'\n'122880$'\n'3858431$'\n'w | fdisk ${IMGFILE}
$ echo t$'\n'1$'\n'c$'\n'w | fdisk ${IMGFILE}

これでガワだけは出来ました。
$ fdisk -l ${IMGFILE}

ディスク /media/sf_shared/new.img: 1975 MB, 1975517184 バイト
ヘッド 255, セクタ 63, シリンダ 240, 合計 3858432 セクタ
Units = セクタ数 of 1 * 512 = 512 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
ディスク識別子: 0x0177f305

                デバイス ブート    始点      終点  ブロック   Id  システム
/media/sf_shared/new.img1          8192    122879    57344    c  W95 FAT32 (LBA)
/media/sf_shared/new.img2        122880   3858431  1867776   83  Linux

# 最初はこのディスクイメージを "sudo kpartx -v -a ${IMGFILE}" して、
# "mkfs.ext4 /dev/mapper/loop0p2" とかして直接フォーマットしようとしたんですが、
# 何かうまく出来なくてmountも出来ないので、下記のような手順を踏む事にしました。

◆各パーティションイメージの作成
それぞれ
  (122879 + 1) - 8192 = 114688
  (3858431 + 1) - 122880 = 3735552
の値を指定し、各パーティションのイメージファイルを作成します。
$ dd if=/dev/zero of=boot.img count=114688 bs=512
$ dd if=/dev/zero of=rootfs.img count=3735552 bs=512
それぞれフォーマットします。
$ mkfs.vfat boot.img
$ mkfs.ext4 -F rootfs.img

元のイメージディスクをマウントします。
$ mkdir old1/ old2/ new1/ new2/
$ sudo kpartx -v -a /media/sf_shared/rpi.img
$ sudo mount /dev/mapper/loop0p1 old1/
$ sudo mount /dev/mapper/loop0p2 old2/
元のイメージディスクの中身をそれぞれ全コピーします。
$ sudo mount boot.img new1/
$ sudo mount rootfs.img new2/
$ sudo cp -a old1/* new1/
$ sudo cp -a old2/* new2/
その他変更等(.bash_history や /var/cache/* の削除等)、やりたければやって、気が済めばアンマウントします。
$ sudo umount new1/
$ sudo umount new2/
元のイメージディスクをアンマウントします。
$ sudo umount old1/
$ sudo umount old2/
$ sudo kpartx -d /media/sf_shared/rpi.img
$ rmdir old1/ old2/ new1/ new2/

◆ディスクイメージとして結合
ベースのディスクイメージの各パーティションを置き換えて出来上がりです。
$ dd if=boot.img of=${IMGFILE} seek=8192 bs=512
$ cat rootfs.img >> ${IMGFILE}
これを "Win32 Disk Imager" で microSD に書き込めば、いつでもこの環境に復帰できます。
ちなみに、このディスクイメージは圧縮したら 400MB 弱になりました。

◆おまけ1

dd コマンドでは "bs=512, count=2048" でも、"bs=1024, count =1024" でも、どちらでも 1MB (bs * count) の読み書きを行なう、という事には変わりありません。では動きとしてはどう違うのでしょうか?

dd コマンドでは、if で指定したファイルから bs 単位で read し、of で指定したファイルに bs 単位で write を行う、という操作を count 回数分繰り返します。
つまり bs 単位の read, write システムコールを count 回発行しているのです。

以下のように、strace で観察するとよく分かります。
$ strace dd if=/dev/zero of=dummy count=100 bs=512
execve("/bin/dd", ["dd", "if=/dev/zero", "of=dummy", "count=100", "bs=512"], [/* 48 vars */]) = 0
brk(0)                                  = 0x9cf4000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
            :
open("/dev/zero", O_RDONLY|O_LARGEFILE) = 3
dup2(3, 0)                              = 0
close(3)                                = 0
_llseek(0, 0, [0], SEEK_CUR)            = 0
open("dummy", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
dup2(3, 1)                              = 1
close(3)                                = 0
clock_gettime(CLOCK_MONOTONIC, {238, 286988438}) = 0
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 512) = 512
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 512) = 512
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 512) = 512
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 512) = 512
read(0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 512) = 512
write(1, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 512) = 512

            :

Raspbian(2015-02)のLinuxカーネルを差し替える

前記事で新バージョン(2015-02-16-raspbian-wheezy)の Raspbian をインストールしたので、Linuxカーネルも差し替えたいと思います。
以下、以前に書いた、この辺を見ながらクロスビルドしました。

微妙に手順変わってます。。。

◆カーネル/ローダブルモジュールのビルド

カーネルのクロスビルドには以前作った環境を使います。
以下、ホスト環境での操作になります。

git からLinuxカーネルのソースを取得します。
$ cd /home/mint/raspi/
$ git clone https://github.com/raspberrypi/linux.git
$ cd linux/
$ git checkout -b rpi-3.19.y remotes/origin/rpi-3.19.y
現時点の最新カーネルバージョンは 3.19.1 でした。(もうすぐ 4.0 になりますね。)

Raspberry Pi 実機上から取得したカーネルコンフィグをベースに、デバッグ関連、プロファイル関連のコンフィグを無効化したカーネルコンフィグ(これ)を使用します。(機能的にはデフォルトを維持してます。圧縮形式は lz4 に変更してますが。)

$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
$ cd /home/mint/raspi/linux/

上記のカスタマイズしたコンフィグを.config として linux ディレクトリ直下に置きます。
$ curl http://sstea.blog.jp/raspi/kbuild/kconfig-rpi-3.19.1 > .config
デフォルトのコンフィグを使用する場合は↓のようにしてもいいです。
$ make bcmrpi_defconfig

カーネルをビルドします。(コア数に応じて -j2 とかお好みで付けてあげてください)
$ make dtbs zImage modules
$ make modules_install INSTALL_MOD_PATH=../out/  INSTALL_MOD_STRIP=--strip-unneeded

前までは zImage を kernel.img にリネームするだけで問題ありませんでしたが、
dtb 使うようになってから、もう一工程、下記作業が必要になったようです。
(ここめっちゃ悩みました。詳細は↓おまけ1参照。
  mkknlimg は "git clone https://github.com/raspberrypi/tools.git" で取ってきた中にあります。)
$ cd /home/mint/raspi/
$ tools/mkimage/mkknlimg --dtok linux/arch/arm/boot/zImage out/kernel.img
dtb ファイル(bcm2708-rpi-b-plus.dtb)もコピーしておきます。
$ cp -p linux/arch/arm/boot/dts/bcm2708-rpi-b-plus.dtb out/

dtbファイルとkernel.img とローダブルモジュール郡を圧縮し、Raspberry Pi に持っていきます。
(まあ、このあたりは好きな方法で持っていってもらえればいいんですが。)
$ tar cvjf new.tar.bz2 out/

$ scp -p new.tar.bz2 pi@192.168.0.100:~
# IPアドレス部分は Raspberry Pi のIPアドレスを指定

◆クロスビルドしたLinuxカーネルへの差し替え
以下、Raspberry Pi 側での操作になります。

dtbファイルとカーネルイメージを差し替えます。
$ tar xvjf new.tar.bz2

$ sudo cp out/bcm2708-rpi-b-plus.dtb /boot/
$ sudo cp out/kernel.img /boot/
新しいカーネルバージョンのローダブルモジュールを展開します。
$ sudo cp -a out/lib/firmware/* /lib/firmware/
$ sudo cp -a out/lib/modules/3.19.1+/ /lib/modules/
リブートし、新しいカーネルの起動確認を行ないます。
$ reboot

もはや不要になったファイルは削除しておこうと思います。(必須ではないです)
$ sudo rm -rf /lib/modules/3.18.9+/ /lib/modules/3.18.9-v7+/
$ sudo rm -rf /boot.bak/

使用しない dtb ファイルや カーネルイメージファイルも削除していいですよね?
(自分が使用しているのは Raspberry Pi Model B+ モデルですので、下記ファイルは使用していません。)
$ sudo rm /boot/bcm2708-rpi-b.dtb /boot/bcm2709-rpi-2-b.dtb /boot/kernel7.img
$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root        3671884 1723412   1749112  50% /
devtmpfs          219996       0    219996   0% /dev
tmpfs              44836     452     44384   2% /run
tmpfs               5120       0      5120   0% /run/lock
tmpfs              89660       0     89660   0% /run/shm
/dev/mmcblk0p1     57288   10200     47088  18% /boot

◆おまけ1

以前のように、クロスビルドしたlinuxカーネルの zImage ファイルを kernel.img とリネームだけして、Raspberry Pi のカーネルを差し替えてみたんですが、どうも dtb ファイルを認識していないように思います。
ブートログにちらほらエラーも見えますし。
/boot/bcm2708-rpi-b-plus.dtb ファイルは確かに存在するのですが。
(ブートログは /var/log/messages で確認できます。)
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 3.19.1+ (mint@Mint) (gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) ) #1 PREEMPT Sat Mar 14 22:50:58 JST 2015
[    0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[    0.000000] Machine: BCM2708
[    0.000000] cma: Reserved 8 MiB at 0x1b800000
[    0.000000] Memory policy: Data cache writeback
            :

試しに、/boot/config.txt の末尾に
device_tree=bcm2708-rpi-b-plus.dtb
と追加し、リブートしてみたところ、
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 3.19.1+ (mint@Mint) (gcc version 4.8.3 20140106 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) ) #1 PREEMPT Sat Mar 14 22:50:58 JST 2015
[    0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[    0.000000] Machine model: Raspberry Pi Model B Plus
[    0.000000] cma: Reserved 8 MiB at 0x1b800000
[    0.000000] Memory policy: Data cache writeback
            :
dtb ファイル認識してますね。。。

どうして、デフォルトのカーネルイメージは config.txt に何も記載がなくても、ちゃんと正しい dtb ファイルを認識できてるんでしょうか?
カーネルバージョンの差か、コンフィグ変えたからか、とか考えていろいろ試してみたんですが、どうも関係なさそうです。
カーネルイメージに何か情報を付与してんじゃねーの?と思って、オリジナルのkernel.imgをバイナリエディタで開いてみると、、、
末尾に何か付いてますね。。。文字列が読めます。
圧縮イメージなのに読める文字列があるって事は、圧縮後に付与されたって事です。

zImageファイルはImageファイルを圧縮して自己展開プログラムを先頭にくっつけたファイルで、自分が知る限り末尾にこんな情報はくっつかないので、外部ツールなりでzImageにこの情報を付与する加工を加えているように思います。

カーネルイメージ生成手順、何か増えてんのか?と思って https://github.com/raspberrypi/tools の中をいろいろ見てると mkknlimg とかいうそれらしいのがありました。

で、コレ使って kernel.img 作ってみると、、、

$ mkknlimg --dtok zImage kernel.img
config.txt を弄らなくても、いけましたー。

◆おまけ2
CONFIG_KALLSYMS を無効化しようとして毎回、迷子になるのでメモ。

[1] CONFIG_LATENCYTOP と CONFIG_FTRACE を無効化

  Kernel hacking  --->
  [ ] Latency measuring infrastructure
  [ ] Tracers  ----

[2] CONFIG_KPROBES を無効化
  General setup  --->
  [ ] Kprobes

[3] KALLSYMS_ALL がようやく変更可能になるので無効化
  General setup  --->
  -*- Configure standard kernel features (expert users)  --->
  [ ]   Load all symbols for debugging/ksymoops

◆おまけ3
dtb (device tree blob)
ファイルは dts (device tree source)ファイルから生成されますが、dtb ファイルから dts ファイルに戻す事もできます。
Linux ツリーの中に dtc (device tree compiler)が入っています。

下記、コマンドで dtb ファイルから dts ファイルを取得できます。
$ cd /home/mint/raspi/
$ linux/scripts/dtc/dtc -I dtb -O dts ./bcm2708-rpi-b-plus.dtb > ./out.dts

Raspbian(2015-02)の環境を構築する

Raspbian が何やら新しいバージョンになっているようなので、環境を構築し直してみようと思います。

以下、以前に書いたここや、このあたりを参考にしつつ再構築しました。
(おおっ!? 備忘録として役立っているではないですか)

設定順序等を再構成し、いろいろ補完を行ないリメイクしました。
細かーい説明とかは端折ったりしてるかも。以前の記事も参照のこと。。。

◆新バージョン Raspbian の書き込み
http://www.raspberrypi.org/downloads/ から Raspbian のイメージファイル(2015-02-16-raspbian-wheezy.zip)をダウンロードし、Win32DiskImager (http://sourceforge.jp/projects/sfnet_win32diskimager/) により、microSD に書き込みます。
(とりあえず今回は4GBのmicroSDを使用しました。)

◆初期設定
書き込み後、最初の起動時に、コンフィグレーション画面が立ち上がりますので、

  microSDのパーティションの拡張。
1 Expand Filesystem

  タイムゾーンに日本(東京)を選択。
4 Internationalisation Options
->I2 Change Timezon
  ->Asia
    ->Tokyo

  キーボードレイアウトに日本語キーボードを選択。
4 Internationalisation Options
->I3 Change Keyboard Layout
  ->Generic 105-key (intl) PC
    ->Other
      ->Japanese
        ->Japanese - Japanese (OADG 109A)
    ->The default for the keyboard layout
      ->No compose key
        ->Yes

  オーバークロック(お好みで)
7 Overclock
->Medium

◆不要パッケージの削除

下記がインストール直後の状態です。1GB弱しか空きがありません。
$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
rootfs           3671884 2479420    993104  72% /
/dev/root        3671884 2479420    993104  72% /
devtmpfs          218604       0    218604   0% /dev
tmpfs              44576     232     44344   1% /run
tmpfs               5120       0      5120   0% /run/lock
tmpfs              89140       0     89140   0% /run/shm
/dev/mmcblk0p1     57288   14720     42568  26% /boot
基本的には以前、に削除したのと同じパッケージを削除しました。(お好みでどうぞ)
何個か追加で削除してますが。(回路シミュレータの smartsim とか。。。)
(インストールされているパッケージは "dpkg -l" で確認できます。)
$ sudo apt-get autoremove -y wolfram-engine scratch sonic-pi
$ sudo apt-get autoremove -y python-minecraftpi python-pygame
$ sudo apt-get autoremove -y idle idle3
$ sudo apt-get autoremove -y netsurf-common dillo
$ sudo apt-get autoremove -y smartsim
$ sudo apt-get autoremove -y pistore debian-reference-common
$ sudo apt-get autoremove -y libraspberrypi-doc

$ sudo apt-get autoremove -y man manpages man-db
$ sudo apt-get autoremove -y git git-man
$ sudo apt-get autoremove -y galculator
$ sudo apt-get autoremove -y weston
$ sudo apt-get autoremove -y gdb gdbserver
$ rm -rf /home/pi/python_games/
$ sudo rmdir /usr/local/games/ /usr/games/

それなりに空きが出来たと思います。

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
rootfs           3671884 1770044   1702480  52% /
/dev/root        3671884 1770044   1702480  52% /
devtmpfs          218604       0    218604   0% /dev
tmpfs              44576     232     44344   1% /run
tmpfs               5120       0      5120   0% /run/lock
tmpfs              89140       0     89140   0% /run/shm
/dev/mmcblk0p1     57288   14720     42568  26% /boot

◆ファームウェア・カーネル/パッケージのアップデート
2015-02-16-raspbian-wheezy のカーネルバージョンは 3.18.7 のようです。
$ uname -r
3.18.7+
/boot の下を見てみると、デバイスツリーのファイル等が以前より増えています。
(あんまりデバイスツリー好きじゃないんですが、、、世の中の流れですね。。。)

ファームウェアのアップデートを行い、完了後リブートします。
$ sudo rpi-update
$ sudo reboot
リブート後、ちゃんとカーネルバージョンが変わっています。
$ uname -r
3.18.9+

古いバージョンのモジュールは不要なので、削除しておきます。
$ sudo rm -rf /lib/modules/3.18.7+/ /lib/modules/3.18.7-v7+/

サンプルプログラムも削除します。(お好みで。ビルドして一度サンプルを実行してみてもいいと思います。)
$ sudo rm -rf /opt/vc/src/hello_pi/

その他のパッケージもアップデートします。

$ sudo apt-get update
$ sudo apt-get upgrade

まだ半分くらいの空きがあります。
$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
rootfs           3671884 1766000   1706524  51% /
/dev/root        3671884 1766000   1706524  51% /
devtmpfs          218644       0    218644   0% /dev
tmpfs              44584     244     44340   1% /run
tmpfs               5120       0      5120   0% /run/lock
tmpfs              89160       0     89160   0% /run/shm
/dev/mmcblk0p1     57288   14760     42528  26% /boot

◆sambaの初期設定
ネットワーク経由で Raspberry Pi とファイルのやりとりを行なうために、sambaの設定を行ないます。
(ホストマシンでクロスビルドしたカーネルイメージを持ってくるためです。)

$ sudo apt-get install samba chkconfig

    /etc/samba/smb.conf を編集。
[global]
dos charset = CP932
unix charset = UTF-8

ファイル末尾に以下を追加。
    : (略)
[pi]

path = /home/pi
writable = yes
guest ok = yes
browsable = yes
force user = pi
create mode = 0777
direcory mode = 0777

次回は 2015-02-16-raspbian-wheezy 用のLinuxカーネルを差し替えます。

Raspberry Pi のディスクイメージをバックアップする

ここまで環境設定をいろいろやってきました。

しかし、機能的には何も嬉しい事をしてません。
ここからは、いろいろインストールしたりとかしようと思っていますが、一旦ここでこの環境をセーブしておきたいと思います。

何か失敗してやり直したいと思うかも知れませんし、ファイルシステム破損してしまった時とかに、再度環境構築するのは面倒くさいですし、、、

本当のところは、現在使っているclass 4のmicro SDカードからclass 10のmicro SDカードに引越してみて、起動時間がどうなるか見てみたい、というのが一番だったりするのですが。。。

単純にディスクイメージを吸い出すだけでもいいのですが、それだとmicroSDのサイズのディスクイメージが出来てしまいます。
(32GBのmicroSDを使用していると使用/未使用を問わず32GBのディスクイメージファイルになります。)
圧縮すれば未使用部分は縮むのですが、それでも個人的にはディスクイメージファイル自体に縮んでいて欲しいのです。(容量の小さいmicroSDに引越し出来ないし)

ディスクイメージの引越しについて、ディスクイメージを弄くり倒して行なう別解を用意しました。
(ホストマシンに直接カードリーダが繋げない、gparted使えない、などの環境でも引越し可能なはずです。)

◆ rootfs パーティションを縮小
まず、Linux ホストマシンに Raspberry Pi で使用していたmicroSDを挿します。
以前に Linux Mint の仮想環境をVirtualBoxで作成したので、今回はそれを使おうと思います。

Linux ホストマシンで gparted を使用します。ないならインストールします。
$ sudo apt-get install gparted

gparted を使用し、Raspberry Pi の rootfs パーティション(2個目のパーティション)を適当なサイズに縮小します。

ss_vbox_gparted

◆ ディスクイメージの出力
Raspberryp Pi 用microSD が /dev/sdb として認識されているものとして以下、記載します。

$ sudo fdisk -l /dev/sdb
とすると、
デバイス ブート      始点        終点     ブロック  Id  システム
/dev/sdb1            2048      262143      130048    6  FAT16
/dev/sdb2          262144     5439487     2588672   83  Linux
というように表示されたとします。
ここで、二個目のパーティションの終点の数値が最終セクタ番号になります。

なので、サイズとしては +1 した値を指定します。
$ sudo dd if=/dev/sdb of=/media/sf_shared/raspi.img count=5439488 bs=512
これでディスクイメージファイルが /media/sf_shared/raspi.img として出力されます。

◆ディスクイメージをマウントする
$ sudo kpartx -v -a /media/sf_shared/raspi.img
とすると、下記のような表示が出ると思います。
この時に表示された loop デバイスを使用します。(この例では loop0 を使用します)
add map loop0p1 (252:0): 0 260096 linear /dev/loop0 2048
add map loop0p2 (252:1): 0 5177344 linear /dev/loop0 262144

下記のようにすることで、Raspberry Pi 用のディスクイメージの rootfs パーティションを /mnt/ にマウントできます。
$ sudo mount /dev/mapper/loop0p2 /mnt/
◆ディスクイメージの中身を編集
せっかくマウントしたので、中をいじってみたいと思います。

bashの履歴ファイルを削除しておきましょう。
$ rm /mnt/home/pi/.bash_history
$ touch /mnt/home/pi/.bash_history

キャッシュもたぶん消しても大丈夫と思います。
(debconf ディレクトリは残しておいた方がよさそうです。apt 時に何かワーニング出ました。。。)
$ sudo rm -rf /mnt/var/cache/*
$ sudo mkdir /mnt/var/cache/debconf/

ディスクイメージの圧縮時に圧縮率が高まるように、未使用領域をゼロ埋めしておきます。
(下記のように実行することで空き容量がなくなるまで、中身が0で埋まったdummyというファイルを作成しています)
$ sudo dd if=/dev/zero of=/mnt/dummy bs=4096
$ sudo rm /mnt/dummy

◆ディスクイメージをアンマウントする

$ sudo umount /mnt/
$ sudo kpartx -d /media/sf_shared/raspi.img

◆おまけ1

Win32DiskImager で普通にディスクイメージを吸い出してもいいと思います。
上記を参考に、応用すれば必要部分のみのディスクイメージにすることが出来ます。

gparted は、コマンドラインで起動する場合、パラメータにデバイス意外にもイメージファイルを指定することができます。(イメージファイルの場合は、リサイズは出来ませんが...)
$ sudo gparted イメージファイル

また、下記のようにすることで、イメージファイルを必要部分のみ切り出すことができます。
$ sudo dd if=イメージ1 of=イメージ2 count=必要セクタ数 bs=512

◆おまけ2

ちにみにclass 4のmicro SDカードからclass 10のmicro SDカードに変えてみましたが、起動時間は3秒ほど早くなっただけでした。(もう少し期待してたんですが。)


今回作成したディスクイメージは dd コマンド、または Win32DiskImager で microSD に書き込むことで、環境をいつでもリストア出来ます。

次回からは、心おきなく Raspberry Pi をいじくることが出来ますね。

Raspberry Pi のカーネルをクロスビルドする

前回までは設定をいじってましたが、今回はLinuxカーネルを差し替えます。

こちらの記事で最新のRaspbianのカーネルを差し替えてますので、そちらも参考までに。

◆VirtualBox上でクロスコンパイルする

特にカーネルを差し替える必要はないのかもしれませんが、自己満足コンフィグレーションの最適化のため、何となく自家製Myカーネルに差し替えたいと思います。愛着もわきますし。

Raspberry Piのターゲット上でカーネルをビルドをすることも可能ですが、カーネルビルドするにはRaspberry Piでは非力で、とても時間がかかってしまうため、VirtualBox上に構築したLinux Mintでクロスコンパイルしようと思います。

VirtualBox上にLinux Mintの構築方法はこちらを参照。

以下はVirtualBox上のLinux Mintでの操作です。

◆Raspberry Pi用クロスコンパイラを取得する
コンパイラもカーネルソースもgitで公開されています。

  GitHub (https://github.com/raspberrypi/)

gitがインストールされていない場合は、インストールしておきます。
$ sudo apt-get install git

まずはTerminalを起動し、適当な作業ディレクトリを作成します。
以降、作業ディレクトリを ${HOME}/raspi/ として記述します。
$ cd ${HOME}/raspi/
$ git clone https://github.com/raspberrypi/tools.git

取得してきた中を見ると tools/arm-bcm2708/ に以下の4つのツールチェーンがあります。
- arm-bcm2708-linux-gnueabi
- arm-bcm2708hardfp-linux-gnueabi
- gcc-linaro-arm-linux-gnueabihf-raspbian
- gcc-linaro-arm-linux-gnueabihf-raspbian-x64

どれを使うべきか、、、
自分は 32bit版 Linux Mint をインストールしているので 64bit版はそもそも実行できません。
これで残りの候補は3つ。(64bitマシンならこれ一択でいい気もします)
それぞれの gcc で --version を実行した結果が下記です。
$ arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-gcc --version
arm-bcm2708-linux-gnueabi-gcc (crosstool-NG 1.15.2) 4.7.1 20120402 (prerelease)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ arm-bcm2708hardfp-linux-gnueabi/bin/arm-bcm2708hardfp-linux-gnueabi-gcc --version
arm-bcm2708hardfp-linux-gnueabi-gcc (crosstool-NG 1.15.2) 4.7.1 20120402 (prerelease)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc (crosstool-NG linaro-1.13.1-4.8-2014.01 - Linaro GCC 2013.11) 4.8.3 20140106 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
gcc-linaro-arm-linux-gnueabihf-raspbian がGCCバージョン4.8.3 で一番新しいので、これを使うことにします。
(安易ですが、OSSは最新であれば最新ほどいい、が自分のモットーですので。)

.bashrc の最後に
PATH=${HOME}/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:${PATH}
とでも付け加えて、パスを通しておきます。

# 新しいTerminalを使うか ". ~/.bashrc" と実行しないと、まだ反映はされていませんので注意。

◆Raspberry Pi用Linuxカーネルのソースコードを取得
$ cd ${HOME}/raspi/
$ git clone https://github.com/raspberrypi/linux.git
それなりに時間かかると思います。

◆Raspberry Pi用のカーネルコンフィグを最適化する
カーネルコンフィグは Raspberry Pi 上で
$ sudo zcat /proc/config.gz > raspi.config
とすれば、今 Raspberry Pi で動いているLinuxカーネルのカーネルコンフィグが取得できます。

今回は自分がデフォルトのコンフィグをベースに変更を加えたこのコンフィグを使用します。
カーネルバージョンは 3.12.31 です。

# もっと最新のカーネルがいいという方はもっと↓を参照。

変更点は下記の通りです。
- デバッグ関連のコンフィグを無効化
(ダンプ 吐かれても別に原因解析する気ないなー、と思ったのでCOREDUMP、GDB、KPROBEとか全部切ってます。)
- プロファイル関連のコンフィグを無効化
- IPv6 の無効化(元々ローダブルモジュールだったのでそのままでもいいのですが)
- ROOT_NFS の無効化
- カーネル圧縮形式をlz4に変更
- ログバッファサイズとかその他、何点か微修正

カーネルイメージの省サイズ化、及びオーバーヘッド軽減を目的としたものなので、デフォルトのコンフィグから機能的には変わっていないはずです。(nfs root を使用する場合を除き)

上記コンフィグを.config として linux ディレクトリ直下に置きます。
$ curl http://sstea.blog.jp/raspi/kbuild/kconfig-rpi-3.12.31 > .config

◆Raspberry Pi用のカーネルをビルド(再構築)する
今回、カーネル圧縮形式をlz4にしているので下記をインストールしておきます。
$ sudo apt-get install liblz4-tool

ついでに、カーネルビルドに必要なパッケージが未インストールなら入れておきます。
$ sudo apt-get install build-essential libncurses5-dev

環境変数を設定します。
$ export ARCH=arm
$ export CROSS_COMPILE=arm-linux-gnueabihf-
カーネルコンフィグを変えたい場合は変えます。(変えないならmenuconfigは不要です。)
$ cd ${HOME}/raspi/linux/
$ make menuconfig
カーネルをビルドします。
$ make
カーネルモジュールのビルド&インストールを行います。(インストール先はテンポラリなのでどこでもいいです。../mod-3.12.31である必要はありません。)
$ make modules
$ make modules_install INSTALL_MOD_PATH=../mod-3.12.31/  INSTALL_MOD_STRIP=--strip-unneeded

ビルドが完了したなら、linux/arch/arm/boot/zImage がカーネルイメージになります。
これを kernel.img とリネームし、Raspberry Pi の /boot/kernel.img と置換することで新カーネルに差し替えることが出来ます。

ちなみに、元のカーネルイメージはgzip圧縮形式で 3.3MBほどでした。
今回のカーネルイメージはlz4圧縮形式で3.0MBほどで、シュリンク出来ています。
(同じgizp圧縮形式なら2.6MBまで縮みましたが、展開速度が高速なlz4を採用しています。)

あと、${HOME}/raspi/mod-3.12.31/ というのが出来ているはずなのでこの中の lib/modules/3.12.31+/ をRaspberry Pi の /lib/modules/ 以下に置いてあげるのも忘れずに。

ちなみに、../mod-3.12.31/lib/firmware/ にもいろいろファイルが出来ているのですが、
Raspberry Pi の /lib/firmware/ にあるファイルと一つも被っていないのが謎。
たぶんなくてもいい気もしますが、念のために ../mod-3.12.31/lib/firmware/ 以下のファイルも Raspberry Pi の /lib/firmware/ 以下にコピーしておくことにします。

◆Raspberry Pi用のチャキチャキの最近カーネルを使用する
と、ここで終わってもいいのですが、せっかくビルドまでして自家製カーネルを使うのだから、最新バージョンのカーネルを使用したいと思います。
現在の最新バージョンは 3.17.2 ですので、3.17.2 のカーネルにしましょう。

git でLinuxカーネルのソースを取得する所までは同じです。
(または、3.12.31 のツリーが不要なら make distclean してそれを流用しましょう。)
$ cd ${HOME}/raspi/linux/
$ git checkout -b rpi-3.17.y remotes/origin/rpi-3.17.y

3.17.2 のカーネルコンフィグにはこのコンフィグを使用します。
デフォルトコンフィグからの変更点は 3.12.31 の時と同様です。

ビルド方法等は 3.12.31 と同様です。

カーネルイメージを差し替えて、リブート後 Raspberry Pi 上で
$ uname -r
とし、3.17.2 と表示されていれば成功です。

◆カーネルイメージのファイル名を変更する
今回はカーネルを自家製カーネルに置き換えました。
ファームアップデート等を行なうと、本家のカーネルイメージに置き換えられてしまいます。

カーネルイメージのファイル名をデフォルト(kernel.img) から変更することで、これを回避することができます。

/boot/config.txt に下記を追記します。
$ kernel=kernel-3.17.img

カーネルイメージのファイル名をリネームします。
$ sudo mv /boot/kernel.img /boot/kernel-3.17.img

◆おまけ1
カーネルのオーバーヘッド軽減を目指してカーネルコンフィグをいじりましたが、効果は出ているのでしょうか?

printk で表示できる時間はカーネル起動からの時間のため、カーネル省サイズ下によるブートローダーの展開時間削減の効果は残念ながら正確な確認方法がありません。(体感できるレベルでなければ)

カーネル起動後であればカーネルログで確認できますので、今回の確認方法としてはカーネルログのrootfsのマウントまでの時間("EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)"とういうログの出力時間)を指標としたいと思います。
以前の記事でquietの効果確認を行なったのと同じ方法です。)

オリジナルconfig
raspberrypi kernel: [   13.000215] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
変更config
raspberrypi kernel: [   12.670055] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)

一応オリジナルより早くなってそうです。体感できないと思いますが。
小さなことからコツコツと!!

◆おまけ2

initramfsを使用してみます。

# 結局使用しない構成に戻しましたが。

現状のブートシーケンスはbootloader→kernel→rootfsの順に起動しますが、
bootloader→kernel→initramfs→rootfsの順に起動させる事ができます。

このinitramfsで先に起動させておきたいデーモン等やモジュールのロード等を済ませれば、rootfsの起動スクリプトの処理が遅かろうが関係ありません。
$ sudo apt-get install initramfs-tools
$ sudo update-initramfs -c -k $(uname -r)
で /boot/ 以下に initrd.img-3.17.2+ というファイルが出来ているはずです。

/boot/config.txt に以下を追記すれば、initramfsを使用したブートシーケンスになります。
initramfs initrd.img-3.17.2+
ただこのままだと、純粋にinitramfsを経由するようになった分だけ起動時間が少し遅くなっただけでメリットはありません。

initramfsの中身をいじくるためにこのファイルを VirtualBox の Linux Mint 上に持っていきます。
以下は ${WORKDIR} にファイルを持ってきたとして記載します。

ファイル名を変更し、ディレクトリを作成しておきます。
$ mv initrd.img-3.17.2+ initrd.img-3.17.2+.orig.gz
$ mkdir -p ${WORKDIR}/initramfs/
展開します。
$ cd ${WORKDIR}/initramfs/
$ gunzip -c -9 ../initrd.img-3.17.2+.orig.gz | cpio -i -d -H newc
お好きにいじくってください。

満足したら、再びinitramfsイメージにします。
$ cd ${WORKDIR}/initramfs/
$ find . | cpio -o -H newc | gzip > ../initrd.img-3.17.2.+
これを raspberry pi の /boot/ 以下においてあげてください。


次回はいったんこの環境をバックアップしようと思います。

Raspberry Pi の更なる最適化を試みる

前回、いろいろな最適化にトライしました。
今回は更なる最適化をはかりたいと思います。

◆電源投入~カーネルまで


そもそもLinuxカーネルのログ出力が開始されるまでで、8秒程かかっているように感じます。
つまりLinuxカーネル到達前のブートローダ部分でそれだけかかっている?

NOOBS は便利で高機能ですが、それゆえに起動時間の足を引っ張っている可能性はあります。

以前の記事では NOOBS を使って Raspbian をインストールしましたが、NOOBS を経由せず Raspbian を起動させてみて、起動時間が短縮されるか見てみたいと思います。

http://www.raspberrypi.org/downloads/ から今度は Raspbian のイメージファイル(2014-09-09-wheezy-raspbian.zip)をダウンロードします。

Win32DiskImager (http://sourceforge.jp/projects/sfnet_win32diskimager/) をダンロード&インストールし、ダウンロードしたイメージファイルを展開し microSD 書き込みます。、

※ microSD の内容は全て消去されます。ご注意を!!


で、電源投入すると、、、
前より明らかに早いです!!

4秒くらいは早くLinuxカーネルに到達出来ている気がします。
パーティションも2個とスッキリしました。(NOOBSを使用したインストール時はパーティションが6個くらい出来ていました。)

こちらの環境をベース環境としたいと思います。
前記事で行なった初期設定最適化等を再度行ないます。。。(面倒くさいですが)

◆カーネル起動~ログインプロンプト表示まで

気を取り直して、、、

起動時にカーネルログがベロベロ出ますが、見てますか?特に見ませんよね?
なので、あのカーネルログ出力を抑制しようと思います。
下記のように、カーネルコマンドラインに quiet を追加するだけです。

/boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait quiet
起動してみると、ログインプロンプト到達までが 1, 2秒短縮されたような気がします。

コンソールへの出力を抑制するだけで、内部的にはきちんとログ出力はされているので、
どうしても見たいという場合は
$ cat /var/log/syslog
とすれば、ブート時のカーネルログを確認することが出来ます。

実際に、/var/log/syslog 内のルートファイルシステムのマウント箇所のログが下記ですが、
quiet を付ける事で、ログ出力のタイミングが 1.3s 程早くなっている事が確認できます。
高速化は気のせいではなかったようです。よかった。よかった。

quiet なし
    : (略)
raspberrypi kernel: [   13.90288] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
quiet あり
    : (略)
raspberrypi kernel: [   12.670055] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)

◆オーバークロック
早く動かしたいならクロックを早くする。道理です。真理です。
やはり手っ取り早いのはオーバークロックでしょう。
$ sudo raspi-config
で、"7 Overclock" を選択します。
とはいいつつも、不安定になっては元も子もないので、とりあえず中間のやつにしときます。
Medium 900MHz ARM, 250MHz core, 450MHz SDRAM, 2 overvolt

◆fsckチェックの抑制

起動時のfsckチェックを省いてみます。

/etc/fstab
proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       0
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       0
tmpfs           /tmp            tmpfs   defaults,size=32m 0       0
tmpfs           /var/log        tmpfs   defaults,size=32m 0       0

リブートしてみましたが、、、
あんまり、早くなったような感じはないです。体感的には分かりません。

これは諸刃の剣でもあるので、ここは変更しなくてもいいかもしれません。
自分は、毎回でなくてもたまにfsckするくらいでいいかな、というのと、ファイルシステム破損に対しては"ディスクイメージ自体のバックアップ"で対処しようと思っていますので、このままで行ってみます。

◆起動時のスクリプトは...(よく分からないので)現状維持
起動時間のボトルネックの大半はユーザー空間の起動スクリプトのように(体感では)思いますが、あのあたりのスクリプトは何をしてるのか自分はよく分かってないので、今は触らずに置いておきます。今度は(もやは自己満足ですが)カーネルをいじくって最適化をはかりたいと思います。(自分はこっちが本業なので)

次回はカーネルを自前ビルドし、差し替えたいと思います。

Raspberry Pi の最適化を試みる

前回、初期設定まで行ないましたので、今回は最適化を行ないます。

◆不要パッケージを削除

何をするにもディスク容量が逼迫しているので、ディスク容量をまず空けようと思います。
ただし方針としては、最小構成を目指すつもりはありません。
GUI 使わない方が、そりゃ最小になりますが、GUI 使わないかは人によるでしょうし。
なので X window 関連をバッサリ削除、というような事は(今は)しません。という意味です。

デフォルトの機能を削る事なく、機能面を維持した上での最小の構成を目指します。
(GUIが立ち上がる、音がなる、ネットワークに繋がる等)
当たり障りがあまりないであろうパッケージのみを削除します。

まずは、プリインストールの以下を削除します。(後ろ髪引かれる思いですが、ここは心を鬼にして)
もちろん、使用予定があるものは置いておいていいと思います。
- Wolfram Alpah
- Scratch
- Python Games
- Pi Store
- Sonic-pi
- Minecraft
- IDLE, IDEL 3
- Webブラウザ(NetSurf, Epiphany, Dillo)のどれか2つ
→ Webブラウザ 3つもいらんので、1つ残して、それ以外は削除しようと思います。
    NetSurf を残そうと思いましたが、日本語入力できなかったので、Epiphany の方を残すことにします。
- Debian リファレンス

$ sudo apt-get autoremove -y wolfram-engine
$ sudo apt-get autoremove -y scratch
$ sudo apt-get autoremove -y python-pygame
$ sudo apt-get autoremove -y pistore
$ sudo apt-get autoremove -y sonic-pi
$ sudo apt-get autoremove -y python-minecraftpi
$ sudo apt-get autoremove -y idle idle3
$ sudo apt-get autoremove -y netsurf-common dillo
$ sudo apt-get autoremove -y debian-reference-common
$ sudo apt-get autoremove -y libraspberrypi-doc
これで 1GB くらい空きました。

Python Games 関連のはこれだけだと残ってるのもあるので、手動削除しておきます。
$ rm -rf /home/pi/python_games/
$ sudo rmdir /usr/local/games/
$ sudo rmdir /usr/games/

後、個人的に要らんかな、と思うのを削除します。
- man
→ 使い方が分からん場合は、-h か --help で大概ヘルプが表示される。
    それでも分からん場合は、ググるので、man は自分はあまり見ない。
- git
→ Raspberry Pi 上でのコンパイルは軽いのはするかもしれないが、ガッツリはしないと思う。
     その場合はクロスコンパイルするので。
- galculator
→ そもそもWindowsでもGUIの電卓は使わない。
    そもそも電卓(電子卓上計算機)の親玉であるPC(電子計算機)で、なんで電卓のエミュレートしてんのかと悲しくなる。
$ sudo apt-get autoremove -y man manpages
$ sudo apt-get autoremove -y git git-man
$ sudo apt-get autoremove -y galculator

◆アップデート

ある程度、4GBのmicroSDカードにも容量に余裕が出来たので、パッケージとファームウェアをアップデートしときます。
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo rpi-update

◆不要デーモンを無効化する
まずはデーモン管理用に chkconfig パッケージをインストールします。
(自分が慣れてるのがこのやり方なだけですが)
$ sudo apt-get install chkconfig

下記で無効化。
$ sudo chkconfig motd off
$ sudo chkconfig triggerhappy off
$ sudo chkconfig alsa-utils off
$ sudo chkconfig lightdm off
$ sudo chkconfig plymouth off

◆RAMディスクを使用する
一時ファイルとか、ログとかは、(自分は)別に蓄積しなくていいので電源落せばクリーンになるように、RAMディスクを使用するようにします。
(厳密にはRAMディスクではなく tmpfs です。)

# 最近知りましたが tmpfs は結構よく出来ているようです。
# tmpfs ではサイズ指定はしていますが、別にメモリ上にそのサイズが確保されるわけではなく、
# 上限サイズとなるだけのようです。(使用部分だけメモリを消費します)
# tmpfs として使用していない部分は、普通のメモリとして使えます。
# またメモリが足りなくなった場合には、tmpfs のファイルはスワップアウトする事ができます。

/etc/fstab に以下を追加(サイズはユースケースに応じて任意に変更してください)
tmpfs           /tmp            tmpfs   defaults,size=64m 0       0
tmpfs           /var/log        tmpfs   defaults,size=32m 0       0

# このままだと、マウントされてる現在の /tmp, /var/log 下のファイルがゴミとして残ってしまいそう。。。
# 一応 rm -rf /tmp/*, rm -rf /var/log/* しといた方がいいかも。)

この状態でリブートすると起動時に、「ディレクトリがない」とか、「ファイルがない」と怒られましたので、起動時に空ディレクトリや空ファイルを作成するようにしときます。

/etc/init.d/init-ramdisk を新たに作成しましょう。
#!/bin/sh
### BEGIN INIT INFO
# Provides:       init-ramdisk
# Required-Start: $local_fs
# Required-Stop:  $local_fs
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
### END INIT INFO

chmod 775 /var/log
mkdir -p /var/log/ConsoleKit/
mkdir -p /var/log/fsck/
mkdir -p /var/log/apt/
mkdir -p /var/log/ntpstats/
mkdir -p /var/log/samba/
chown root.ntp /var/log/ntpstats/
chown root.adm /var/log/samba/
touch /var/log/lastlog
touch /var/log/wtmp
touch /var/log/btmp
chown root.utmp /var/log/lastlog
chown root.utmp /var/log/wtmp
chown root.utmp /var/log/btmp

上記をコピペするなり、curl コマンドで取るなりします。
$ curl -O http://sstea.blog.jp/raspi/script/init-ramdisk
$ sudo mv init-ramdisk /etc/init.d/init-ramdisk
最後に、起動時に init-ramdisk が実行されるようにします。
$ sudo chmod 755 /etc/init.d/init-ramdisk
$ sudo chkconfig --add init-ramdisk

◆SWAPを無効にする
Raspberry Pi Model B+ はメモリ量 512MB あるんで、SWAPは要らないかな、って。
(一部をRAMディスクとして使用しますし、GPUともシェアするので、実質使えるのはもう少し少ないのですが)
$ sudo apt-get autoremove -y dphys-swapfile
# スワップファイルを使わなくても ZRAM を有効にすれば、ある程度メモリを増やしたのと同程度の効果があります。

次回はもう少し突っ込んだ最適化にトライしてみようと思います。

Raspberry Pi の初期設定をしてみる

前回、OSのインストールまで行いましたので、今回は初期設定を行います。

◆Tera Term によるリモートログイン

raspi-config にてSSHをdisableにしない限りはSSHデーモンが立ち上がっているはずですので、Tera Term にてSSH経由でリモート操作すれば、Raspberry Pi の実機に接続したマウスやキーボードで操作する必要はありません。

実機上で ifconfig が何かでIPアドレスを確認しておき、Tera Term に指定してあげてください。

一応、何回かリブートしても基本は同じIPアドレスになっていると思いますが、デフォルトは DHCP 設定になっているので、ずっと同じIPアドレスである保証はないです。
そこは固定IPにしてあげる必要があります。

◆Raspbian をインストールしてまず行うこと(独断と偏見に基づく)
が、とりあえず自分は emacs がないと何も出来ません。
設定ファイル一ついじるのにも、vi だと手間取ってしまいます。
なので、まず最初にする事は
$ sudo apt-get install emacs
です。(ここは人により不要と思います)

次にするのは、、、
.emacs.el の設定。。。(ここも人により不要と思います)

ファイルを編集する度に、スタートアップメッセージを表示されるのも、~ 付きのバックアップファイルを量産されるのも嫌なので、.emacs.el に
(setq inhibit-startup-message t)
(setq make-backup-files nil)
(setq auto-save-default nil)

としておきます。

ついでに行数の表示や括弧対応等の表示を有効にするため、
(show-paren-mode 1)
(column-number-mode 1)
(line-number-mode 1)

とします。

また、タブ幅を4(Linuxカーネルのソースコードは8だが)にして、インデントをタブで行うようにします。
(setq-default c-basic-offset 4
              tab-width 4
              indent-tabs-mode t)


全角スペースや、行末スペース、タブとスペースの混在検出のため、以下を追加。
(global-font-lock-mode t)

(defface my-face-b-1 '((t (:background "red"))) nil)
(defface my-face-b-2 '((t (:background "gray"))) nil)
(defface my-face-u-1 '((t (:background "SteelBlue" :underline t))) nil)
(defvar my-face-b-1 'my-face-b-1)
(defvar my-face-b-2 'my-face-b-2)
(defvar my-face-u-1 'my-face-u-1)

(defadvice font-lock-mode (before my-font-lock-mode ())
 (font-lock-add-keywords
  major-mode
  '((" " 0 my-face-b-1 append)
    (    "\t" 0 my-face-b-2 append)
    ("[ \t]+$" 0 my-face-u-1 append)
 )))
(ad-enable-advice 'font-lock-mode 'before 'my-font-lock-mode)
(ad-activate 'font-lock-mode)

emacs はそれなりに使ってきたんですが、正直、メジャーモードとかマイナーモードとか、Emacs Lispとかはイミフです。
昔、設定例をググって見つけたどこかのをコピペしてきて使い続けてます。

あと、.bashrc に
alias ll='ls -la'
 を追加するのも忘れずに。(ここも人に(以下略))

ようやく各種ファイルをまともに編集出来るようになりましたので、Raspberry Pi の設定をいろいろいじっていきたいと思います。

◆DHCP設定から固定IPに変更する

    /etc/network/interfaces
# iface eth0 inet dhcp

iface eth0 inet static
address 192.168.0.100
network 192.168.0.0
netmask 255.255.255.0
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameservers 192.168.0.1

元の設定をコメントアウトし、上記のように追記します。
IP アドレスが 192.168.0.100 である必要はないです。好きに書き換えてください。

◆ホストマシンとファイルやり取り出来るようにする(sambaの設定)
samba をインストールします。
$ sudo apt-get install samba samba-common samba-common-bin

/etc/samba/smb.conf を編集。[global] 以下に追記。
[global]
dos charset = CP932
unix charset = UTF-8

ファイル末尾に以下を追加。
[pi]
path = /home/pi
writable = yes
guest ok = yes
browsable = yes
force user = pi
create mode = 0777
directory mode = 0777

ネットワーク内からなら誰からでも見れてしまうので、それがマズい場合はもう少しちゃんと設定しましょう。

◆NTPの設定
NTPサーバーを日本のサーバーに変更しておきます。

    /etc/ntp.conf

# pool: <http://www.pool.ntp.org/join.html>
#server 0.debian.pool.ntp.org iburst
#server 1.debian.pool.ntp.org iburst
#server 2.debian.pool.ntp.org iburst
#server 3.debian.pool.ntp.org iburst
pool ntp.nict.jp iburst

◆日本語化

それなりの容量消費しますので、英語でも全然違和感ないなら日本語化する必要はないです。
$ sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big xfonts-kaname

日本語入力

$ sudo apt-get install -y uim uim-anthy

次回はRaspberry Piの最適化にトライしてみます。

Raspberry Pi に Raspbian をインストールしてみる

前回からの続き。

こちらの記事で最新版Raspbianをインストールし、環境を再構築してみました。

◆NOOBS を使用し Raspbian をインストール
# 最終的には、NOOBS を使わずにインストールする方にしましたが。。。

まずはホストPC上の操作。
ダウンロードした NOOBS(NOOBS_v1_3_10.zip)を解凍。
解凍した全ファイルを micro SD にコピー。

次に、micro SD を Raspberry Pi に挿します。
HDMIケーブルでテレビと接続。
LANケーブル、マウス、キーボードもそれぞれ接続する。
んで、最後に電源のmicroUSBケーブルを接続。(接続と同時に電源ONになるので。)

# 自分の場合は、microUSBケーブルをPCのフロントパネルのUSBに接続して電源供給しています。
# PCの方は通電していれば良く、立ち上げておく必要は無いです。

これだけで、何やら画面にGUIが表示されました。ちょっと感動です!!
簡単!!(仕事で少し触ったPandaBoardとかはもっと面倒くさかったです。。。)

インストールするOS(正確にはディストリビューションと言うべきかも)を複数選択する事も出来るようですが、容量の関係で現状は無理なので、素直にRECOMMENDEDされている Raspbian のみをインストールする事とします。
# いずれ全OS、一通りインストールして、どんな感じか見てみますが。

左上の Install ボタンを押して、「SD 書き換えるけど、本当にええねんな?」という確認をかい潜れば、特に何をするでもなく、後は数十分も放っておけばOSのインストールは完了です。
簡単!!(仕事で少し触...(以下略))

OSのインストール完了後、リブートすると、Raspi-config のメニュー画面が出ると思います。
始めは何も変えずに終了でも特に問題ないと思います。
強いて言えば、タイムゾーンとキーボードは日本にローカライズしておいた方がいいかも。
後、自分はパスワードを少し短いものに変えました。毎回打つのが面倒くさかったので。。。
(デフォルトのloginユーザ名はpi、初期パスワードはraspberryです。)

◆Raspbian のデフォルトの状態がどういうものかを確認してみる
まずはデフォルトの状態が、どういう状態か確認してみます。

df コマンド叩いてみます。

インストール直後で既に、4GB のSDの残り容量が数百MBしかないです。
これはなかなか厳しいですね。。。

とりあえずは GUI を立ち上げてみます。
$ startx
とすると、HDMIで接続したテレビの画面にでっかいラズパイを壁紙としたGUIが立ち上がります。
アイコンもいくつかデフォルトで並んでいます。

◆Raspbian のプリインストールソフトを使用してみる
とりあえず、並んでいるアイコンを適当にクリックして使用してみました。

・ Wolfram Alpah
→ よく分かんないです。
・ Scratch
→ なるほど。プログラム学習用ですね。
     昔、小学校の時にやったLOGO(亀動かすやつ)みたいなのかな?
・ Python Games
→ 簡単なテーブルゲームやボードゲーム詰め合わせです。
・ Pi Store
→ ストアですね。いろいろ売ってます。
・ Sonic-pi
→ よく分かりません。音楽とプログラムの勉強が同時に出来る?
・ Minecraft
→ とりあえず適当にキーを押してたら、地面掘り進んで、果てしなく落ちていきました。
・ IDLE, IDEL 3
→ 何これ?エディタ...でもないな。
・ NetSurf, Epiphany, Dillo
→ Web ブラウザ。
    youtube で適当な動画を再生してみる。
    おぉ! HDMI経由でテレビから音出てますねー。
    でも、重たいです。
    3つもいらん。どれか1つでいいや。

うん。はい。満足しました。
これらのソフトのほとんどはもう触らない気がしました。

一旦、左下のメニューからログアウトして GUI は終了させます。


<Raspberry Pi の初期設定は次回
プライバシーポリシー
当サイトでは、Googleを含む第三者配信事業者や広告ネットワークが配信する広告を掲載しています。
当サイトでは、アクセス情報に基づいた適切な広告表示、及びトラフィックデータ収集のためにCookieを使用しています。
ユーザーはCookieの無効化により、これらの情報の提供を拒否する事ができます。
スポンサーリンク
記事検索
スポンサーリンク