uClinuxがやっとブートした話のつづき。
この、某CPUの評価ボードには、プログラム中から制御できるLEDが16個ついている。こうなったら、なにはさておき、「ナイトライダー」を作らなくては、気がすまない(笑)。
PDFのハードウェアマニュアルを斜め読みしていくと、あるアドレスに16ビットデータを書き込めばLEDが点灯することがわかる。
そこで、簡単なテストプログラム数行を、C言語で書いて、実行してみると、Memory Faultとかいうようなエラーがでて、LEDの点灯状況はまったく変化しない。このエラーメッセージは、シグナルハンドラで出しているっぽい雰囲気。
組み込みネットに掲載されていたuClinuxの紹介記事によれば、uClinuxでは、MMUをサポートしていないので、メモリ・プロテクションも、アドレス変換もなにもしていない、と書いてあった。実は、これは、古い情報だったらしい。実際には、メモリ保護は実装されていた。だから、ユーザープログラムからは、LEDを制御するアドレスへの書き込みは、許可されていないらしい。
そのことを知らずに、/dev/memをつかったり、mmapしてみたりしたけど、ぜんぜんダメ。それが月曜までの状況。
今日になって、メモリ保護が実装されてんじゃないの?という疑いがムクムクっともちあがり、カーネルソースをざざーっとながめる。やっぱり、実装されてんじゃん。。。と、ようやく気が付く。てゆーか、そのCPUアーキ用にかかれたドキュメントをみれば、すぐわかったことだった。
じゃあどうしようかな、ってことで、LEDを制御するデバドラを書いてみることにした。デバイスドライバを書くのは、MS-DOS以来だ。
procfsを使うと簡単らしいことが、グーグルしてみてすぐわかった。
適当にコピペ。
ググッた情報は、どのバージョンのlinuxのことだかぜんぜん書いてないものが多く、どうもそのままでは動かないっぽい。コンパイルオプションとか、コーディングの流儀とかも、微妙に違うらしい。
とりあえず、今あるカーネルソースに含まれているデバイスドライバを参考に、手直しをする。
1時間ほどして、ようやく動いた。ソースコードは100行ほど。insmodしたとき、ちょっと、わけのわかんないエラーがでるので、一部の機能は殺した。
echo "0000111111110000" >/proc/led みたいにして、LEDが点灯することを確認。
あとは、ナイトライダーするプログラムは、シェルスクリプトで書き、実行。
とりあえず、これで満足した。
0 件のコメント:
コメントを投稿