デバイスドライバを書かずにIOを読み書きする_その2

汎用ライブラリ化してみた

i386用の ioperm() をまねて bogo_ioperm() を作ってみました。
使い方は i386の ioperm()と同じです。

ただし、あくまでも超簡易的なものです。bogo_ioperm()内部ではスタティックに変数を使っているので

  • 2度 bogo_ioperm() を呼び出してはいけません。開けるwindowは一箇所のみ
  • 当然スレッド*アンセーフ*です

filebogoio.tgz

userland_io/
userland_io/userland_io.slpro
userland_io/Makefile
userland_io/main.c
userland_io/README
userland_io/bogoio.c
userland_io/bogoio.h

bogoio.h

int bogo_ioperm(unsigned long from, unsigned long num, int turn_on);

unsigned char bogo_inb(unsigned long port);
unsigned short bogo_inw(unsigned long port);
unsigned int bogo_inl(unsigned long port);

void bogo_outb(unsigned char value, unsigned long port);         /* データ, アドレスの順なので注意 */
void bogo_outw(unsigned short value, unsigned long port);
void bogo_outl(unsigned int value, unsigned long port);

main.c

#include <stdio.h>
#include "bogoio.h"
int main(){
        // 使用開始 0xa4000000番地〜 0x400バイト分
        bogo_ioperm(0xa4000000,0x400,1);

        // 0xa4000130番地に 0x00 出力
        bogo_outb(0x00,0xa4000130);

        // 閉める
        bogo_ioperm(0xa4000000,0x400,0);

        return 0;
}

普通のユーザランドのプログラムですから gdbserver を使ったリモートデバックや、SWEETを使った Windows機からのリモートデバックでプログラム開発がしやすくなると思います。

sweet.jpgSWEETは、WINDOWS上でLinuxプログラムの開発を行うアプリケーションです。
開発に必要なコマンド や面倒なコマンドが簡単に使えるようになります。
既に使いこなしている上級者には 「より使いやすい環境」 を、
Linuxの コマンドラインでの開発が初心者という方には 「やさしい環境」 を提供します。
SWEET

なぜ これが 「あまりお勧めできない」のか

デバイスドライバを書かなくてもユーザ空間から直接I/Oが操作できるようになりました。便利ですよね。gdbやSWEETを使ってステップ実行したり、で気軽に実験が出来ます。アプリケーションプログラム中からから直接I/Oを操作するのは、

  1. てっとりばやい
  2. いろいろ試しやすい
  3. gdb (gdbserver) や SWEETでお手軽にデバックできる

とうメリットがあります。ハードウェア動作確認のための手法としてはかなり便利です。

しかし勉強やテストを除き、アプリケーションプログラム中からから直接I/Oを操作するコードで「仕事を終わらせるのは」避けるべきです。理由は、セキュリティーとかpermissionがどうのこうの、という理由ではありません。

トータルで開発費が高くついてしまうから

です。

例えば i396の inb(), outb() や 上記の bogo_inb(), bogo_outb() を多用して

int main()
   unsigned char x;
   ioperm(ナントカ);
  
   x=inb(LEDポート);
   outb(x|0x80 , LEDポート);  // 動作LED点灯

というコードを書いてしまうと、それはそのボード(基板)でしか動かない、移植不可能な(移植に手間=コストがかかる)ソフトウェアになってしまいます。

例えば今回は SH3ボードでソフトウェアを書き、動作し、納品したとします。ところが3年後くらいになって、じゃぁ基板改定しましよう、今度はARMプロセッサです。とか言われたときに昔のコードをサッと取り出してサッと修正して仕事を終わりにしたいですよね(プロとしては)。

面倒でもデバイスドライバを書くというのは、ハードウェアとアプリケーションを分離するためです。LEDやGPIOという簡単なハードウェアでも、面倒でもデバイスドライバを作ってアプリケーションと分離させておけば、LEDのデバイスドライバだけを新基板用に書き直して、そこだけ単体テストすれば昔のアプリケーションはまったく手を入れずにサッと再利用できます。

アプリケーションとハードウェアを分離すると利点はたくさんあります

  1. アプリケーションメイン部分が違う基板に移植しやすくなる/共有化できる
    せっかく書いたコードだもの。大切に長生きさせたいですよね
  2. 複数人で開発しやすい
    あなたドライバ、私アプリ。みたいに。外部委託もしやすい
    一人でやるときも頭を切り替えやすい
  3. 仕事の引継ぎが楽になる
    先ほどのように、将来基板改定が入ったときに、ソフトを作った人間が既に辞めちゃった困った。という場面でも、ドライバ部分だけ書き直せばなんとかなる、仕様の引継ぎが楽

先ほどからアプリケーション側の利点ばかりいっていましたが、同時にドライバ側にも利点はあって、ドライバも一度書いてしまえば長く使いまわせるというメリットがあります。

だから最初は面倒でも

『将来の自分に楽をさせると思って』

ハードウェアとの分離を進めていくと、やっぱり将来の自分はかなり楽が出来るはずです。

それで

上記の理由を踏まえ理解いただいたうえで、最初は bogo_inb() などを利用してデバックを進め、最終的にはデバイスドライバの形で社内資産を蓄積してはいかがでしょうか。

Linuxデバイスドライバのセミナーは定期的に開催しています。

次回(があれば) linux-2.6のデバイスドライバについて記述します。デバイスドライバが書けるようになるとユーザーランドだけでは不可能な

  • 割り込み
  • DMA(バスマスタ)転送

等が使えます。

リンク

Last-modified: 2019-07-22 (月) 17:56:00 (32d)