2.6.32关于bus_id的问题
来源:互联网 发布:知乎周刊全集 编辑:程序博客网 时间:2024/05/13 04:58
转自:http://zhuzhenzhong123.blog.163.com/blog/static/198862752011101825626662/
实验环境:
linux2.6.32.2
在做bus驱动实验的时候,出现了一个问题:
提示bus_id找不到。于是到内核源代码找了一番,果然没有看见。直接到device结构体中看,找到的最像的也就
const char *init_name; /* initial name of the device */
想到这个也可以作为标识,并且BUS_ID_SIZE也找不到,于是将strncpy(my_dev.init_name, "my_dev", BUS_ID_SIZE);注释掉,直接在mydev中添
加.init_name="my_dev"。
但是在注册驱动时又出现了段错误,根据console打印,知道在strncmp时,也就是总线在比较驱动和设备的名字的时候出问题了。
于是在比较函数里加入
printk("dev->init_name:%s\tdriver->name:%s\n", dev->init_name, driver->name);
想看看到底是怎么比较的。结果console上打印出来的是
dev->init_name:<NULL> driver->name:my_dev (与下面亮点关联)
Unable to handle kernel NULL pointer dereference at virtual address 00000000
dev->init_name不存在?
于是baidu了一下,发现了了下面网友的那段,我用对了init_name,却没直接在内核里搜到dev_name(dev),于是又在内核搜索一番。可以找到下面一段总线上的比较函数:
static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
{
struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
int len = strlen(sub->wanted);
if (0 == strncmp(dev_name(dev), sub->wanted, len))
return 1;
return 0;
}
它用的是dev_name(dev)而不是dev->init_name。还是在match函数里加入输出语句,打印如下:
dev_name(dev):my_dev driver->name:my_dev
成功了!
那我们深究下,dev_name()是什么东东呢?
static inline const char *dev_name(const struct device *dev)
{
return kobject_name(&dev->kobj);
}
├———static inline const char *kobject_name(const struct kobject *kobj)
{
return kobj->name;
}
其实就是kobj->name;
dev_name(dev)怎么和dev->kobj-name联系上的呢?找遍“可见”代码找不到,猜测很可能是在device_register里面。
从源码里顺蔓摸瓜:
└—device_register
└—device_add
└—if (dev->init_name)
{
dev_set_name(dev, "%s", dev->init_name);
dev->init_name = NULL; (亮点!)
}
dev_set_name
└—kobject_set_name_vargs (看到希望了!)
└—kobj->name= kvasprintf(GFP_KERNEL, fmt, vargs);(找到了,这个就是的了!)
找到了!就是在注册设备的时候将init_name成员赋给了kobj->name,发现那个"亮点"没,不是说说写得有多漂亮(也不是说写得不漂亮,纠结了。。),“亮
点”的意思是发现了新大陆那种感觉,越说越远。。看到前面我为了查错误从控制台打出来的信息,dev->init_name:<NULL> driver->name:my_dev中,dev-
>init_name等于NULL就是在这个dev->init_name = NULL;“亮点”的地方被置空了。这也是为什么用strncmp比较会出错的原因。
要感谢下面这个网友,才想到要到内核去搜一下dev_name。内核版本号不同,必然有一些改动,当我们发现不同后,要善于从中去找到不同,找到解决问题的方
法。
以下是转载自
网友ying_seven的博客(看到其也是转载的,但是并没有注明来处)
--------------------------------------------------------------------------------------------------------------------------
按照国嵌的代码(LDD那本书上的代码也一样):
struct device my_bus = {
.bus_id = "my_bus0",
.release = my_bus_release,
};
static int my_match(struct device *dev, struct device_driver *driver)
{
return !strncmp(dev->bus_id, driver->name, strlen(driver->name));
}
编译时,提示 struct device 中没有bus_id 这样的错误。打开/lib/modules/2.6.35-28-generic/build/include/linux/device.h
找到struct device 的定义,里面没有bus_id,但有:
const char *init_name; /* initial name of the device */ 这句。
可见,要把上面结构中的.bus_id = "my_bus0", 改为 .init_name = "my_bus0",
同时上网搜到,return !strncmp(dev->bus_id, driver->name, strlen(driver->name));这句也要改成:
return !strncmp(dev_name(dev), driver->name, strlen(driver->name));
这样编译即可成功!
另注:
如果要设置设备的名字,也不再使用strncpy(my_dev.bus_id, "my_dev", BUS_ID_SIZE); 而改用:
dev_set_name(&dev, "name");
- 2.6.32关于bus_id的问题
- 关于2.6.32内核bus_id的问题
- 2.6.32关于bus_id的问题
- 关于bus_id的问题
- 关于2.6.32在创建bus总线时的bus_id和.init_name的问题
- 关于2.6.30.4在创建bus总线时的bus_id的问题
- 移植2.6.31遇到的问题(2):'struct device' has no member named 'bus_id'
- 嵌入式创建总线bus时的bus_id问题
- 总线驱动模型——2.6.30中bus_id消失问题
- ldd3 lddbus编译遇到问题 bus_id
- struct device的成员变量bus_id到哪里去了?
- linux2.6.28和linux2.6.3xx内核 的struct device 中,bus_id的改变
- 总线设备驱动框架程序 及 struct device中消失的bus_id的取代方法
- 总线设备驱动框架程序 及 struct device中消失的bus_id的取代方法
- 关于问题的问题
- linux中device->bus_id找不到
- 5.4 关于问题的问题
- 关于TreeTable 的问题
- 遇到的spark 错误
- 黑马程序员—接口
- jquery的翻页分页插件使用
- 那些所谓的曾经
- 深入理解Hadoop集群和网络
- 2.6.32关于bus_id的问题
- 《从菜鸟到测试架构师》简要总结(1)----新人培训
- binder驱动-------之数据结构篇1
- 回忆也是一本无价的书,一种买不到的幸福。
- linux学习笔记(四)_shell与shell script__bash shell
- javascript:void(0)
- 【Unity Shaders】Lighting Models —— 衣服着色器
- 二叉树后序遍历
- Eclipse 插件开发 基于org.eclipse.ui.startup扩展点 实现eclipse启动时执行相关操作