[Suzaku:00591] Re: キャラクタデバイスのドライバーの作成

Yasushi SHOJI email@hidden
2006年 7月 13日 (木) 17:41:35 JST


At Thu, 13 Jul 2006 17:11:19 +0900,
Abe wrote:
[...]
> f_posは「・・ユーザーがアクセスしているファイルの位置を示す・・」と
> ありましたので、seekで設定した値が反映されると思っていました。
> ではseekは意味が無いと言う事なんでしょうか。

カーネルの世界へようこそ。:-)

ユーザランドでは

    fd = open("/path/to/file", ...);
    lseek(fd, offset, SEEK_SET);
    write(fd, buf, c);

とすることで、/path/to/fileの offset目からデータを書くことができます。
これは kernelが見せている虚像にすぎません。

kernel側から上記の挙動を見ると openではファイル名が渡され、lseekではシー
クするための値が渡され、writeではデータの入ったメモリ領域のアドレスと
バイト数が渡されるだけです。

kernelはそれぞれ渡されたデータをある場所に書いたり、読んだりという実際
の処理を行なわなければなりません。kernelには虚像を見せてくれる人はいな
いのです。

ですから「seekは意味が無い」ということではなく、「(必要であれば) seek
に意味を持たせなくてはならない」のです。

> それと、
> >    *(volatile unsigned long *)ADDRESS = VALUE;
> >
> > と書くと ADDRESSで指定した値で address busがドライブされ、data busでは
> > VALUEの値がドライブされると思います。
> ですが、
> どのように関数の中に書けばよいのか分かりません。

仮に opb_emcがマップされているアドレスが 0xffffd000、書きたい値を 0x5a
としたとき

ssize_t s_write(struct file *filp, const char *buf, ssize_t count, loff_t *f_pos)
{
	*(unsigned long *)0xffffd000 = 0x5a;

	return 0;
}

としてはどうでしょうか?与えられるデータや、seekの有無に関わらず
0xffffd000に 0x5aが書かれるはずです。しかもユーザランドから見ると
write()システムコールは、なにも書かれなかったことを示す 0を返すはずで
す。
--
          yashi



suzaku メーリングリストの案内