设为首页 收藏本站
查看: 445|回复: 0

[经验分享] Linux内核大讲堂 (二) 传说中的字符设备(1)

[复制链接]

尚未签到

发表于 2016-3-15 08:53:50 | 显示全部楼层 |阅读模式
Linux内核大讲堂()传说中的字符设备(1)

就当我还在学校的时候,我就曾在一个装机群里听一位装机圣手说,驱动程序的安装没你想的那么简单,分类型的,分为字符设备驱动和块设备驱动。我当时就纳闷了,我说我装机的时候好像没看到啊,我就把光盘放过去然后就一直点下一步,然后重启就好了啊。后面我在群里被几位高手围攻,败下阵来,时过境迁,哥现在也算是道上混的兄弟了,再也没那么容易被蒙了。就算你DIY再牛,你也不要和我说装驱动要分类。否则我就和你讲内核,讲晕你再说。看谁更能吹,哈哈。我得意的笑。我发现学内核的一个好处,就是非常好装B。你只要把内核里面的名词背熟了,拿出来去吓唬吓唬人,挺管用的,不过撞到行家的话,你就要注意了。呵呵。
好了,学内核不是为了吓唬人的,是为了掌握其原理,学习其技巧与方法,知其然而知其所以然,另外内核代码是具有一定复杂度的,看了内核代码再看看我们自已写的,和玩具没啥两样,这就是学内核的好处!
如果看了驱动模型系列文章的朋友应该有这种感受:你这玩意折腾来折腾去半天的,昨不干活呢?
我本来是打算把要讲的东西全部都自已实现一套,如果把这整个一系列看完的话,应该是具备了自已制作总线,驱动,设备,文件系统等一系列能力的,但是这样下去的话,一者怕大家受不了,二者说实话,我也不好受,需要花费的时间精力过大。是重复造轮子。并且造的还不如人家的好。所以就决定还是回归本原,不到万不得已,不打算自已写了!
字符设备是传说中的东西,玩过linux的人都知道这个东西,很多同志也可以照猫画虎的写出一个字符设备。但哥不,哥是有追求的人,知其然,必需得知其所以然。我决不会不负责任的把大家领进门后就不管了。我依然会不惜笔墨的把该说的全都说清楚。我们先不用去抠概念,不要说,什么是字符设备啊,什么是块设备啊。这些都没意义,你最需要知道的是这个叫字符设备的东西究竟都干了些啥?他到底是怎么工作的?搞清楚后,什么是字符设备你就明白了。如果再学块设备,一对比,差异在哪?你就明白了。我学习一向都不喜欢抠概念。有的同志你叫字符设备他回答你说char设备,你说块设备他说block设备,你说底半部他说下半部。你说NXP他说恩智浦,还好哥是道上混的,多少知道一点。否则就被人家给唬住了。好了,闲话不多说了,总的来说要表达的就是一种学习态度:不用抠概念。
接下来我们欣赏一下字符设备。
看过驱动模型系列文章的同志现在应该有一种意识了,我们暂且把它叫做“初始化意识”。就是说你用register_chrdev()注册的时候是很爽,但是那是因为前人把路铺好了,好,我们就来看看前人都做了些啥,再提醒一次一定要有“初始化意识”。
我们在“初始化意识”的指引下找到了一个文件:char_dev.c。打开这个文件一看。有这么一个初始化函数:
void__initchrdev_init(void)
{
cdev_map=kobj_map_init(base_probe,&chrdevs_lock);
bdi_init(&directly_mappable_cdev_bdi);
}
base_probe是一个很简单的函数:
staticstructkobject*base_probe(dev_tdev,int*part,void*data)
{
if(request_module("char-major-%d-%d",MAJOR(dev),MINOR(dev))>0)
/*Makeold-style2.4aliaseswork*/
request_module("char-major-%d",MAJOR(dev));
returnNULL;
}
request_module这个函数先大概知道意思就行了,他的意思是请求加载一个模块。
chrdevs_lock是一把大大的锁。没别的,就这两玩意。
关键在:
structkobj_map*kobj_map_init(kobj_probe_t*base_probe,structmutex*lock)
{
structkobj_map*p=kmalloc(sizeof(structkobj_map),GFP_KERNEL);
structprobe*base=kzalloc(sizeof(*base),GFP_KERNEL);
inti;

if((p==NULL)||(base==NULL)){
kfree(p);
kfree(base);
returnNULL;
}

base->dev=1;
base->range=~0;
base->get=base_probe;
for(i=0;i<255;i++)
p->probes=base;
p->lock=lock;
returnp;
}
最关键的一个角色就在这种神不知鬼不觉的情况下登场了,那就是structkobj_map
我们可以看到首先用kmalloc分配了一块内存并赋值给structkobj_map*p了。
structkobj_map{
structprobe{
structprobe*next;
dev_tdev;
unsignedlongrange;
structmodule*owner;
kobj_probe_t*get;
int(*lock)(dev_t,void*);
void*data;
}*probes[255];
structmutex*lock;
};
里面内嵌了一个长度为255的结构体数组和一把锁。
Linux内核里面如果是直接分配比较大块的内存,基本都是有hash思想在里面的,主要是为了效率。这个结构体中的成员等会大家就知道干嘛用的了。
接下来
structprobe*base=kzalloc(sizeof(*base),GFP_KERNEL);
内核作者你就卖弄吧。写成structprobe*base=kzalloc(sizeof(structprobe),GFP_KERNEL)这样多好?不管了,随便了,反正我只取其精华。
接下来:
if((p==NULL)||(base==NULL)){
kfree(p);
kfree(base);
returnNULL;
}
如果对这个有疑问的同志可以仔细研究一下kfree函数。这个是没有问题的。我再说一个思想,有疑问就看源码,不要去翻书,或者google百度的。Linux内核里面的函数全都是自给自足的,你所有的疑问都可以通过翻阅内核源码本身得到解决。当然啦,如果不是说不要去看书,我的意思是能不看就尽量不看。
接下来:
base->dev=1;
base->range=~0;//取反,比你写一堆0xff...好多了,并且可移植性更好
base->get=base_probe;//把函数指针指向传进来的那个回调函数。
接下来:
for(i=0;i<255;i++)
p->probes=base;
base初始化整个kobj_map.probe[255]
p->lock=lock;
returnp;
最后把锁也传过来,并返回指针。
接下来:
bdi_init(&directly_mappable_cdev_bdi);
这个玩意先不用管了,这个对我们理解字符设备目前没有任何帮助,并且只能添乱。
好了。今天就到这吧。
下一节可能会比较久,最近实在太忙了。请各位体谅一下!谢谢。抽烟去罗。^_^



<!--EndFragment-->

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-190944-1-1.html 上篇帖子: Linux下如何使CP命令不提示覆盖(转) 下篇帖子: 共用Linux用户时使用自己的配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表