資料 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
© Copyright 2024 Paperzz