设备驱动模型中设备的init_name成员

        现象是依次加载了总线bus,设备device,驱动driver,在加载驱动时候出现了segmentation fault。采用的是国嵌的教材(可能是教材比较古老了吧,导致出现这样问题),内核版本使用的是2.6.32.2。

        首先更正一下国嵌源代码中的一些新旧版本引起的问题。struct device 结构的bus_id 成员(不知道是那个版本的了)。

struct device my_bus = {
	.bus_id   = "my_bus0",
	.release  = my_bus_release
};

         现在的 struct device 结构中使用 const char  *init_name; /* initial name of the device *,即应当修改成如下的形式。其他的相应的改动就省略了。

struct device my_bus = {
	.init_name   = "my_bus0",
	.release  = my_bus_release
};

         回到正式的Bug,也算是新旧版本引起的问题。总线上的match函数实际调用的函数。

static int my_match(struct device *dev, struct device_driver *driver)
{
	return !strncmp(dev->bus_id, driver->name, strlen(driver->name));
}

        一开始先将dev->bus_id改成了dev->init_name,解决了编译上的错误。但是改成这样之后再加载便出现了segmentation fault。根据segmentation fault的错误显示,锁定在是在strncmp()函数调用出了错。具体原因便不得而知了,后面进行了这样的假设,将dev->bus_id和driver->name分别改成“my_dev”,发现当修改dev->init_name为“my_dev”时加载正常。于是开始根据调用栈一步步往被调用的函数查找原因。段错误的信息如下:

Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c39a4000
[00000000] *pgd=33a79031, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1]
last sysfs file: /sys/devices/my_bus0/my_dev/dev
Modules linked in: driver(+) device bus
CPU: 0    Not tainted  (2.6.32.2-FriendlyARM #5)
PC is at strncmp+0x14/0x70
LR is at my_match+0x2c/0x38 [bus]
pc : [<c014a8d4>]    lr : [<bf00002c>]    psr: 20000013
sp : c3a73e48  ip : c3a73e58  fp : c3a73e54
r10: 00000000  r9 : c3a72000  r8 : c0030088
r7 : 00000000  r6 : c0187cf4  r5 : bf00c0f0  r4 : bf0060a0
r3 : bf00c0f6  r2 : 00000006  r1 : bf00c0f0  r0 : 00000000
Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: c000717f  Table: 339a4000  DAC: 00000015
Process insmod (pid: 741, stack limit = 0xc3a72270)
Stack: (0xc3a73e48 to 0xc3a74000)
3e40:                   c3a73e6c c3a73e58 bf00002c c014a8d0 bf0060a0 bf00c120
3e60: c3a73e8c c3a73e70 c0187d20 bf000010 bf00c120 c3a73e90 c0187cf4 00000000
3e80: c3a73eb4 c3a73e90 c0187408 c0187d04 c3a51338 c39dd390 bf00c120 bf000228
3ea0: c39dd120 00000000 c3a73ec4 c3a73eb8 c0187a80 c01873a8 c3a73ef4 c3a73ec8
3ec0: c0186c60 c0187a70 bf00c0f0 bf00c120 bf00c120 bf00c120 00000000 bf00f000
3ee0: c0030088 00000000 c3a73f14 c3a73ef8 c0188064 c0186bcc bf00c120 c3a72000
3f00: 00000000 bf00f000 c3a73f2c c3a73f18 bf00f018 c0187ff4 c049d9c0 c3a72000
3f20: c3a73f7c c3a73f30 c002f32c bf00f010 00000000 00000000 00000000 00000000
3f40: 00000000 000b8038 bf00c168 00000000 00000c3d 000b8038 bf00c168 00000000
3f60: 00000c3d c0030088 c3a72000 00000000 c3a73fa4 c3a73f80 c006e394 c002f300
3f80: c3a73fa4 ffffffff 00000005 00000069 bef0ce94 00000080 00000000 c3a73fa8
3fa0: c002fee0 c006e2d8 00000005 00000069 000b8038 00000c3d 000a3cd0 00000000
3fc0: 00000005 00000069 bef0ce94 00000080 bef0ce98 000a3cd0 bef0ce98 00000000
3fe0: 00000001 bef0cb44 0001852c 401c8984 60000010 000b8038 00000000 00000000
Backtrace: 
[<c014a8c0>] (strncmp+0x0/0x70) from [<bf00002c>] (my_match+0x2c/0x38 [bus])
[<bf000000>] (my_match+0x0/0x38 [bus]) from [<c0187d20>] (__driver_attach+0x2c/0x98)
 r5:bf00c120 r4:bf0060a0
[<c0187cf4>] (__driver_attach+0x0/0x98) from [<c0187408>] (bus_for_each_dev+0x70/0x98)
 r7:00000000 r6:c0187cf4 r5:c3a73e90 r4:bf00c120
[<c0187398>] (bus_for_each_dev+0x0/0x98) from [<c0187a80>] (driver_attach+0x20/0x28)
 r7:00000000 r6:c39dd120 r5:bf000228 r4:bf00c120
[<c0187a60>] (driver_attach+0x0/0x28) from [<c0186c60>] (bus_add_driver+0xa4/0x248)
[<c0186bbc>] (bus_add_driver+0x0/0x248) from [<c0188064>] (driver_register+0x80/0x140)
[<c0187fe4>] (driver_register+0x0/0x140) from [<bf00f018>] (my_driver_init+0x18/0x30 [driver])
 r7:bf00f000 r6:00000000 r5:c3a72000 r4:bf00c120
[<bf00f000>] (my_driver_init+0x0/0x30 [driver]) from [<c002f32c>] (do_one_initcall+0x3c/0x1dc)
 r5:c3a72000 r4:c049d9c0
[<c002f2f0>] (do_one_initcall+0x0/0x1dc) from [<c006e394>] (sys_init_module+0xcc/0x1fc)
[<c006e2c8>] (sys_init_module+0x0/0x1fc) from [<c002fee0>] (ret_fast_syscall+0x0/0x28)
 r7:00000080 r6:bef0ce94 r5:00000069 r4:00000005
Code: e92dd800 e24cb004 e3520000 0a000010 (e5d03000) 
---[ end trace 5a4392902458b24f ]---
Segmentation fault

         最后发现是内核中int device_add(struct device *dev)函数中有这么一段代码:

/*
	 * for statically allocated devices, which should all be converted
	 * some day, we need to initialize the name. We prevent reading back
	 * the name, and force the use of dev_name()
	 */
	if (dev->init_name) {
		dev_set_name(dev, "%s", dev->init_name);
		dev->init_name = NULL;
	}

         根据注释可以知道了,强制要求使用dev_name(),因此改成如下形式即可加载成功了。

static int my_match(struct device *dev, struct device_driver *driver)
{
	return !strncmp(dev_name(dev), driver->name, strlen(driver->name));
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值