Raspberry Pi 2でDebian jessie armhf を動かす
Raspberry Pi 2のCPUはCortex A7でarmv7アーキテクチャです。RaspbianはRaspberry Pi 1との共通化のためにarmv6向けにビルドされています。Debianのarmhfはarmv7向けなので、これをRaspberry Pi 2で動かしてみました。
debootstrapを使ったDebianのルートファイルシステムの構築
NFSサーバとなっているLinuxマシン(今回はUbuntu 14.04 x86_64)の上で以下を実行しNFSのディレクトリにarmhf_jessieのルートファイルシステムの元のファイルを置きます。
$ sudo apt-get install debootstrap $ mkdir armhf_jessie $ sudo debootstrap --foreign --arch armhf jessie ./armhf_jessie/ http://http.debian.net/debian/ $ sudo cp -a ./armhf_jessie /export/
Raspberry Pi 2のSDカードの/boot/cmdline.txt のカーネルパラメータを以下のようにNFSrootで起動するようにし、init=/bin/sh を追加します。
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 root=/dev/nfs nfsroot=192.168.0.6:/export/armhf_jessie rw ip=dhcp elevator=deadline rootwait init=/bin/sh
これでRasberry Pi 2を起動すると # のshのプロンプトが出るので、そこで以下を実行します。
# /debootstrap/debootstrap --second-stage
これは20分くらいかかります。
各種設定ファイルの編集
NFSサーバの側から以下の4つのファイルを編集します。
- /export/armhf_jessie/etc/hostname
- /export/armhf_jessie/etc/hosts
- /export/armhf_jessie/etc/resolv.conf
- /export/armhf_jessie/etc/apt/source.list
Raspberry Pi 2のホスト名をarmhf-jessie00とすると
/export/armhf_jessie/etc/hostname
armhf-jessie00
/export/armhf_jessie/etc/hosts
127.0.0.1 localhost 127.0.1.1 armhf-jessie00ff02::1 ip6-allnodes ff02::2 ip6-allrouters
/export/armhf_jessie/etc/resolv.conf
nameserver 8.8.8.8
/export/armhf_jessie/etc/apt/sources.list
deb http://http.debian.net/debian jessie main #deb-src http://http.debian.net/debian jessie main deb http://http.debian.net/debian jessie-updates main #deb-src http://http.debian.net/debian jessie-updates main deb http://security.debian.org jessie/updates main #deb-src http://security.debian.org jessie/updates main
Raspberry Pi 2でユーザーの登録と初期設定
Raspberry Pi 2のシェルのプロンプトで以下を実行します。
最初に登録するユーザーアカウントをuser とすると
# export PATH=/bin:/usr/bin:/sbin:/usr/sbin # mount -t proc proc /proc # adduser user # adduser user sudo # apt-get update # apt-get install sudo locales dialog ssh # dpkg-reconfigure locales # dpkg-reconfigure tzdata
完成
これで最小限の設定はできたはずなので、initスクリプトを動かしてみます。
# exec /sbin/init
これで問題なくuserのアカウントでログインできて使用することができたら、SDカードのboot/cmdline.txt の中の init=/bin/sh を外します。
Raspberry Pi 2でのDebain jessie armhfのブートログ
debootstrap --second-stageの後の細かい設定が煩雑ですが、これの面倒を見てくれる便利なスクリプトはないのかな?
Raspberry Pi のインストール方法いろいろ
遅ればせながら、Raspberry Piを触ってみることにしました。
新しく購入した Raspberry Pi 2 model B とかなり昔のどこかの勉強会の懇親会でのじゃんけん大会に勝ってもらったものの、ずっと放置していた Raspberry Pi 1 model B(初期型。RAM 256MB) です。
本家のインストール手順の説明に従ってまずはNOOBSというツールでインストールしてみます。
ダウンロードはここから。
NOOBSとNOOBS Liteの2種類があったので、それぞれ試してみました。今回は全てRaspbianをインストールしています。
(以降、標準サイズのSDカードもマイクロSDカードも区別せずに「SDカード」と記述しています。)
NOOBS
NOOBS_v1_4_1.zipというサイズが約800MBのファイルをダウンロードします。それを展開して、その中身のファイルをSDカードのトップディレクトリにコピーします。コピーの前にSDカードをフォーマットし直せと書いてあったのですが、今回は新品をおろしたので、フォーマットせずにそのままできました。
後は、Rasberry Pi にそのSDカードを挿し、HDMIでテレビに、USBでキーボードとマウスをつないで、マイクロUSBで給電します。
テレビの画面のGUIを操作してRaspbianを選択してインストール開始。40分くらい待つとインストール完了。
インストールの時間はファイルの書き込み速度が支配的なので、速いSDカードを使うとその分早く終わります。今回はclass 4のものを使ったので遅めでした。
起動すると、テレビの画面にログインプロンプトが出るので、ID:pi, Password:raspberry でログインできます。
最初のログインでは自動的にraspi-configコマンドが実行されるので、ここでLocaleやTimezoneを設定します。
startxを実行するとX Windowのデスクトップが起動しますが、Raspberry Pi 2であってもあまり快適な速度ではないので、私はデスクトップを使うことはあまりなさそうです。
NOOBS Lite
もう一台あるので、Raspberry Pi 1のほうは、NOOBS Liteでインストールしてみました。
NOOBS_lite_v1_4.zipは22MBしかなくて、ずっと小さいです。Raspberry PiをEthernetにつなぐ以外は、NOOBSと全く同じようにインストールできます。ネットワークからダウンロードしながらファイルを書き込むことになるのですが、結局SDカードの書き込み速度が支配的なので、NOOBSのときと変わらない時間でインストールが完了しました。
固定回線のある環境では、NOOBS Liteはおすすめです。
NOOBS について
NOOBS とは New Out of Box Software のことだそうです。
ソースコードはGithubで公開されており、詳細な説明もここに書いてあります。
実際にこれはramdisk上で動作するLinuxシステムで、UIにはQtが使われいるようです。
インストール後も、NOOBSはリカバリ用のパーティションに格納されていて、起動時にシフトキーを押すとリカバリのためにNOOBSが起動するそうです。
NOOBSを使わずにRaspbianをインストール
確かにNOOBSを使うと初心者でも簡単にインストールすることができます。でも、コマンドラインでddコマンドを使うことをいとわなければ、もっと直接的にRaspbianをインストールすることができます。
Download Raspbian for Raspberry Pi
サイズが約1GBの2015-05-05-raspbian-wheezy.zipというファイルをダウンロードします。それを展開するとサイズが約3GBの2015-05-05-raspbian-wheezy.imgというファイルができるので、それをddコマンドでSDカードに書き込みます。
MacからddコマンドでSDカードに書く手順。
まずは、diskutil list コマンドでSDカードのデバイスファイルを確認します。
koba-mac:raspi koba$ diskutil list /dev/disk0 #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *500.3 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Apple_HFS Macintosh HD 499.4 GB disk0s2 3: Apple_Boot Recovery HD 650.0 MB disk0s3 /dev/disk1 #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *8.0 GB disk1 1: Windows_FAT_32 boot 58.7 MB disk1s1 2: Linux 7.9 GB disk1s2
/dev/disk0と/dev/disk1の2つが見えますが、容量からdisk1のほうがSDカードだとわかります。
SDカードをアンマウントします。
koba-mac:raspi koba$ diskutil unmountDisk /dev/disk1 Unmount of all volumes on disk1 was successful
次にddコマンドを使って書き込みを行います。Macの場合はデバイス名のrawを表すrがついた/dev/rdisk1に書き込みます。
コマンドを実行する前に、デバイスファイル名が間違っていないか指差し確認してください。
sudo でddコマンドを使うのは実は非常に危険で、ここでうっかり/dev/rdisk0に書いてしまうと、Macが起動不能になります。
koba-mac:raspi koba$ sudo dd bs=1m if=./2015-05-05-raspbian-wheezy.img of=/dev/rdisk1 Password: 3125+0 records in 3125+0 records out 3276800000 bytes transferred in 260.141958 secs (12596199 bytes/sec)
書き込みには4分半かかりました。class 10のSDカードを使っています。
このとき自動で再度マウントされているので、SDカードを抜く前にもう一度アンマウントしてください。
koba-mac:raspi koba$ diskutil unmountDisk /dev/disk1 Unmount of all volumes on disk1 was successful
できたSDカードをRaspberry Piに挿して起動します。
最初の段階ではルートファイスシステムの容量は以下のように認識されていて、SDカードの容量いっぱいまで使用でできていません。これはパーティションテーブルごと書き込みをおこなったためです。
pi@raspberrypi:~$ df -h Filesystem Size Used Avail Use% Mounted on rootfs 2.9G 2.4G 335M 88% / /dev/root 2.9G 2.4G 335M 88% / devtmpfs 87M 0 87M 0% /dev tmpfs 19M 224K 18M 2% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 37M 0 37M 0% /run/shm /dev/mmcblk0p1 56M 19M 37M 34% /boot
rasp-configコマンドで"Expand Filesystem"の項目を選択して実行します。
pi@raspberrypi:~$ sudo raspi-config
その後、再起動してルートファイスシステムの容量を確認すると以下のようになります。(8GBのカードを使用しました。)
pi@raspberrypi:~$ df -h Filesystem Size Used Avail Use% Mounted on rootfs 7.2G 2.4G 4.5G 35% / /dev/root 7.2G 2.4G 4.5G 35% / devtmpfs 87M 0 87M 0% /dev tmpfs 19M 224K 18M 2% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 37M 0 37M 0% /run/shm /dev/mmcblk0p1 56M 19M 37M 34% /boot
raspi-configコマンドはシェルスクリプトなので、何をやっているのかを確認できます。
"Expand Filesystem"ではfdiskコマンドでrootfsのパーテョンを一度削除してから、容量一杯のサイズでパーティションを再作成し、次に起動したときに一度だけresize2fsが実行されるようにinitスクリプトに登録を行っていました。
RaspbianはRaspberry Pi 1/2 どちらも共通
Raspbianをインストール済みのSDカードはRaspberry Piの1と2のどちらでも使えます。1と2ではCPUが異なるのでカーネルは別々になりますが、ブートパーティションの中には両方のカーネルが格納されていて、ブートローダーがCPU種別を判別して適切なカーネルを選んで起動してくれます。
ルートファイルシステムは共通で、armv6向けにFPUを有効にしてビルドされています。Raspbianのgccはデフォルトでそのようなコードを生成するようにconfigされています。
まとめ
Raspberry Pi 1/2 にRaspbianをインストールするいろいろな方法を試しました。
人にすすめるならば、NOOBS Liteかな。安全で簡単なので。自分ではさくっとddで書く方法を使います。
なお、SDカードのサイズは4GBでRaspbianをインストールできますが、それだと残り容量にあまり余裕が無いので8GBをおすすめします。
Raspberry Pi 1/2 のブートログとcpuinfo
Raspberry Pi 1と2 にRaspbianをインストールして起動したときのカーネルのブートログと/proc/cpuinfo をgistに貼りました。
Raspberry Pi 2のブートログ
Raspberry Pi 2の/proc/cpuinfo
Raspberry Pi 1のブートログ
Raspberry Pi 1の/proc/cpuinfo
Raspberry Piにシリアルコンソールをつなぐ
ハンダ付けは得意でないので、ありものを買ってきてつなぎました。
PL2303HX内蔵USBシリアル変換ケーブル
Raspberry Piのボードの接続は以下の写真の通り。
一番端から一個あけて、赤、黒、白、緑です。Raspberry Pi 1も2もこの位置は同じ。
赤は5Vの電源です。これをつなげばマイクロUSBからの給電しなくても起動します。Ethernetのみの接続ならこれでいけそうです。
USBホストに何かをつなぐときには、これでは電流不足になると思うので赤をはずしてマイクロUSBからACアダプタで給電したほうがよいと思います。
Mac用のPL2303のドライバは以下のサイトから入手しました。
http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=229&pcid=41
Macからコンソールに接続するには以下のコマンドを実行します。
$ sudo cu -l /dev/tty.usbserial -s 115200
Raspberry Piにはディスプレイ、キーボード、マウスはつながずに、Ethernetとシリアルコンソールで使うのが好みです。
VMWare Fusionでvmnet1のIPアドレスを変更する方法
VPNがどうもうまくいかないと思ったら、VMWare Fusionのvmnet1のIPアドレスとぶつかっていることが判明しました。
VMWare Fusionを終了させると、VPNが使えるようになるのですがこのままでは不便です。
以下のようにしたらvmnet1のIPアドレスを変更できて、VMWare Fusionを使用したままでもVPNが使えるようになりました。
OS X バージョン 10.9.5
VMWare Fusion バージョン 7.1.1
(1) VMWare fusionを止める
(2) 以下のファイルをroot権限で編集する
/Library/Preferences/VMware Fusion/networking
/Library/Preferences/VMware Fusion/vmnet1/dhcpd.conf
今回は全ての172\.16を172\.19に置換しました。
(3) VMare fusionを起動する
(4) netstat -rn でvmnet1のアドレスが変わっていることを確認する
vmnet8も同様の手順で変更可能だと思います。
さらに、VMWare Fusion上で動かす仮想マシンのネットワークをNATにしておくと、その仮想マシンからMacのVPN接続を経由してVPN先につなぐことができることも確認しました。
Go言語のARMのsoft floatのトリッキーな実装
kernel/VM Night! で発表してきました。
スライドは発表時から少し追記しています。
この日のライブ配信も担当しました。発表よりも実はそっちの方が大変でした。LiveWedgeというビデオスイッチャーを使ってカメラ3台体制で行いました。会社のブログのほうにライブ配信体験談を書く予定です。
そういえば、発表に出てきたARMv5のLinuxの実機ってどれのことですか?とは誰にも質問されなかったな。
"Non-temporal" あえてキャッシュに入れない
8/29に開催されたカーネル読書会でARM 64bitの話をしてきました。同じスライドで話すのは3回目なのですが質問が多くでて今回が最も盛り上がりました。
(撮影:@hyoshiok さん)
特にキャッシュの操作に関しての食いつきはすごかったです。
Aarch64ではキャッシュの操作がきめ細かくユーザーモードからでも行うことができるようになりました。さらに、再度アクセスする可能性が低いデータ(ストリーミングなど)のときにはあえてキャッシュに入れないという指定も可能です。(Non-temporal load/store)
Non-temporal load/storeはx86ではかなり前に導入されていることを前回発表したときに教えてもらいました。(movnt命令)
Linuxカーネルの中ではそれがどこに使用されているか、ソースコードを検索したらカーネルとユーザー空間の間のメモリのコピーを行うところで使用されていることがわかりました。(arch/x86/lib/copy_user_noncache_64.S など)
今回のカーネル読書会では、吉岡さんがコントリビュートしたパッチがまさにNon-temporal命令によるノンキャッシュのコピーの追加だったということを知りました。
そのパッチはこれです。
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c22ce14
2006年のものなので、ファイルの構成は現在のカーネルと変わっています。