Buildroot based Linux on the DCP

資料 1
Buildroot based Linux
on the DCP-SH7785 board
Contents
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
1.10
1.11
1.12
1.13
1.1
はじめに . . . . .
U-Boot 設定 . . .
転送速度比較 . .
U-Boot から起動
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
ログインについて . . . . . . . . . . . . . . .
telnet と mount . . . . . . . . . . . . . . . .
CPCI バス経由仮想イーサネットドライバ .
リアルタイム応答性能測定ドライバ . . . . .
ハイバネーションについて . . . . . . . . . .
時刻設定について . . . . . . . . . . . . . . .
CF ディスクのパーティション設定について
外部割り込みと RTC について . . . . . . .
添付プログラムリスト . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
2
4
4
5
5
6
8
12
13
13
14
15
はじめに
DCP-SH7785 上で動作する Buildroot ベース Linux1 パッケージについて説明します。
DCP-SH7785 上で動作する Linux パッケージは以下の特徴を持ちます。
メモリディスクベース Linux
Buildroot/Busybox/uClibc ベースとする最小構成のファイルシステムで起動します。フラッシュメモ
リに initrd イメージとして格納し、ルートファイルシステムをメモリディスク2 として起動します。
CF ディスクベース Linux
Buildroot/Busybox/uClibc ベースとする最小構成のファイルシステムに gcc/g++の開発環境やその
他有用なツール3 を付加し、CF ベースで起動します。CF ディスクに ext2/ext3 ファイルシステムと
して格納し、ルートファイルシステムを CF として起動します。
PCI バス経由仮想イーサネットドライバ
CPCI バス上に DCP-SH7785 を複数枚(最大4枚4 )使用し、ボード間で通信を行なうためのドラ
1 Linux-3.2.28
または RT プロジェクトの RT パッチを適用した Linux-3.2.28-rt42
2 書き込んだファイルはシステム停止前に個別に保存する必要があります
3 net-snmp,
4 PCI-PCI
procps
ブリッジの設定変更とドライバ変更により最大8枚
1/
19
イバです。CPCI バスを仮想のイーサネットとし、TCP/IP や UDP/IP でソケット通信をおこなうこ
とができます。
リアルタイム応答性能測定ドライバ
測定用ユーティリティを実行することにより定期的な割り込みやタスク切替えを発生させ、割り
込み受け付け遅れやプリエンプションの遅れを計測します。計測したデータをファイルに保存し
gnuplot 等ツールを使用して計測結果をグラフ表示することができます。
DCP-SH7785 上で Linux を動作させる場合、ボードのディップスイッチ設定を以下に示します。*で示
す設定であることを確認して下さい。ENDIAN の設定以外は必須ではありません。
ビット
ビット名
8
BATT FS
7
EEPWP
6
FM WP
5
ENDIAN
説明
SRAM と RTC のデータバックアップ
ON: バッテリ無効
*OFF: バッテリ有効
オンボード EEPROM への書き込み
*ON: 書き込み有効
OFF: 書き込み無効
フラッシュメモリへの書き込み
ON: 書き込み禁止
*OFF: 書き込み有効
SH7785 エンディアン
ON: ビッグエンディアン
*OFF: リトルエンディアン
図 1.1: ディップスイッチ設定
1.2 U-Boot 設定
DCP-SH7785 ボード上バッテリを有効とした場合、以下のコマンドを実行し時刻設定を行なって下さい。
以降のコマンド実行例では、’=> ’ は U-Boot のコマンド実行を、’# ’ は Linux スーパユーザでのコマ
ンドの実行を、’$ ’ は Linux 一般ユーザでのコマンドの実行を示します。
=> date reset ↓
=> date 072614392012 ↓
=> date ↓
時刻の確認
2012 年 7 月 26 日 14 時 39 分の場合
DCP-SH7785 ボード上には三種類のシリアル EEPROM があります。
PCI-PCI ブリッジ(PCI6466-CB66BIG)
マスターボードとスレーブボード間で仮想イーサネットドライバを使用した通信を行なう場合、シ
リアル EEPROM の設定変更が必要となります。
PCI-PCIe ブリッジ(PI7C9X111SLBFDE)
工場出荷時の設定で使用します。
Gigabit Ethernet(WG82574IT)
工場出荷時の設定で使用します。
2/
19
シリアル EEPROM 設定用に U-Boot に以下のコマンドが追加されています。下記シンタックス表示で
device に指定できるデバイス名は、eth0, eth1 のイーサネットポートを示す e1000#0, e1000#1 および各
ブリッジデバイスを 0.0.0 の形式で PCI デバイスとして指定して下さい。offset はワード単位(16 ビッ
ト)でのオフセット値を指定して下さい。
src
srd
sre
sri
srw
-
serial
serial
serial
serial
serial
rom
rom
rom
rom
rom
write checksum
dump
erase
write initial data
write
=> ? src ↓
src - serial rom write checksum
Usage:
src device
イーサネットポートについてチェックサムを設定
=> ? srd ↓
srd - serial rom dump
Usage:
srd device [offset [count]]
データをダンプ表示
=> ? sre ↓
sre - serial rom erase
Usage:
sre device [offset [data [count]]]
データを消去
=> ? sri ↓
sri - serial rom write initial data
Usage:
sri device [x.x.x.x.x.x]
イーサネットポートについて初期データを書き込み
MAC アドレス指定可
=> ? srw ↓
srw - serial rom write
Usage:
srw device offset data...
データを書き込み
PCI-PCI ブリッジについて工場出荷時の設定値を以下に示します。
=> srd 0.0.0 ↓
0000 1516 001e
0008 0000 0000
0010 0000 7e01
0018 0000 0015
10b5
0000
1192
0001
6540
0110
7785
fb00
0000
0808
0001
0000
0604
0000
fb00
0000
0001
2020
0000
0000
0680
0000
0000
0015
PCI-PCI ブリッジについて仮想イーサネットドライバを使用する場合、設定値を以下のように変更して
下さい。
=> srw 0.0.0 14 0000 0000 0000 0000 0000 fa7f ↓
=> srw 0.0.0 1a 0000 0000 0000 0000 0000 fabf ↓
3/
19
1.3
転送速度比較
DCP-SH7785 ボードを二枚使用して転送速度を計測した場合の速度を以下に示します。なお、転送速度
は参考値であり平均値ではありません。ソケット間通信速度および mount してのファイル転送速度計測
時に使用した転送サイズは 16MB(メガバイト)です。
CPCI バス経由書き込み速度
27.6 [MB/sec]
Linux 上プロセスから mmap による書き込みテスト
libc の memcpy 関数は浮動小数点を用いた高速データ転送を行なっている
CPCI バス経由書き込み速度
19.3 [MB/sec]
Linux ドライバ内での memcpy 関数を使用した書き込みテスト
TCP/IP ソケット間通信速度
仮想イーサネットドライバの場合
7.6 [MB/sec] mtu 1500 の場合
11.0 [MB/sec] mtu 9000 の場合
e1000e ドライバの場合
20.0 [MB/sec] mtu 1500 の場合
20.5 [MB/sec] mtu 9000 の場合
mount してファイル転送速度
仮想イーサネットドライバの場合
7.9 [MB/sec] mtu 1500 の場合
10.2 [MB/sec] mtu 9000 の場合
e1000e ドライバの場合
15.2 [MB/sec] mtu 1500 の場合
16.6 [MB/sec] mtu 9000 の場合
1.4 U-Boot から起動
DCP-SH7785 上のフラッシュメモリ先頭にはブートローダーとして U-Boot が格納されています。512K
バイトの U-Boot 領域に続いて initrd イメージが格納されており、次のブートコマンドにより、ルート
ファイルシステムをメモリディスクとして Linux が起動します。
=> bootm 80000 ↓
RT プロジェクトの RT パッチを適用した Linux で起動する場合は次のブートコマンドを実行して下さい。
=> bootm 880000 ↓
物理アドレス
0x00000000-0x0007ffff
0x00080000-0x0087ffff
0x00880000-0x01ffffff
0x02000000-0x0207ffff
サイズ
512K バイト
8M バイト
23.5M バイト
512K バイト
説明
デバイスファイル
U-Boot
initrd イメージ
initrd イメージ
SRAM
/dev/mtdblock0
/dev/mtdblock1
/dev/mtdblock2
/sys/devices/platform/rtc7301/nvram
図 1.2: フラッシュメモリマップ
U-Boot のデフォルトのブートコマンドは CF からのブートとなります。
4/
19
=> boot ↓
CF から boot/uImage.sh4 のファイルを読み込んでブート
ブート時にキー入力がない場合の自動起動として、フラッシュメモリに書き込んだ initrd イメージから
起動させる場合、あらかじめ以下のコマンドを実行する必要があります。
=> setenv bootcmd bootm 80000 ↓
=> saveenv ↓
RT プロジェクトの RT パッチを適用した Linux で CF から起動する場合、あらかじめ以下のコマンドを
実行する必要があります。
=> setenv bootfile boot/uImage.rt ↓
=> saveenv ↓
saveenv コマンドにより、現在の環境変数が SRAM 先頭にセーブされます。次回の U-Boot 起動から SRAM
にセーブした環境変数を読み込んでブートを実行します。SRAM にセーブした環境変数を無効とするた
めには SRAM の先頭にゼロを書き込んで下さい。
=> mw.l a2000000 0 ↓
1.5
ログインについて
マシン起動時のログイン例を以下に示します。
Welcome to Buildroot
buildroot login: root ↓
#
スーパユーザ root でログインする場合
Welcome to Buildroot
buildroot login: default ↓
$ su ↓
#
一般ユーザ default でログインする場合
スーパユーザに移行
1.6 telnet と mount
他の Linux マシンとの通信例を以下に示します。イーサネットケーブルを eth0 ポートに接続し通信を行
ないます。
# ifconfig eth0 192.168.2.123 up ↓
# inetd ↓
他のマシンから telnet, ftp を行なう場合実行
他のマシンから/tmp を mount します。
# mount 192.168.2.123:/tmp /mnt ↓
他のマシンから telnet でログインします。
% telnet 192.168.2.123 ↓
Trying 192.168.2.123...
Connected to 192.168.2.123.
Escape character is ’ˆ]’.
buildroot login: default ↓
$
5/
19
1.7 CPCI バス経由仮想イーサネットドライバ
複数枚の DCP-SH7785 ボードを使用して、ボード間通信に仮想イーサネットドライバが使用できます。
以下の説明では、システムスロットにあるボードをマスターボード、ペリフェラルスロットにあるボード
をスレーブボードと呼びます。通信機能は CPCI バスを介して共有メモリにデータの書き込みを行ない
割り込みを発行します。マスターボードとスレーブボード間の通信と同様にスレーブボード間でのデー
タ転送が行なえます5 (図 1.3 参照)。
MAC 0.0.0.0.0.10
ÿÿÿÿÿ
eth2
MAC 0.0.0.0.0.12
ÿÿÿÿÿ
MAC 0.0.0.0.0.11
ÿÿÿÿÿ
eth2
eth2
Board#0
Board#2
Board#1
192.168.10.123
192.168.10.122
192.168.10.121
図 1.3: ボード間通信
図 1.3 では、Board#0 がマスターボード、Board#1 と Board#2 がスレーブボードとなります。各ボードの
メインメモリの一部が共有メモリとして見えており、ソケット通信では CPCI バスを介して共有メモリ
にデータの書き込みを memcopy 関数を呼び出すことで行ないます。
データを送る側のボードは、共有メモリへの書き込みが終了すると割り込みを発行します。データを受
け取る側のボードは、共有メモリからデータをローカルメモリに転送すると割り込みを発行します。
ソケット通信を行なう場合、最初に以下のコマンドを実行する必要があります。
# ifconfig eth2 192.168.10.123 up ↓
Board#0 上で実行の場合
オンボード上にギガビット・イーサネット・インタフェース用 eth0 と eth1 が存在するため、ネットワー
ク・インタフェースは eth2 となります。
本ドライバは一つのインタフェース eth2 を介して他の複数ボードと通信を行なうため6 、いずれかの通
信が混雑し、送信を一時的に停止する必要が生じた場合、他の送信も止めることになります7 。
MTU の変更が可能で、デフォルトの MTU は 1500 です。最大 9000 までの設定が可能です。以下に MTU
の変更例を示します。
# ifconfig eth2 mtu 9000 ↓
5 スレーブボード間で通信を行なうためには、マスターボード上に本ドライバが動作している必要があります
6 イーサネットフレームの宛先
7 eth2
MAC アドレスから送信相手ボードを識別します
に対する通信の一時停止は全てのボードに対する通信の停止を意味します
6/
19
仮想イーサネットドライバが起動し各ボードとのソケット通信が可能になったことを通知する手段が用
意されており、プログラム例を添付プログラム 1.13 に示します。プログラムでは、本ドライバが作成す
るシステムファイル/sys/devices/pci0000:00/0000:00:00.0/pcivnet の生成検出を inotify
(ファイルシステム・イベントを監視する)機能を使って検出します。システムファイルから 1 バイト
のデータを読み出すことが可能で、LSB から 0 番のボード番号を表します。1がセットされるとソケッ
ト通信が可能であることを示します。値が変化するまで、読み込もうとするプロセスはブロックします。
ドライバが削除された場合、read システムコールは 0 の値を返すことでデータが読み込めないことを示
します。
添付プログラムの実行例を以下に示します。
# notify &
Changed on
Changed on
Changed on
Changed on
Changed on
↓
board
board
board
board
board
0
1
2
2
2
UP
UP
UP
DOWN
UP
Board#2 上で ifconfig eth2 192.168.10.122 down を実行
Board#2 上で ifconfig eth2 192.168.10.122 up を実行
各ボードで reboot や halt コマンドを実行する場合、ソケット通信が行なえなくなることを他のボードに
通知するために本ドライバを先に削除する必要があります。以下のようなシェルスクリプトはこれを可
能にします。
#!/bin/sh
modprobe -qr pci6466
exec /sbin/reboot
パケットフォワーディング例を 1.4 に示します。
MAC 0.0.0.0.0.12
MAC 0.0.0.0.0.10
ÿÿÿÿÿ
ÿÿÿÿÿ
eth2
eth2
192.168.10.122
192.168.10.123
Board#0
Board#2
eth0
eth0
192.168.6.122
192.168.5.123
HUB
HUB
192.168.6.102
192.168.5.100
System#2
system#0
図 1.4: パケットフォワーディング例
7/
19
図 1.4 において、system#0 と system#2 間でパケットの通信を行なう場合、各マシン上で以下のルーティ
ング設定が必要です。
system#0 上での設定
route add -net 192.168.6.0 gw 192.168.5.123 netmask 255.255.255.0
board#0 上での設定
route add -net 192.168.6.0 gw 192.168.10.122 netmask 255.255.255.0
sysctl -w net.ipv4.ip forward=1
board#2 上での設定
route add -net 192.168.5.0 gw 192.168.10.123 netmask 255.255.255.0
sysctl -w net.ipv4.ip forward=1
system#2 上での設定
route add -net 192.168.5.0 gw 192.168.6.122 netmask 255.255.255.0
1.8
リアルタイム応答性能測定ドライバ
割り込み応答性能およびタスク切替の遅れを測定するドライバです。CPU 内蔵 TMU のチャネル3と4
を使用します。更に、以下のようにデバイスファイルを使用します。
# ls -l /dev/rtrtc ↓
crw-rw-rw1 root
root
60,
0 Jul 30 14:17 /dev/rtrtc
リアルタイム応答性能を評価するために、ジッタ(値のばらつき)を測定します。図 1.5 は無負荷時の
ジッタ測定結果を示します。
ジッタ測定用プログラム実行例を以下に示します。
# rttest -timespace 30 -period 10 -silent -output /tmp/data -priority 60 ↓
各パラメタを説明します。
# rttest -q ↓
usage: [devname] [-period #msec] [-silent] [-debug] [-output file]
: [-timespace #sec] [-priority #] [-[23]]
minor 0 :
4( 0.1usec/Hz) (default) -- uses to set TMU4
1 :
16( 0.4usec/Hz)
2 :
64( 1.6usec/Hz)
3 : 256( 6.4usec/Hz)
4 : 1024(25.6usec/Hz)
period #msec -- uses to set TMU3
priority # -- set scheduling priority, from 1 to 99
-[23] -- specify output column 2 or 3, default is both
timespace
period
silent
output
priority
測定時間を秒で指定(例は 30 秒間)
割り込みのタイミングをミリ秒で指定(例は 10 ミリ秒)
測定結果を表示しない
測定結果を指定ファイルに出力(例では/tmp/data)
スレッドのプライオリティを指定(例では 60)
出力形式を以下に示します。時間(秒)、タスク切替の遅れ(マイクロ秒)、割り込み受付の遅れ(マイ
クロ秒)の順にデータを記録します。
8/
19
0.000000 16.879999 3.440000
0.010000 11.679999 1.920000
0.020000 10.559999 1.600000
他の Linux マシン上で gnuplot を起動し下記コマンドを実行します。測定しているマシンの/tmp/data ファ
イルを予めコピーして下さい。
gnuplot> plot "/tmp/data" using 1:2 ↓
60
"/tmp/data" using 1:2
55
50
45
40
35
30
25
20
15
10
5
0
5
10
15
20
25
30
図 1.5: ジッタ測定
図 1.6 は仮想イーサネットドライバ動作時のジッタ測定結果を示します。負荷として、/tmp/file(64MB
(67108864 バイト)サイズ)のファイルをコピーします。
# mount 192.168.10.123:/tmp /mnt ↓
# rttest -timespace 30 -period 10 -silent -output /tmp/data -priority 60 &
sleep 5; time cp /tmp/file /mnt/file; time cp /tmp/file /mnt/file ↓
図 1.7 は RT パッチを適用した場合の仮想イーサネットドライバ動作時のジッタ測定結果を示します8 。
RT パッチを適用したカーネル上で動作する仮想イーサネットドライバのパケット受信処理は受信用ス
レッドで行ないます。割り込み処理はリアルタイム・スケジューリング・ポリシーを持ち、受信割り込
み処理を優先順位を下げたプロセスに分割することで他の割り込み応答性能の向上を意図しています9 。
通常のカーネルの場合、仮想イーサネットドライバのパケット受信処理は受信割り込みハンドラの中で
行なっています。
8 RT パッチを適用すると、応答性能の向上が認められるものの、割り込み内で行なっていたメモリ間転送処理を受信用スレッドで
行なうためスループットの低下があります
9 RT パッチを適用すると割り込みハンドラはスレッドとして実行されます。全ての割り込みハンドラ用スレッドのプライオリティ
は同一であるため、割り込みハンドラの処理が重い場合、応答性能の低下の原因となります
9/
19
550
"/tmp/data" using 1:2
500
450
400
350
300
250
200
150
100
50
0
0
5
10
15
20
25
30
図 1.6: ジッタ測定 2
600
"/tmp/data" using 1:2
500
400
300
200
100
0
0
5
10
15
20
25
30
図 1.7: ジッタ測定 3
CF に含まれる procps ユーティリティを使用して、RT パッチを適用したカーネル上でのプロセス表示を
下記に示します。PRI フィールドが-51 のプロセスは割り込みハンドラがリアルタイムプロセスとして動
作していることを表します。PID 1024 のプロセスは仮想イーサネットドライバの割り込みハンドラを、
PID 1022 のプロセスは同ドライバの送信スレッドを、PID 1023 のプロセスは同ドライバの受信スレッ
ドを示します。
# ./p alx ↓
F
UID
PID
PPID PRI
NI
VSZ
RSS WCHAN
10/
19
STAT TTY
TIME COMMAND
4
1
5
1
1
1
1
5
1
5
5
1
1
1
1
1
5
5
1
5
1
1
1
1
1
5
1
1
1
5
5
5
1
5
5
1
5
5
5
5
5
1
1
1
1
1
1
4
5
5
1
5
5
5
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
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
2
3
4
5
6
7
8
9
31
32
148
150
152
157
164
169
170
281
282
293
298
299
300
301
878
899
904
909
918
922
925
934
938
948
959
961
964
967
990
995
1000
1001
1002
1003
1004
1006
1008
1020
1021
1022
1023
1024
1026
1030
0
0
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
1
1
1
1
1
1
2
2
2
2
2
1
1
964
964
2
2
2
2
2
20
0
20
0
-2
20
0
20
0
-100 0 -20
20
0
20
0
-51
-51
20
0
20
0
0 -20
0 -20
20
0
-51
-51
0 -20
20
0
20
0
20
0
20
0
0 -20
0 -20
-51
20
0
20
0
20
0
-51
-51
-51
0 -20
-51
-51
20
0
20
0
20
0
20
0
20
0
20
0
20
0
0 -20
0 -20
20
0
20
0
20
0
20
0
20
0
20
0
20
0
-49
-51
-51
20
0
1344
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
0
1328
1328
1724
812
844
844
0
0
0
0
0
948
1776
1724
1724
0
0
0
0
0
380
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
0
288
284
624
304
360
360
0
0
0
0
0
416
1092
520
548
0
0
0
0
0
11/
19
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
schedu
Ss
S
S
S
S
S
S<
S
S
S
S
S
S
S<
S<
S
S
S
S<
S
S
S
S
S<
S<
S
S
S
S
S
S
S
S<
S
S
Ss
Ss
Ss
Ss
Ss
Ss
S
S<
S<
S
S
Ss
Ss
S
S
S
S
S
S
S
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
ttySC0
?
?
?
?
?
?
?
0:02
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
init
[kthreadd]
[ksoftirqd]
[kworker/0]
[kworker/u]
[posixcput]
[khelper]
[kdevtmpfs]
[kworker/u]
[irq/64-PC]
[irq/69-PC]
[sync supe]
[bdi-defau]
[kblockd]
[ata sff]
[khubd]
[irq/33-DM]
[irq/33-DM]
[rpciod]
[kworker/0]
[khungtask]
[kswapd0]
[fsnotify ]
[nfsiod]
[crypto]
[irq/14-id]
[mtdblock0]
[mtdblock1]
[mtdblock2]
[irq/8-ehc]
[irq/4-ohc]
[irq/6-ohc]
[kpsmoused]
[irq/15-rt]
[irq/40-sh]
/sbin/syslo
/sbin/klogd
/lib/udev/u
portmap
rpc.statd
rpc.statd
[lockd]
[nfsd4]
[nfsd4 cal]
[nfsd]
[nfsd]
rpc.mountd
-sh
/lib/udev/u
/lib/udev/u
[eth2]
[eth2]
[irq/8-pci]
[irq/10-et]
[flush-3:0]
4
1
1.9
0
0
1031
1032
1008
2
20
20
0
0
1316
0
424 R+
0 schedu S
ttySC0
?
0:00 ./ps alx
0:00 [kworker/0]
ハイバネーションについて
ハイバネーション機能によりメモリ上のデータをディスクに保存し、次の起動時にディスクに保存した
データから起動することが可能です。コンフィグファイル内ではデフォルトのディスクパーティション
を/dev/hda2 としています。
CONFIG PM STD PARTITION="/dev/hda2"
ハイバネーションを実行する場合のコマンド実行例を以下に示します。コマンド例では、CF ディスク上
に複数のパーティションがあり、二番目のパーティションに 256 メガバイトのスワップ用スペースがあ
るとします。
# swapon /dev/hda2 ↓
# echo platform > /sys/power/disk; echo disk > /sys/power/state ↓
ハイバネーションする場合、下記のオプション設定があります。/sys/power/pm async の初期設定は1で、
サスペンド処理中にデバイス電源断処理を非同期に行ないますが、その処理をカーネルスレッドを複数
生成し行ないます。そのため次に起動した場合、その生成した複数のカーネルスレッドが残った状態に
ありこれを禁止する場合は/sys/power/pm async に0を設定して下さい。
# cat /sys/power/pm async ↓
1
# echo 0 > /sys/power/pm async ↓
再起動により、スワップ用パーティションに保存したデータは消去されますが、保存データからの再起
動を繰り返し行なうために保存データを消去しない場合、/sys/power/keep image に1を設定して下さい。
ただし、この場合スワップ用パーティションは再起動直後 swapoff コマンドで未使用として下さい。
# cat /sys/power/keep image ↓
0
# echo 1 > /sys/power/keep image ↓
上記オプション設定を行なってからハイバネーションを実行して下さい。
保存データを消去しない設定とした場合、新たにデータを保存する場合や保存データを消去する場合、
mkswap コマンドでスワップ用パーティションを初期化して下さい。
# swapoff /dev/hda2 ↓
# mkswap /dev/hda2 ↓
# swapon /dev/hda2 ↓
保存データを消去しない設定とした場合、一時的に通常起動する(保存データから起動しない)場合、
自動起動を中断し、u-boot にコマンドを入力することで起動して下さい。下記コマンド実行例はメモリ
ディスクベースで起動の場合です。
=> setenv bootargs console=ttySC0,115200 noresume ↓
=> bootm 80000 ↓
ハイバネーション機能により再起動した場合、時刻がデータ保存時の時刻に戻るため、起動直後にシス
テムの時刻を設定する必要があります。
12/
19
1.10 時刻設定について
システムの時刻からボード上 RTC の時刻を設定します。RTC の時刻を変更する場合実行して下さい。
# hwclock -r ↓
# hwclock -w ↓
RTC の時刻を表示
システムの時刻から RTC の時刻を設定
ハイバネーション機能により再起動した場合、ボード上 RTC の時刻からシステムの時刻を設定します。
# hwclock -s ↓
RTC の時刻からシステムの時刻を設定
1.11 CF ディスクのパーティション設定について
CF ディスクのパーティション設定は、メモリディスクベースで起動し、fdisk コマンドを実行します。
# fdisk /dev/hda ↓
Command (m for help): m ↓
コマンド一覧を表示
Command Action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
l list known partition types
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition’s system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)
Command (m for help):
下記に示すコマンドを入力し、インタラクティブに設定を行ないます。パーティションのサイズ指定で
は、256 メガバイトを +256M と指定します。
p
d
n
w
q
-
現在のパーティションを表示
番号を指定して既存のパーティションを一つ削除
番号とサイズを指定してパーティションを一つ作成
パーティションテーブルを CF に書き出し、設定を終了
変更を中断して終了
生成したパーティションを Linux で使用するためにフォーマットして下さい。
# mkfs.ext2 /dev/hda1 ↓ パーティション1を EXT2 形式でフォーマット
# mkfs.ext3 /dev/hda1 ↓ パーティション1を EXT3 形式でフォーマット
# mkswap /dev/hda2 ↓ パーティション2をスワップ領域としてフォーマット
ファイルシステムチェックを行なう場合のコマンド例を以下に示します。
13/
19
# fsck.ext2 /dev/hda1 ↓
# fsck.ext2 -f /dev/hda1 ↓
ファイルシステムチェックを強制する
1.12 外部割り込みと RTC について
CPU の割り込みコントローラで、外部割り込み入力端子 IRQ0 から IRQ7 は独立した割り込み入力とし
て使用します。ボード上割り込み要因との関係を以下に示します。
IRQ 番号
IRL0
IRL1
IRL2
IRL3
IRL4
IRL5
IRL6
IRL6
IRL6
割り込み番号
2
4
6
8
10
12
14
15
16
検出方法
レベル
レベル
レベル
レベル
レベル
レベル
エッジ
エッジ
エッジ
割り込み要因
CPCI の INTA
CPCI の INTB
CPCI の INTC
CPCI の INTD
ETH0(LAN2)
ETH1(LAN1)
IDE(Compact Flash)
RTC
WDT(未使用)
図 1.8: 割り込み要因(システムボード動作時)
IRQ 番号
IRL4
IRL5
IRL6
IRL6
IRL6
IRL7
割り込み番号
10
12
14
15
16
0
検出方法
レベル
レベル
エッジ
エッジ
エッジ
レベル
割り込み要因
ETH0(LAN2)
ETH1(LAN1)
IDE(Compact Flash)
RTC
WDT(未使用)
PCI-PCI ブリッジ
図 1.9: 割り込み要因(スレーブボード動作時)
PCI-PCI ブリッジ割り込みは仮想イーサネットドライバで使用します。システムボード動作時のスレー
ブボードからの割り込みは CPCI の INTA から INTD のいずれかを使用します。そのいずれになるかは、
スレーブボードの挿入位置によります。
RTC は次の割り込みを出力します。
• 更新割り込み
• アラーム割り込み
RTC の更新割り込みは、コントローラの周期割り込み機能を使用し、1Hz(一秒)サイクルで割り
込みを発生します。ただし、本割り込み機能はアプリケーションプログラムの中で/dev/rtc0 をオープン
し、そのファイルディスクリプタに対し ioctl システムコールを使用して本機能の使用開始および使用停
止を行なって下さい。
ioctl(fd, RTC UIE ON, 0);
ioctl(fd, RTC UIE OFF, 0);
周期割り込み使用開始
周期割り込み使用停止
14/
19
1.13 添付プログラムリスト
/*
* sample program in order to sense directory for PCI6466(pcivnet) driver
* using inotify and pthread
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/inotify.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#define PCIVNET_DIR "/sys/devices/pci0000:00/0000:00:00.0"
#define PCIVNET
"pcivnet"
#define USE_THREAD 1
static int vfd;
#if USE_THREAD
static pthread_t mythread, main_self;
#endif
static void print_mask(char *name, uint32_t mask);
#if USE_THREAD
static void *myTask(void* arg)
{
unsigned char prev_stat = 0;
unsigned char cur_stat;
int rv;
rv = write(vfd, &prev_stat, sizeof (prev_stat));
if (rv <= 0) {
close(vfd);
goto restart;
}
for (;;) {
int n;
lseek(vfd, SEEK_SET, 0);
rv = read(vfd, &cur_stat, sizeof (cur_stat));
if (rv <= 0) {
close(vfd);
goto restart;
}
if (rv > 0 && prev_stat != cur_stat) {
unsigned char stat = prev_stat ˆ cur_stat;
for (n = 0; n < 8; n++) {
if (stat & (1 << n)) {
15/
19
int up = (cur_stat & (1 << n)) != 0;
printf("Changed on board %d %s\n", n, up ? "UP" : "DOWN");
}
}
prev_stat = cur_stat;
}
}
restart:
vfd = -1;
return NULL;
}
static void fork_thread(pthread_t* thread, void* arg)
{
main_self = pthread_self();
if (pthread_create(thread, NULL, myTask, arg)) {
perror("pthread_create");
exit(1);
}
}
#endif /* USE_THREAD */
int main(int ac, char **av)
{
int ifd, wd;
int off, size, len, rv;
struct inotify_event *ep;
char pcivnet[64];
char event[512];
int verbose = 0;
char *dir = NULL;
char *file = NULL;
ac--, av++;
for (; ac > 0; ac--, av++) {
char *s = *av;
if (s[0] == ’-’) {
if (s[1] == ’v’) {
verbose = 1;
continue;
}
fprintf(stderr, "usage: [-v] dir file\n");
exit(0);
} else if (dir == NULL)
dir = *av;
else if (file == NULL)
file = *av;
else
break;
}
16/
19
if (dir == NULL)
dir = PCIVNET_DIR;
if (file == NULL)
file = PCIVNET;
snprintf(pcivnet, sizeof (pcivnet), "%s/%s", dir, file);
if (geteuid() != 0) {
fprintf(stderr, "Only the superuser may do it.\n");
exit(1);
}
vfd = -1;
ifd = -1;
wd = -1;
for (;;) {
int tfd;
tfd = open(pcivnet, O_RDWR);
if (tfd >= 0) {
if (vfd < 0) {
vfd = tfd;
#if USE_THREAD
fork_thread(&mythread, NULL);
#endif /* USE_THREAD */
} else
close(tfd);
} else {
if (vfd >= 0) {
close(vfd);
vfd = -1;
#if USE_THREAD
if (pthread_detach(mythread)) {
perror("pthread_detach");
exit(1);
}
#endif /* USE_THREAD */
}
}
if (ifd < 0) {
ifd = inotify_init();
if (ifd < 0) {
perror("inotify_init");
exit(1);
}
}
if (wd < 0) {
uint32_t mask = IN_ALL_EVENTS & ˜(IN_CLOSE_WRITE | IN_OPEN);
wd = inotify_add_watch(ifd, dir, mask);
if (wd < 0) {
perror("inotify_add_watch");
exit(1);
17/
19
}
}
off = 0;
size = 0;
again:
rv = read(ifd, &event[off], sizeof (event) - off);
if (rv < 0) {
if (errno == EINTR)
goto again;
perror("read");
exit(1);
}
if (rv > 0) {
for (size += rv; size > 0;) {
ep = (struct inotify_event *)&event[off];
if (size < sizeof (int) * 4 ||
size < sizeof (*ep) + ep->len) {
memmove(event, ep, size);
off = size;
goto again;
}
if (verbose)
print_mask(ep->name, ep->mask);
len = sizeof (*ep) + ep->len;
size -= len;
off += len;
}
}
}
if (ifd >= 0) {
rv = inotify_rm_watch(ifd, wd);
if (rv < 0) {
perror("inotify_rm_watch");
exit(1);
}
close(ifd);
}
}
static void print_mask(char *name, uint32_t mask)
{
printf("%s: ", name);
if (mask & IN_ACCESS)
printf("ACCESS ");
if (mask & IN_ATTRIB)
printf("ATTRIB ");
if (mask & IN_CLOSE_WRITE)
printf("CLOSE_WRITE ");
if (mask & IN_CLOSE_NOWRITE)
printf("CLOSE_NOWRITE ");
18/
19
if (mask & IN_CREATE)
printf("CREATE ");
if (mask & IN_DELETE)
printf("DELETE ");
if (mask & IN_DELETE_SELF)
printf("DELETE_SELF ");
if (mask & IN_MODIFY)
printf("MODIFY ");
if (mask & IN_MOVE_SELF)
printf("MODIFY_SELF ");
if (mask & IN_MOVED_FROM)
printf("MOVE_FROM ");
if (mask & IN_MOVED_TO)
printf("MOVE_TO ");
if (mask & IN_OPEN)
printf("OPEN ");
if (mask & IN_IGNORED)
printf("IGNORED ");
if (mask & IN_ISDIR)
printf("ISDIR ");
if (mask & IN_Q_OVERFLOW)
printf("Q_OVERFLOW ");
if (mask & IN_UNMOUNT)
printf("Q_UNMOUNT ");
printf("\n");
}
Sep-18-2012
19/
19