上午,我主要在阅读ldd书中scull的代码 编译scull目录下的代码,并insmod后会出现3个设备scull、scullp、sculla,其中scull是最简单的,scullp设备使用 了环形缓冲区和阻塞读写的技术,sculla貌似是添加了访问控制的功能,我主要在看scull的代码,并把scull设备的代码独立出来了,之后对其进 行编译、插入模块、读写等操作。
scull的整体结构是很基本的,只是在内存的处理方面有些繁琐。以前我虽然大致了解字符设备驱动程序的基本框架,但是ldd中调试技术我没有看,在代码中遇到了使用proc文件系统的技术,scull中用到了两种使用/proc文件系统的方法:
1、使用create_proc_read_entry()创建/proc/scullmen文件,并绑定读取函数scull_read_procmem;
2、使用seq_file接口,使用create_proc_entry()创建/proc/scullseq文件,之后指定proc_fops.
在对设备测试时,觉得每次输入insmod mknod rm rmmod命令有点麻烦,但是shell脚本的写法基本全忘了,于是就顺便复习了下perl的内容(其实当初也没学得很深入)
装载模块,创建设备文件
#!/usr/bin/perl
use strict;
use warnings;
system("insmod ./scullm.ko");
for(my $i = 0; $i < 4; $i ++){
if(-e "/dev/scullm$i"){
system("rm /dev/scullm$i");
}
}
my $line;
my $major;
open(DEV, "/proc/devices") || die("Failed to open /proc/devices $!/n");
while($line = <DEV>){
if($line =~ /(/d+)/s+scullm$/){
$major = $1;
}
}
if(defined($major)){
for(my $i = 0; $i < 4; $i ++){
system("mknod /dev/scullm$i c $major $i");
}
}
简单的测试(每个文件写入一点内容,然后再读出来)
#!/usr/bin/perl
use warnings;
use strict;
my $n = 0;
for($n = 0; $n < 4; $n++){
print("open /dev/scullm$n/n");
open(FILE, ">/dev/scullm$n") || die("$!");
print(FILE "dev/scullm$n /n");
close(FILE);
}
print ("now get data out");
for($n = 0; $n < 4; $n++){
open(FILE, "</dev/scullm$n") || die("$!");
my $line = <FILE>;
close(FILE);
print ("$line");
}
删除设备文件,卸载模块
#!/usr/bin/perl
use strict;
use warnings;
for(my $i = 0; $i < 4; $i ++){
system("rm /dev/scullm$i");
}
system("rmmod scullm");
(代码水平不够)
下午,我请教了下赵猛学长我的新内核不能联网的问题:在 /etc/init.d/network start时会报错:“pcnet32 device eth0 does not seem to be present delaying initializtion”,他告诉我在.config中驱动PCNET32的驱动没有选中。傍晚,我修改了下.config文件,把 CONFIG_PCNET32 is not set 修改为CONFIG_PCNET32=yes,重新编译,安装后就可以了。
晚上,赵猛学长给我讲解了request中buffer的原理: 每一个新来的bio结构后,系统会把试图把它合并到已有的request中,条件是bio中指向的缓存区域与request中的bio连续,否则会重新创 建一个request结构。(不知道我这样理解对不对)。这样一来每个request结构中bio指向的缓存是连续的,所以使用一个buffer指针就可 以了。关键在于理解request中的bio指向的缓存地址连续。
此外,我在读代码的时候,发现对于cscope的使用依然不熟,但发现
貌似使用 cscope-indexer -r比cscope -Rbkq好用一些;
以前在vi中使用cscope查到一堆结果(好几页)时,我不知道怎么退出查找结果,总是一直往后翻,翻到最后了,敲回车就可以了,今天发现:
SPACE/d/j: screen/page/line down, b/u/k: up, q: quit
原来,敲q就行了,居然和man差不多。