ふとLibreOfficeをソースからフル・ビルドしてやろうと思い立ち、調べてみると案の定かなりの難物の模様。
まずソースをgitでおとしてこないといけませんが、これがかなり時間がかかり(家はフレッツ光の一般家庭用です、マンションなんかのシェアタイプとは違います)、1GB以上をDLするのに数時間かかりました。(速度が出ないところをみると、gitのサーバの能力の問題と思われます)
普通ならまず、./configureなんですが、最初に./autogen.shを実行しろとのこと。./configureの代わりみたいなんですが、FONTCONFIGのところでどうしてもエラーがでます。ビルドマシンはCentOS6.4ですが、調べてみるとパッケージはちゃんと入っています。(2.2以上を要求してきましたが、2.8が入っています)
ちょこちょこ調べてみると、同じエラーで悩んでいる方も多く、ビルド環境を整えるために以下を行えとありました。
# yum-builddep libreoffice # RedHat系
# apt-get build-dep libreoffice # Debian, Ubuntu系
ところがこれを実行しようとすると、どうもソースパッケージ(CentOSならソールRPM)を探しに行ってしまい、たまたま最新(4.x系)が見つからなくてエラーになります。
いやちょっと何よこれ、とコマンドの意味を調べたら、当該パッケージをビルドするのに必要なパッケージをとってくるものとのこと。ライブラリ関係はいいんですが、肝心のソースは本家のものでやらせてよ・・・・
ということで、あきらめて設定を手作業で修正してやらないとだめなようです。
PS:
英語のメーリングリストで有用な情報を見つけました。この./autogen.shではビルドに必要なヘッダファイル(*.h)があるかを見ているようで、パッケージとしてfontconfigが入っていてもだめで、fontconfig-develが入ってないとだめとのこと。早速インストールです。
# yum install fontconfig-devel
./autogen.shが無事先に進むようになりましたが、、、今後はPerlのところでひっかかりました。LibreOfficeを開発している人、どんなシステム環境で作業してるんだ\(-o-)/
2013年8月18日日曜日
2013年8月16日金曜日
Linuxプログラムのメモリ不足
人の作ったプログラム何ですが、やたらとmalloc(正確にはcallocの方)を使ったCプログラムがありました。それの動きがどうもおかしい(不安定)なんで、見てみると数百MBのデータファイルを最初に読み込ませていました。(データファイルの大きさは、利用する状況によって変わります)動いているマシンが、RHEL6 32bitとのことなんで、明らかにmallocに失敗していると思われます。
ところが、このプログラムmallocの結果を全然チェックしておらず、catchもしていません。またプログラムを使っている人たちもLinuxに関しては素人ということで、何が悪いのか理解させるのに一苦労。試しにちょっとサンプルプログラムを作って見ました。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MALLOC_SIZE 100000
int main()
{
int i,j;
int *pt;
for (i=0; i<10000; i++) {
pt = (int *)calloc( MALLOC_SIZE, sizeof(int));
if (pt == NULL) {
printf("## calloc error!! i= %d ##\n", i);
exit(0);
}
for (j=0; j<MALLOC_SIZE; j++) {
pt[j] = i;
}
ところが、このプログラムmallocの結果を全然チェックしておらず、catchもしていません。またプログラムを使っている人たちもLinuxに関しては素人ということで、何が悪いのか理解させるのに一苦労。試しにちょっとサンプルプログラムを作って見ました。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MALLOC_SIZE 100000
int main()
{
int i,j;
int *pt;
for (i=0; i<10000; i++) {
pt = (int *)calloc( MALLOC_SIZE, sizeof(int));
if (pt == NULL) {
printf("## calloc error!! i= %d ##\n", i);
exit(0);
}
for (j=0; j<MALLOC_SIZE; j++) {
pt[j] = i;
}
}
}
取得したメモリに値を書き込んでいるのは、こうして実際に何か使わないと、それまでは本当にメモリの取得につながらないからです。(最初、これで苦労しました)
さてこれで実行してみるとerrorが出たときの、iの値は8,017、あれ?毎回400KB近くのメモリを取得しているはずなのに、これだと3.2GBのメモリを取得したことになっちゃうぞ?確か、Linuxだと1プロセスの最大サイズは2GB弱で、そのうちStackが1GB、Heapが700MBくらいだったはず。おおすぎます。
そこでValgrindでチェックしてみると、i=6,910 2.764GBのheap要求がされたとのこと。(計算が合う)再度、ぐぐりましたが、どうも1プロセスでのサイズ制限はなくなり、4GBのどの空間をKernel用、Stack用、Heap用に用途わけするようになったみたいです。
マシンを占有できれば大きなプログラムを動かせますが、動作解析が更にやっかいになったようです。
2013年7月27日土曜日
ART-Linuxの実験 プロセス起動のリアルタイム性
さてサンプルで1secに1回プログラムが起きるようにしてみました。さて、他のプログラムが動いていたらどうなるでしょう?一般的には遅れが発生すると予想されます。
1.YouTubeを同時に動かす
CPU負荷が20%以下にしかなりませんが、サンプルプログラムの起動タイミングにはまるで影響がでませんでした。
これでは負荷が軽すぎるようです。
2.CPUを100%使用するfor-loopだけのプログラムを同時に動かす。
ところがこれでもサンプルプログラムの1sec毎の起動には影響がでません。(負荷をかけるプログラムの実行時間がサンプルプログラムと同時に動かすと若干realの実行時間が多くなりますので、負荷プログラムが同時に動くことによる影響はでているようです)
3.起動周期をかえる
ここまでAPは動かさず、ずっとBSPで実験してきました。BSPでも結構リアルタイム性は高いような気がしてきましたが、なんか変です。
ふと気づいたのが、サンプルプログラムが1sec毎のタスク起動だということです。実際にこれを使うプログラムなら1~10ms毎のタスク起動で使うでしょう。そこでサンプルを10ms毎のタスク起動にしてみました。(100回だったloopは10000回になります)普通にまたコンソールに出力したら、そこでボトルネックになりそうなので、ファイルへリダイレクトします。
(最終行)
[9999] 99.971077
ちょっとこれは予想外な値になりました。ほかのタスクは何も動いていません。(gnome-desktopは動いていましたが)artのtimerがどういう仕組みになっているのかわかりませんが、10ms毎と指定しているのに、ほんの少し早くトリガがかかってしまうようです。
4.APで実験する
同じサンプルをAP側で実行してみました。
(最終行)
[9999] 99.99090
さすがにさっきよりは正確ですね。それでもぎりぎりという感じです。
Core2やNVidiaのPCだとARTのタイマは遅れ気味になるという話を別のところで聞いたのですが、これだと逆に早くなってない?という感じです。ただまあ、あきらかにAPを使うシステムの方がリアルタイム性にはすぐれていそうな雰囲気ではあります。
ただART-linuxのデフォルトのタイマ分解能は1msだとのことなので、10ms周期のタスク制御がぎりぎりかなあという感じではあります。(元がLinuxベースなのでしょうがない?
PS
先ほど「タイマ分解能」と書きましたが、正確には実時間割り込み周期の最短時間のことです。特に設定せずに実験していましたが、ちょっと気になって設定して同じことをしてみました。
grubで起動するときに、ART=***というオプションを追加します。単位はusですので、デフォルトはART=1000だと思っていました。これをART=500で起動してみると明らかにタイマ割り込みが遅くなってしまいました。(BSP、AP両方とも)割り込み処理の負荷が耐え切れなくなったのか?と思い、ART=1000にしてみました。これでもとに戻るかと思ったら、ほぼデフォルトには近くなりましたが、タイマの精度がよくありません。
内部タイマで実験してもそろそろ限界のようなので、外部で計測してみないとだめのようです。(あるいはもっと長時間計測用プログラムを動かして、誤差の蓄積を多くする)
1.YouTubeを同時に動かす
CPU負荷が20%以下にしかなりませんが、サンプルプログラムの起動タイミングにはまるで影響がでませんでした。
これでは負荷が軽すぎるようです。
2.CPUを100%使用するfor-loopだけのプログラムを同時に動かす。
ところがこれでもサンプルプログラムの1sec毎の起動には影響がでません。(負荷をかけるプログラムの実行時間がサンプルプログラムと同時に動かすと若干realの実行時間が多くなりますので、負荷プログラムが同時に動くことによる影響はでているようです)
3.起動周期をかえる
ここまでAPは動かさず、ずっとBSPで実験してきました。BSPでも結構リアルタイム性は高いような気がしてきましたが、なんか変です。
ふと気づいたのが、サンプルプログラムが1sec毎のタスク起動だということです。実際にこれを使うプログラムなら1~10ms毎のタスク起動で使うでしょう。そこでサンプルを10ms毎のタスク起動にしてみました。(100回だったloopは10000回になります)普通にまたコンソールに出力したら、そこでボトルネックになりそうなので、ファイルへリダイレクトします。
(最終行)
[9999] 99.971077
ちょっとこれは予想外な値になりました。ほかのタスクは何も動いていません。(gnome-desktopは動いていましたが)artのtimerがどういう仕組みになっているのかわかりませんが、10ms毎と指定しているのに、ほんの少し早くトリガがかかってしまうようです。
4.APで実験する
同じサンプルをAP側で実行してみました。
(最終行)
[9999] 99.99090
さすがにさっきよりは正確ですね。それでもぎりぎりという感じです。
Core2やNVidiaのPCだとARTのタイマは遅れ気味になるという話を別のところで聞いたのですが、これだと逆に早くなってない?という感じです。ただまあ、あきらかにAPを使うシステムの方がリアルタイム性にはすぐれていそうな雰囲気ではあります。
ただART-linuxのデフォルトのタイマ分解能は1msだとのことなので、10ms周期のタスク制御がぎりぎりかなあという感じではあります。(元がLinuxベースなのでしょうがない?
PS
先ほど「タイマ分解能」と書きましたが、正確には実時間割り込み周期の最短時間のことです。特に設定せずに実験していましたが、ちょっと気になって設定して同じことをしてみました。
grubで起動するときに、ART=***というオプションを追加します。単位はusですので、デフォルトはART=1000だと思っていました。これをART=500で起動してみると明らかにタイマ割り込みが遅くなってしまいました。(BSP、AP両方とも)割り込み処理の負荷が耐え切れなくなったのか?と思い、ART=1000にしてみました。これでもとに戻るかと思ったら、ほぼデフォルトには近くなりましたが、タイマの精度がよくありません。
内部タイマで実験してもそろそろ限界のようなので、外部で計測してみないとだめのようです。(あるいはもっと長時間計測用プログラムを動かして、誤差の蓄積を多くする)
2013年7月23日火曜日
ART-Linuxの実験 再インストール
しばらく時間が開いてしまいましたが、5月末にART-Linuxをインストールしていた実験PCがおかしくなってしまったんです。その後、まとまった時間がとれないのと、当該実験PCがWindowsXPとのマルチブートでそっちもおかしくなってしまい、XPからの再インストールとなってしまい、大変でした。
さてART-Linuxの設定は前回記録を残したので、特に問題なく設定できましたが、前回でも問題になったのがAP(アプリケーションプロセッサ)の起動です。このAP、本体(BSP:ベースプロセッサと呼ぶようです)のファイルシステムの一部に自分のroot-fsを構築していて、そこをなぜかNFSで利用します。(この理由がわからんが、これに苦しめられています)
最初にインストールしたUbuntuがDesktop版のせいか、クライアントには簡単になれますが、サーバーになるためのパッケージやら設定が全然入っていません。どうしてもNFSサーバーとして起動してくれないんで、APの起動がうまくいかないんです。
おまけにAP用のEtherとして特別のルーター設定もしているせいか、結局全部手動でやらないといけない状態ですが、とりあえず手順をまとめます。
1.マシン起動(BSPが立ち上がります)
2.AP用のコンソールを起動します。
$ sudo screen /dev/ttyAP0
3.別のshellでAP用のネットを起動します。
$ sudo ifup ap0
4.あらためてNFSのファイルシステムの公開を宣言します。
$ sudo exportfs -a
5.まずNFSのために、portmapを起動します。
$ sudo /etc/init.d/portmap start
6.次にNFSサーバーを起動します。
$ sudo /etc/init.d/nfs-kernel-server restart
7.これで準備が整いました。apbootをします。
NFSサーバーを起動するのにまずportmapを起動しないといけないんですが、どうもUbuntuのdesktopはこのあたりの設定に問題があるらしく、起動してきれません。なので先に5.の手順をしておかないと、6.のところで応答がかえってこなくなります。
あとAPではプログラムのコンパイルができません。BSP側で実行形式を作成し、AP側のfsにコピーしてやればいいんですが、基本root権限でコピーしてやる必要があります。
なんちゅうか、まだまだ研究室の中で使用されるレベルです。(やっと実験環境が戻った・・・・)
さてART-Linuxの設定は前回記録を残したので、特に問題なく設定できましたが、前回でも問題になったのがAP(アプリケーションプロセッサ)の起動です。このAP、本体(BSP:ベースプロセッサと呼ぶようです)のファイルシステムの一部に自分のroot-fsを構築していて、そこをなぜかNFSで利用します。(この理由がわからんが、これに苦しめられています)
最初にインストールしたUbuntuがDesktop版のせいか、クライアントには簡単になれますが、サーバーになるためのパッケージやら設定が全然入っていません。どうしてもNFSサーバーとして起動してくれないんで、APの起動がうまくいかないんです。
おまけにAP用のEtherとして特別のルーター設定もしているせいか、結局全部手動でやらないといけない状態ですが、とりあえず手順をまとめます。
1.マシン起動(BSPが立ち上がります)
2.AP用のコンソールを起動します。
$ sudo screen /dev/ttyAP0
3.別のshellでAP用のネットを起動します。
$ sudo ifup ap0
4.あらためてNFSのファイルシステムの公開を宣言します。
$ sudo exportfs -a
5.まずNFSのために、portmapを起動します。
$ sudo /etc/init.d/portmap start
6.次にNFSサーバーを起動します。
$ sudo /etc/init.d/nfs-kernel-server restart
7.これで準備が整いました。apbootをします。
NFSサーバーを起動するのにまずportmapを起動しないといけないんですが、どうもUbuntuのdesktopはこのあたりの設定に問題があるらしく、起動してきれません。なので先に5.の手順をしておかないと、6.のところで応答がかえってこなくなります。
あとAPではプログラムのコンパイルができません。BSP側で実行形式を作成し、AP側のfsにコピーしてやればいいんですが、基本root権限でコピーしてやる必要があります。
なんちゅうか、まだまだ研究室の中で使用されるレベルです。(やっと実験環境が戻った・・・・)
2013年6月30日日曜日
Windows Vistaの憂鬱
親戚のPCが動かなくなって見てくれと電話が入りました。5年ちょっと前に購入したWindows Vistaのマシンです。親戚はPCのことはからっきしで、ネットの契約も私がしたくらいです。
そろそろ寿命が来てもおかしくないなと思って、買い替えを覚悟させて様子を見に行くと、電源いれてもDeskTopがいつまでたっても表示されない状態でした。(HDDは動きっぱなし)あきらかに普段のシャットダウン(でもVistaはSleep!)でおかしくなってますね。電源ボタン長押しで強制再起動、F2でBIOSをデフォルトにしてさらに再起動、一応セーフモードで様子を見ます。いちおうDesktopが表示されて操作できるようになりましたが、HDDの動きが止まりません。当然、HDDの最適化なんて知らないだろうから、HDDの様子を見ると使用量は半分くらいしか使ってません。これならそんなに問題ないと思うんだけど、ブラウザ開いてみたらなんかIEにGoogle Tool Barがついてます。普段の検索はこっちでやってるとのことで、みたらChromeも入ってるじゃん。インストールされているプログラムを調べてみると、案の定おそらくGoogle Tool Barをインストールしたときにデフォルトの推薦でGoogle DeskToopが入ってました。(HDDが動きっぱなしなのはこいつだ!)普段使いの人にはあまり意味がない(そのくせ処理負荷だけ高い)ので、すぐに削除。
ウイルスチェックの状態を調べてみると、最初にはいってたウイルスバスターが更新されずにそのまま・・・まあ普通はこんなもんだよな、ということでこれも削除し、Microsoft Essential入れてきました。(ベストじゃないけど、ベターな選択)ただちゃんとパターン更新してくれるかな~ 後は、VistaのシャットダウンはSleepだから(意味わかってないだろうな)、1週間に1回はメニューのここで完全にシャットダウンしてくれと頼んできました。
とりあえずこれで、Desktopが表示されてHDDが異常に動きっぱなしの状態も解消されました。まあもう2,3年は動いてくれ。(普通の人に、この状態でWindows8渡したら、どうなることやら。M$ももう少しPC使うユーザーのこと考えてくれ)
そろそろ寿命が来てもおかしくないなと思って、買い替えを覚悟させて様子を見に行くと、電源いれてもDeskTopがいつまでたっても表示されない状態でした。(HDDは動きっぱなし)あきらかに普段のシャットダウン(でもVistaはSleep!)でおかしくなってますね。電源ボタン長押しで強制再起動、F2でBIOSをデフォルトにしてさらに再起動、一応セーフモードで様子を見ます。いちおうDesktopが表示されて操作できるようになりましたが、HDDの動きが止まりません。当然、HDDの最適化なんて知らないだろうから、HDDの様子を見ると使用量は半分くらいしか使ってません。これならそんなに問題ないと思うんだけど、ブラウザ開いてみたらなんかIEにGoogle Tool Barがついてます。普段の検索はこっちでやってるとのことで、みたらChromeも入ってるじゃん。インストールされているプログラムを調べてみると、案の定おそらくGoogle Tool Barをインストールしたときにデフォルトの推薦でGoogle DeskToopが入ってました。(HDDが動きっぱなしなのはこいつだ!)普段使いの人にはあまり意味がない(そのくせ処理負荷だけ高い)ので、すぐに削除。
ウイルスチェックの状態を調べてみると、最初にはいってたウイルスバスターが更新されずにそのまま・・・まあ普通はこんなもんだよな、ということでこれも削除し、Microsoft Essential入れてきました。(ベストじゃないけど、ベターな選択)ただちゃんとパターン更新してくれるかな~ 後は、VistaのシャットダウンはSleepだから(意味わかってないだろうな)、1週間に1回はメニューのここで完全にシャットダウンしてくれと頼んできました。
とりあえずこれで、Desktopが表示されてHDDが異常に動きっぱなしの状態も解消されました。まあもう2,3年は動いてくれ。(普通の人に、この状態でWindows8渡したら、どうなることやら。M$ももう少しPC使うユーザーのこと考えてくれ)
2013年5月3日金曜日
ART-Linuxの実験 インストール(その2)
ここからが本番のリアルタイム制御専用システム(AP)のインストールです。急に難易度があがります。(産総研のHPにあった論文(?)をベースにやったことを意味を追加してメモしていきます)
4.必要なパッケージのDL
以下のパッケージをDLしてきます。
ap-linux-image-2.6.32-art-generic_20130227_i386.deb
ap-linux-headers-2.6.32-art-generic_20130227_i386.deb
apboot-1.0_20121213_i386.deb
ap-linux-*は、AP用のkernelです。あと、apbootはそれを起動するためのbootコマンドです。
まず、bootコマンドをインストールします。
sudo dpkg -i apboot-1.0_20121213_i386.deb
5.AP用システムの作成
次にAP用のFS(ファイルシステム)を作ります。これまで知らなかったんですが、Linuxでは試験用に別の形態のシステムを作成して動かす機能があり、それを使ってます。
mkdir -p ${APROOT}
sudo debootstrap ${SUIT} ${APROOT}
${APROOT}はAP用のファイルシステムのパス名で、動作させるコア数分だけ作成するようです。今回はCore2DuoなのでAPは1個しか作れませんから、1個だけです。
次の、debootstrapというコマンドが、当該パスの下に${SUIT}で指示されたUbuntuのファイルシステムを作成します。今回は’lucid’です。デフォルトではこのdebootstrapコマンドは入っていませんから、apt-getなりaptitudeでインストールしましょう。このコマンドはファイルシステムをネットからDLしてくるので、結構時間がかかります。
6.エクスポートの設定
システムを動かすうえで、BSPとAPのファイルシステムを相互に参照できると便利だろうということで、APのファイルシステムをBSP側で公開(export)する設定をします。
echo ${APIP} ${APNAME} >> /etc/hosts
echo ${APROOT} ${APNAME}\(rw,no_root_squash,subtree_check\) >> /etc/exports
exportfs -a
${APIP}はAP用のIPアドレス、${APNAME}はAPのホスト名です。適当に設定しましょう。(もちろんBSPから届くネットワークリーチャブルでなければ意味はないでしょうが)→APNAME=AP0とすること!11項のapbootでAPをAP0として起動しているため、これと合わせておく必要があります!
ちょっと思ったのが、いちいちechoコマンドで設定ファイルを修正していますが、直接viでやった方がいいと思います。一瞬、何をしているのか考え込んでしまいました。
7.ルータの設定
APから外部ネットワークに接続するためにはBSP経由行う必要があります。BSPにルータの設定をしてやらないといけません。/etc/network/interfacesに以下の設定をしてやります。
iface ap0 inet static
address ${BSPIP}
netmask 255.255.255.255
pointopoint ${APIP}
up iptables -t nat -A POSTROUTING -s ${APIP} -o ${ETH} -j MASQUERADE
down iptables -t nat -D POSTROUTING -s ${APIP} -o ${ETH} -j MASQUERADE
BSPにデバイスap0を定義し、これがAPと通信できるようルートを設定しています。${ETH}はBSP側のEthernetデバイスで、通常はeth0でしょう。あと、/etc/sysctl.confで以下の行のコメントを外してやります。
net.ipv4.ip_forward
8.APカーネルのインストール
ここまで長々とBSP周りの設定をしてきました。ここからやっとAPまわりの設定に入ります。4項でDLしておいたAPカーネルを、5項で準備しておいたAPカーネル用システムにインストールしてやります。
sudo dpkg -i --root=${APROOT} \
ap-linux-image-2.6.32-art-generic_20130227_i386.deb \
ap-linux-headers-2.6.32-art-generic_20130227_i386.deb
9.AP用システムの整備
まだまだ続きます。
(1)AP用システムへ移動(rootで入ることに注意)
# chroot ${APROOT}
(注:${APROOT}が/となり、このシステムのhostsファイル等の設定を行います)
(2)AP用システムのrootのpasswdを設定してやる。
(3)AP用システムの/etc/hostsにて、${hostname}-${APNAME}でホスト名を設定してやる。
(4)/etc/default/console-setup 中のACTIVE_CONSOLESをコメントアウトする。
(5)仮想シリアル端末からのログインを可能にする。
# cd /etc/init
# sed s/tty1/ttyBSP0/ tty1.conf > ttyBSP0.conf
# rm tty?.conf
# cd ..
# sed -i s/ttyS0/ttyBSP0/ securetty
(6)ureadaheadを停止する。
# cd /etc/init
# mv ureadahead.conf ureadahead.conf.bak
# mv ureadahead-other.conf ureadahead-other.conf.bak
(注:ureadaheadはlinux起動を早めるための先読みモジュールです。リアルタイム動作しようとしているので、こういうタイミングに影響が出そうなのは止めといた方が無難でしょう。起動してしまえば関係ないとは思うんですが、なくてもリアルタイム動作には影響しないし、悪さしかしないでしょうから。)
10.AP用のメモリの設定
さて、またBSP側の設定に戻ります。BSPのブート時にカーネルに起動オプションを設定して、AP用のメモリを確保してやらないといけません。
apmem:APに割り当てる低位メモリの領域(複数のAPがある場合はカンマで区切って)
aphighmem:APに割り当てる高位メモリの領域
ampshm:共有メモリに割り当てる低位メモリの領域(APが複数あろうと領域は一つだけです)
maxcpus:BSPカーネルが占有するコア数
どのくらいが適当なのかわからないので、とりあえず以下の設定で動かしてみました。
apmem=300M aphighmem=400M ampshm=100M
ここで「低位メモリ」って何?という意味がわからないと、どれくらいの領域を割り当てたらいいのか見当もつきません。「低位メモリ」とは、Linuxでは物理アドレスの0x00000000を仮想メモリの0xc0000000に割り当てることがほとんどです。つまり仮想アドレスの0xc0000000~0xffffffffの1GBは、物理メモリの最初の場所に配置されることになり、ここを「低位メモリ」と呼びます。
それでここが重要なんですが、Linuxでは複数のプロセスが独自の仮想メモリをもらい動作しますが、この「低位メモリ」は各プロセス共通に割り当てられます。つまり各プロセスがOSのサービスとデータをやりとりしようとしたり、OSのプロセスなんかはこの「低位メモリ」内で動くことになります。
つまり、BSPカーネルとAPカーネルは独自にこの「低位メモリ」領域がないと動けないため、それぞれに動作に必要なだけのメモリを割り当てておかないといけません。とはいっても、どれくらいあれば必要なだけあるかなんて、当該カーネルが動くときにロードするモジュールにもよるので一概に言えません。(特にリアルタイム制御したい、なんて目的なんで外部との専用通信モジュールが必要になることもあるでしょうし)なので適当にとしか言えないのが、つらいところです。
なおうまくメモリ領域が設定できたかは、BSP起動後に/proc/iomemを見てやれば確認できます。
11.APのブート
ここまできてやっとAPの起動ができます。以下のコマンドでインストールしたAP用カーネルが起動し、9(5)で設定した仮想シリアル端末からログインメッセージがでます。
# ifup ap0
# apboot ${APROOT}/boot/vmlinuz-2.6.32-art-generic rw \
ip=${APIP}:${BSPIP}:${BSPIP}:::bsp:p2p \
nfsroot=${BSPIP}:${APROOT},nolock
APが複数ある場合は、apbootのオプションで番号を指定できます。デフォルトは0から始まる番号です。
と、ここまでAPのブートまではできるようになりましたが(できたと思います・・・)、仮想シリアル端末が接続できない状態です。そのうち動くようになったら、また書きます。
追記:
11項でapbootする前に、以下のコマンドでシリアル端末を開いておきます。
sudo screen /dev/ttyAP0
そうするとapbootでAPが起動するときのログが表示されてきます。そこでわかりましたが、起動に失敗してました!ログを見てると、どうもNFSマウントのところで失敗しているようなんですが、なんかap0とap1が混在してる?そういやapbootでAP0として起動してるのに、NFSの設定やらhostsファイルやらAP1で定義してちゃあかんでしょ!
ということでそこを修正、だいぶ起動シーケンスが進むようになりましたが、今度はAP0からBSPへのネットワークが届かないとのこと。どこかルータの設定に問題があるようです。先は長いです。(しかしAPの起動って、数十秒単位で結構時間かかるのね・・・)
結果:
やっと動きました。ルータの設定で最初APIPとBSPIPを同じネットワークアドレスにしたのがまずかったのかと思ったんですが、それでも状況は変わりません。(でもこれはまずいと思います)
APの起動ログをよく見ると、どうもNFSのマウントでBSP側からの応答がないということらしいということで、BSPのNFSサーバ周りの設定を見直しました。デフォルトだとUbuntuのデスクトップ版ではサーバ関係のパッケージ何も入っていないので、後からnfs-kernel-server, nfs-commonを追加インストールしましたが、どこか問題があったようです。手動でnfsdを動かしてやろうと、
sudo /etc/init.d/nfs-kernel-server restart
とやると処理が固まってしまい、戻ってきません。いやこれは明らかにおかしいだろうとネットをググってみると、どうもportmapが動いていないとこうなるようです。psコマンドで見ると、確かに動いてません。設定のどこに問題があるのかわかりませんが、ブート時にportmapが起動してくれなくて、そのためnfsdも動いてなかったようです。そこでとりあえず手動でこのあたりを起動して、再度apbootしたら、あっさり動いてくれました。先に起動に時間がかかるといってたのは、NFSのマウントでtime-outを待っていたせいでした。
4.必要なパッケージのDL
以下のパッケージをDLしてきます。
ap-linux-image-2.6.32-art-generic_20130227_i386.deb
ap-linux-headers-2.6.32-art-generic_20130227_i386.deb
apboot-1.0_20121213_i386.deb
ap-linux-*は、AP用のkernelです。あと、apbootはそれを起動するためのbootコマンドです。
まず、bootコマンドをインストールします。
sudo dpkg -i apboot-1.0_20121213_i386.deb
5.AP用システムの作成
次にAP用のFS(ファイルシステム)を作ります。これまで知らなかったんですが、Linuxでは試験用に別の形態のシステムを作成して動かす機能があり、それを使ってます。
mkdir -p ${APROOT}
sudo debootstrap ${SUIT} ${APROOT}
${APROOT}はAP用のファイルシステムのパス名で、動作させるコア数分だけ作成するようです。今回はCore2DuoなのでAPは1個しか作れませんから、1個だけです。
次の、debootstrapというコマンドが、当該パスの下に${SUIT}で指示されたUbuntuのファイルシステムを作成します。今回は’lucid’です。デフォルトではこのdebootstrapコマンドは入っていませんから、apt-getなりaptitudeでインストールしましょう。このコマンドはファイルシステムをネットからDLしてくるので、結構時間がかかります。
6.エクスポートの設定
システムを動かすうえで、BSPとAPのファイルシステムを相互に参照できると便利だろうということで、APのファイルシステムをBSP側で公開(export)する設定をします。
echo ${APIP} ${APNAME} >> /etc/hosts
echo ${APROOT} ${APNAME}\(rw,no_root_squash,subtree_check\) >> /etc/exports
exportfs -a
${APIP}はAP用のIPアドレス、${APNAME}はAPのホスト名です。適当に設定しましょう。(もちろんBSPから届くネットワークリーチャブルでなければ意味はないでしょうが)→APNAME=AP0とすること!11項のapbootでAPをAP0として起動しているため、これと合わせておく必要があります!
ちょっと思ったのが、いちいちechoコマンドで設定ファイルを修正していますが、直接viでやった方がいいと思います。一瞬、何をしているのか考え込んでしまいました。
7.ルータの設定
APから外部ネットワークに接続するためにはBSP経由行う必要があります。BSPにルータの設定をしてやらないといけません。/etc/network/interfacesに以下の設定をしてやります。
iface ap0 inet static
address ${BSPIP}
netmask 255.255.255.255
pointopoint ${APIP}
up iptables -t nat -A POSTROUTING -s ${APIP} -o ${ETH} -j MASQUERADE
down iptables -t nat -D POSTROUTING -s ${APIP} -o ${ETH} -j MASQUERADE
BSPにデバイスap0を定義し、これがAPと通信できるようルートを設定しています。${ETH}はBSP側のEthernetデバイスで、通常はeth0でしょう。あと、/etc/sysctl.confで以下の行のコメントを外してやります。
net.ipv4.ip_forward
8.APカーネルのインストール
ここまで長々とBSP周りの設定をしてきました。ここからやっとAPまわりの設定に入ります。4項でDLしておいたAPカーネルを、5項で準備しておいたAPカーネル用システムにインストールしてやります。
sudo dpkg -i --root=${APROOT} \
ap-linux-image-2.6.32-art-generic_20130227_i386.deb \
ap-linux-headers-2.6.32-art-generic_20130227_i386.deb
9.AP用システムの整備
まだまだ続きます。
(1)AP用システムへ移動(rootで入ることに注意)
# chroot ${APROOT}
(注:${APROOT}が/となり、このシステムのhostsファイル等の設定を行います)
(2)AP用システムのrootのpasswdを設定してやる。
(3)AP用システムの/etc/hostsにて、${hostname}-${APNAME}でホスト名を設定してやる。
(4)/etc/default/console-setup 中のACTIVE_CONSOLESをコメントアウトする。
(5)仮想シリアル端末からのログインを可能にする。
# cd /etc/init
# sed s/tty1/ttyBSP0/ tty1.conf > ttyBSP0.conf
# rm tty?.conf
# cd ..
# sed -i s/ttyS0/ttyBSP0/ securetty
(6)ureadaheadを停止する。
# cd /etc/init
# mv ureadahead.conf ureadahead.conf.bak
# mv ureadahead-other.conf ureadahead-other.conf.bak
(注:ureadaheadはlinux起動を早めるための先読みモジュールです。リアルタイム動作しようとしているので、こういうタイミングに影響が出そうなのは止めといた方が無難でしょう。起動してしまえば関係ないとは思うんですが、なくてもリアルタイム動作には影響しないし、悪さしかしないでしょうから。)
10.AP用のメモリの設定
さて、またBSP側の設定に戻ります。BSPのブート時にカーネルに起動オプションを設定して、AP用のメモリを確保してやらないといけません。
apmem:APに割り当てる低位メモリの領域(複数のAPがある場合はカンマで区切って)
aphighmem:APに割り当てる高位メモリの領域
ampshm:共有メモリに割り当てる低位メモリの領域(APが複数あろうと領域は一つだけです)
maxcpus:BSPカーネルが占有するコア数
どのくらいが適当なのかわからないので、とりあえず以下の設定で動かしてみました。
apmem=300M aphighmem=400M ampshm=100M
ここで「低位メモリ」って何?という意味がわからないと、どれくらいの領域を割り当てたらいいのか見当もつきません。「低位メモリ」とは、Linuxでは物理アドレスの0x00000000を仮想メモリの0xc0000000に割り当てることがほとんどです。つまり仮想アドレスの0xc0000000~0xffffffffの1GBは、物理メモリの最初の場所に配置されることになり、ここを「低位メモリ」と呼びます。
それでここが重要なんですが、Linuxでは複数のプロセスが独自の仮想メモリをもらい動作しますが、この「低位メモリ」は各プロセス共通に割り当てられます。つまり各プロセスがOSのサービスとデータをやりとりしようとしたり、OSのプロセスなんかはこの「低位メモリ」内で動くことになります。
つまり、BSPカーネルとAPカーネルは独自にこの「低位メモリ」領域がないと動けないため、それぞれに動作に必要なだけのメモリを割り当てておかないといけません。とはいっても、どれくらいあれば必要なだけあるかなんて、当該カーネルが動くときにロードするモジュールにもよるので一概に言えません。(特にリアルタイム制御したい、なんて目的なんで外部との専用通信モジュールが必要になることもあるでしょうし)なので適当にとしか言えないのが、つらいところです。
なおうまくメモリ領域が設定できたかは、BSP起動後に/proc/iomemを見てやれば確認できます。
11.APのブート
ここまできてやっとAPの起動ができます。以下のコマンドでインストールしたAP用カーネルが起動し、9(5)で設定した仮想シリアル端末からログインメッセージがでます。
# ifup ap0
# apboot ${APROOT}/boot/vmlinuz-2.6.32-art-generic rw \
ip=${APIP}:${BSPIP}:${BSPIP}:::bsp:p2p \
nfsroot=${BSPIP}:${APROOT},nolock
APが複数ある場合は、apbootのオプションで番号を指定できます。デフォルトは0から始まる番号です。
と、ここまでAPのブートまではできるようになりましたが(できたと思います・・・)、仮想シリアル端末が接続できない状態です。そのうち動くようになったら、また書きます。
追記:
11項でapbootする前に、以下のコマンドでシリアル端末を開いておきます。
sudo screen /dev/ttyAP0
そうするとapbootでAPが起動するときのログが表示されてきます。そこでわかりましたが、起動に失敗してました!ログを見てると、どうもNFSマウントのところで失敗しているようなんですが、なんかap0とap1が混在してる?そういやapbootでAP0として起動してるのに、NFSの設定やらhostsファイルやらAP1で定義してちゃあかんでしょ!
ということでそこを修正、だいぶ起動シーケンスが進むようになりましたが、今度はAP0からBSPへのネットワークが届かないとのこと。どこかルータの設定に問題があるようです。先は長いです。(しかしAPの起動って、数十秒単位で結構時間かかるのね・・・)
結果:
やっと動きました。ルータの設定で最初APIPとBSPIPを同じネットワークアドレスにしたのがまずかったのかと思ったんですが、それでも状況は変わりません。(でもこれはまずいと思います)
APの起動ログをよく見ると、どうもNFSのマウントでBSP側からの応答がないということらしいということで、BSPのNFSサーバ周りの設定を見直しました。デフォルトだとUbuntuのデスクトップ版ではサーバ関係のパッケージ何も入っていないので、後からnfs-kernel-server, nfs-commonを追加インストールしましたが、どこか問題があったようです。手動でnfsdを動かしてやろうと、
sudo /etc/init.d/nfs-kernel-server restart
とやると処理が固まってしまい、戻ってきません。いやこれは明らかにおかしいだろうとネットをググってみると、どうもportmapが動いていないとこうなるようです。psコマンドで見ると、確かに動いてません。設定のどこに問題があるのかわかりませんが、ブート時にportmapが起動してくれなくて、そのためnfsdも動いてなかったようです。そこでとりあえず手動でこのあたりを起動して、再度apbootしたら、あっさり動いてくれました。先に起動に時間がかかるといってたのは、NFSのマウントでtime-outを待っていたせいでした。
ART-Linuxの実験 インストール(その1)
ART-Linuxとは産総研で研究されている、Linuxのリアルタイム版です。(昔、RT-Linuxというのがあったけど、公開の仕方に問題がありかなり揉めたよね~ 知ってる人はかなり年季の入った人だと思うけどw)
そんで以前から考えてたんですが、ここ数年マルチコアなCPUが増えました。基本Linuxは複数のCPUがあってもそれらは平等に扱いますが、「リアルタイム制御用のコアを設定できたら便利じゃないか?」と思ってたら、ART-Linuxがそれをつい最近(2013年3月)に発表してくれました。これはぜひとも試してみようと思い、記録をメモしておきます。
1.ART-LinuxのインストールするLinuxの準備
ART-LinuxはUbuntu-10.04(Lucid)のKernelを改造したもののようです。まずLucidをDLしてきて、それをマルチコアなマシンにインストールします。(手元で実験に使えそうなのがCore2Duoのマシンしかなかったので、これで。)32bit版をインストールしてください。
2.ART-Linuxのインストール(BSP)
1項でインストールしたUbuntuのkernelを産総研のART-LinuxのHPからDLしてきます。
linux-image-2.6.32-art-generic_20130227_i386.deb
linux-headers-2.6.32-art-generic_20130227_i386.deb
linux-source-2.6.32-art_20130227_all.deb
PAE(メモリ拡張用)とかありますが、今回はベーシックなものを。(ちなみにART-Linuxには32bitしかありません。とりあえずリアルタイムで動かす制御用アプリで64bitが必要な類のものは思いつかないのでいいと思いますが。)
これらをインストールします。
sudo dpkg -i linux-image-2.6.32-art_20130227_i386.deb linux-headers-2.6.32-art_20130227_i386.deb linux-source-2.6.32-art_20130227_all.deb
これでART-Linux(BSP用)のkernelがインストールされ、それ起動用にgrubの設定も追加してくれます。(つまり、元々のUbuntuも起動できます)
注:BSPというのはLinuxの通常業務を行うプロセスのことで、最低1コアは割り当てる必要があります。インストール直後はBSPに何コア割り当てるとかのkernel起動パラメータを設定してありませんので、この場合は2コアで動いてしまいますが、後々AP(リアルタイム用コア)を動かすまではそれで構いません。
3.サンプルプログラムの実行
さてインストールが成功したか確認してみます。BSPでもとりあえずこれまでのART-Linuxの機能はあるようです。(基本は厳密なタイマ管理ができるか、ということになると思いますが。BSPがアプリで占有できないので、ちょうどアプリが動きたいときにシステム作業が発生してしまうと止めようがないでしょうが、システムコールに影響されない厳密なタイマがあるだけでリアルタイムのアプリを書くのは楽になります)
#include <stdio.h>
#include <linux/art_task.h>
#include <time.h>
#include <sys/time.h>
double gettimeofday_sec()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec + (double)tv.tv_usec*1e-6);
}
void process(void)
{
register int i;
double start_t1;
double now_t1;
start_t1 = gettimeofday_sec();
art_enter( ART_PRIO_MAX, ART_TASK_PERIODIC, 1000000 );
/* Real Time Task Start */
for (i=0; i<100; i++) {
art_wait();
now_t1 = gettimeofday_sec();
printf("[%d] %10.30f\n", i, (now_t1 - start_t1));
}
putchar('\n');
art_exit();
/* Real Time Task exit */
}
int main(void)
{
process();
return 0;
}
以下のようにビルドします。
$ gcc -Wall -O sample1.c /usr/lib/art_syscalls.o
オリジナルのサンプルに少し追加しました。art_wait()で1秒間を正確にwaitしてますが、そこからほんの少しですがコードが動きます。その処理時間が累積するのかどうか、それを見るために実時間を表示しました。
大体、100回loopすると以下のような感じになります。
[99] 99.9835
あれ?なんか少しだけ早く回ってる?ちょっと予想とずれてしまいましたが、art_wait()の精度の問題なのか、gettimeofday()の問題なのか、長時間(1時間くらい)のサンプルを書いてみるか、外部に信号を出して計測してみないとわかりません。
追記:
その後、さらに設定をいろいろと変えて実験してみました。結論から言うと、
①上記の結果はインストール途中の結果であり、BSPは2コアの設定になっていた。またAP用のメモリ設定(今後、書きます)もしていなかった。ただし、gnomeのdesktopは動いていた。
②BSP=1にして実験すると、[99] 100.052等安定して処理が遅れるようになっていった。現在のLinuxのタスクスイッチが1ms、しかもデフォルトのART-Linuxの割り込み最短時間が1msなのを合わせて考えると、それが一番なっとくのいく結果と思われる。
③さらにART-Linuxの割り込み最短時間=500usにしてみたが、さらに安定して毎回1ms程度遅れるようになった。(予測しやすくなった)
サンプルが1秒ごとに1行出力するよ、という意味ではないような気がします。もっともこちらもART-Linuxのタイマ管理をよく勉強せずにサンプルを使ってしまいましたが、正確なタイマがあってもこうなるでしょう。本当に1秒周期で1行出力したいなら、タイマで0.99秒ほどまち、それからは1秒たったかloopでチェックするようにしないとだめでしょう。逆に最初の結果(早く動いてしまう)ほうが、リアルタイムのプログラムを作るうえでは、動作予測がしづらく使いづらいです。デフォルトのままだと、gnomeの割り込み処理や、Core2DuoやNvidia(グラフィックボードがこれ使ってます)のドライバ周りの割り込み等、リアルタイムを乱す要因がたくさんあり、変な結果になったと思います。(ゲーム程度の60Hz程度の周期でリアルタイム性が確保できればいいというならこれでもいいですが、本気で1ms周期の制御したいならCLIベースで動作させないといけないでしょう。)
そんで以前から考えてたんですが、ここ数年マルチコアなCPUが増えました。基本Linuxは複数のCPUがあってもそれらは平等に扱いますが、「リアルタイム制御用のコアを設定できたら便利じゃないか?」と思ってたら、ART-Linuxがそれをつい最近(2013年3月)に発表してくれました。これはぜひとも試してみようと思い、記録をメモしておきます。
1.ART-LinuxのインストールするLinuxの準備
ART-LinuxはUbuntu-10.04(Lucid)のKernelを改造したもののようです。まずLucidをDLしてきて、それをマルチコアなマシンにインストールします。(手元で実験に使えそうなのがCore2Duoのマシンしかなかったので、これで。)32bit版をインストールしてください。
2.ART-Linuxのインストール(BSP)
1項でインストールしたUbuntuのkernelを産総研のART-LinuxのHPからDLしてきます。
linux-image-2.6.32-art-generic_20130227_i386.deb
linux-headers-2.6.32-art-generic_20130227_i386.deb
linux-source-2.6.32-art_20130227_all.deb
PAE(メモリ拡張用)とかありますが、今回はベーシックなものを。(ちなみにART-Linuxには32bitしかありません。とりあえずリアルタイムで動かす制御用アプリで64bitが必要な類のものは思いつかないのでいいと思いますが。)
これらをインストールします。
sudo dpkg -i linux-image-2.6.32-art_20130227_i386.deb linux-headers-2.6.32-art_20130227_i386.deb linux-source-2.6.32-art_20130227_all.deb
これでART-Linux(BSP用)のkernelがインストールされ、それ起動用にgrubの設定も追加してくれます。(つまり、元々のUbuntuも起動できます)
注:BSPというのはLinuxの通常業務を行うプロセスのことで、最低1コアは割り当てる必要があります。インストール直後はBSPに何コア割り当てるとかのkernel起動パラメータを設定してありませんので、この場合は2コアで動いてしまいますが、後々AP(リアルタイム用コア)を動かすまではそれで構いません。
3.サンプルプログラムの実行
さてインストールが成功したか確認してみます。BSPでもとりあえずこれまでのART-Linuxの機能はあるようです。(基本は厳密なタイマ管理ができるか、ということになると思いますが。BSPがアプリで占有できないので、ちょうどアプリが動きたいときにシステム作業が発生してしまうと止めようがないでしょうが、システムコールに影響されない厳密なタイマがあるだけでリアルタイムのアプリを書くのは楽になります)
#include <stdio.h>
#include <linux/art_task.h>
#include <time.h>
#include <sys/time.h>
double gettimeofday_sec()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec + (double)tv.tv_usec*1e-6);
}
void process(void)
{
register int i;
double start_t1;
double now_t1;
start_t1 = gettimeofday_sec();
art_enter( ART_PRIO_MAX, ART_TASK_PERIODIC, 1000000 );
/* Real Time Task Start */
for (i=0; i<100; i++) {
art_wait();
now_t1 = gettimeofday_sec();
printf("[%d] %10.30f\n", i, (now_t1 - start_t1));
}
putchar('\n');
art_exit();
/* Real Time Task exit */
}
int main(void)
{
process();
return 0;
}
以下のようにビルドします。
$ gcc -Wall -O sample1.c /usr/lib/art_syscalls.o
大体、100回loopすると以下のような感じになります。
[99] 99.9835
あれ?なんか少しだけ早く回ってる?ちょっと予想とずれてしまいましたが、art_wait()の精度の問題なのか、gettimeofday()の問題なのか、長時間(1時間くらい)のサンプルを書いてみるか、外部に信号を出して計測してみないとわかりません。
追記:
その後、さらに設定をいろいろと変えて実験してみました。結論から言うと、
①上記の結果はインストール途中の結果であり、BSPは2コアの設定になっていた。またAP用のメモリ設定(今後、書きます)もしていなかった。ただし、gnomeのdesktopは動いていた。
②BSP=1にして実験すると、[99] 100.052等安定して処理が遅れるようになっていった。現在のLinuxのタスクスイッチが1ms、しかもデフォルトのART-Linuxの割り込み最短時間が1msなのを合わせて考えると、それが一番なっとくのいく結果と思われる。
③さらにART-Linuxの割り込み最短時間=500usにしてみたが、さらに安定して毎回1ms程度遅れるようになった。(予測しやすくなった)
サンプルが1秒ごとに1行出力するよ、という意味ではないような気がします。もっともこちらもART-Linuxのタイマ管理をよく勉強せずにサンプルを使ってしまいましたが、正確なタイマがあってもこうなるでしょう。本当に1秒周期で1行出力したいなら、タイマで0.99秒ほどまち、それからは1秒たったかloopでチェックするようにしないとだめでしょう。逆に最初の結果(早く動いてしまう)ほうが、リアルタイムのプログラムを作るうえでは、動作予測がしづらく使いづらいです。デフォルトのままだと、gnomeの割り込み処理や、Core2DuoやNvidia(グラフィックボードがこれ使ってます)のドライバ周りの割り込み等、リアルタイムを乱す要因がたくさんあり、変な結果になったと思います。(ゲーム程度の60Hz程度の周期でリアルタイム性が確保できればいいというならこれでもいいですが、本気で1ms周期の制御したいならCLIベースで動作させないといけないでしょう。)
登録:
投稿 (Atom)