Linuxデバイスドライバプログラミングを読みつつRaspberry Piでデバドラ開発(5章)

5章はドライバプログラミングの基礎知識について.

連結リスト

Linuxカーネルには,ドライバへの連結リストの実装を容易化する構造体やマクロが提供されている.

連結リストは次のlist_head構造体を用いて実装する.
この構造体をどのように利用すればよいかが一見わからない.

struct list_head{
    struct list_head *next, *prev;
};

なにかの構造体にリスト構造を持たせるためには,
struct list_head型のメンバを定義する必要がある.
定義する場所はどこでもよい.
以下ではint型のidをリストで扱う例を示す.

struct sample_data {
    int no;
    struct list_head list;
};

このstruct list_headのメンバは,
ドライバのロード時にINIT_LIST_HEAD関数で以下のように一度だけ初期化しておく必要がある.

struct sample_data data
INIT_LIST_HEAD(&data.list);

リストに要素を追加するには,list_add関数を使用する.
第一引数には新しい要素のstruct list_head型のメンバをポインタで渡す.
第二引数にはリストのHEADとなるポインタを渡す.

末尾に追加するにはlist_add_tail()を代わりに使う.
これによりキュー型のリストを作れる.

仮想メモリ

readやwriteといったシステムコールを扱うときは,
ユーザプロセスとデバイスドライバ間でデータの受け渡しを行うことになるが,
別々のメモリ空間上で動作しているため,互いが直接アクセスできない.

そこでLinuxカーネルではユーザプロセスとドライバ間でのデータコピー用のカーネル関数(マクロ)が用意されている.