/dev/nullらしき場所を読む
ではカーネルを読みます。
カーネル本によるとキャラクタデバイスから読むのが読みやすいと書いてあったので今回は/dev/nullを読みます。
/dev/nullが何かというとnullを返すデバイスです。
Linuxにおいてはすべてがファイルでありキーボードなんかもファイルとして読み出されるんですね。
下準備としてGNU GLOBALでタグを作っておきます。
パッケージマネージャからglobalをインストールしておきましょう。
ファイルの関数一覧なんかを表示してくれる頼りになるやつです。
まずはファイルの解析です。
公式サイトなんかからダウンロードしたソースを展開してそのフォルダで
gtags -v
を実行します。
解析結果がが保存されるのでとりあえず関数一覧を見ましょう。
global -f ファイル名
で関数一覧が出ます。
今回は/dev/nullを見るので/drivers/char/mem.cを開きましょう。
まず当たりをつけたのがnullを返すデバイスなのでどこかで0を返しているんじゃないかということです。
ヌルポインタと0は違うものなのですが大雑把にメモリアドレスの0番地をヌルポインタとして使っていることが多いです。
正確にはヌルポインタはどこも指していないポインタなのですが、メモリ0番地はたいていアクセスできないのでnullとして使用されることが多いです。
では関数を見ます。
global -f drivers/char/mem.c
で関数一覧が出ます。
尺稼ぎもあれなんでそれっぽそうなところを抜き出します。
global -f drivers/char/mem.c | grep null
read_null 669 drivers/char/mem.c static ssize_t read_null(struct file *file, char __user *buf,
write_null 675 drivers/char/mem.c static ssize_t write_null(struct file *file, const char __user *buf,
read_iter_null 681 drivers/char/mem.c static ssize_t read_iter_null(struct kiocb *iocb, struct iov_iter *to)
write_iter_null 686 drivers/char/mem.c static ssize_t write_iter_null(struct kiocb *iocb, struct iov_iter *from)
pipe_to_null 693 drivers/char/mem.c static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
splice_write_null 699 drivers/char/mem.c static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
null_lseek 769 drivers/char/mem.c static loff_t null_lseek(struct file *file, loff_t offset, int orig)
zero_lseek 816 drivers/char/mem.c #define zero_lseeknull_lseek
pipe_to_nullを覗く。
full_lseek 817 drivers/char/mem.c #define full_lseek null_lseek
write_zero 818 drivers/char/mem.c #define write_zerowrite_null
write_iter_zero 819 drivers/char/mem.c #define write_iter_zerowrite_iter_null
mem.cの関数一覧からgrep nullでnullと書かれた行を抜き出しました。
推測ですがiterがついているのはイテレータという反復処理をする関数ではないでしょうか?
lseekはシークなのであまり関係なさそうです。
怪しいと睨んだのがread_nullとwrite_nullです。
短いのでread_nullとwrite_nullを載せます。
著作権的にはGPLなので問題ないと思います。
なおGPLなのでこの文章もGPLにしておきます、まあ勝手に使ってください。
static ssize_t read_null(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t write_null(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
}
はい単純明快read_nullは0を返していますね。
特に難しいところはないかと思います。
write_nullに関してはちょっとよくわかんないですね。
おそらくcountを引数でとってそれをそのまま返しているようです。
countとは何でしょうか?
countの型size_tは処理系依存で大抵は符号なしintのマクロになっているようです。
ここから推測できるのは整数型のサイズを返しているようです。
writeなので書き込み時に呼ぶのでしょう。
今回推測できたのは以上です。
本当ならもっとやる予定だったのですが立て込んだので申し訳ありません。
またそのうちC言語基礎を書く予定なのでそちらもよろしければお願いします。
お読みいただきありがとうございます。