总线驱动加载问题:
终端打印出错信息:
# insmod bus.ko
Unable to handle kernel paging request at virtual address e1a0c00d
pgd = c396c000
[e1a0c00d] *pgd=00000000
Internal error: Oops: 3 [#1]
Modules linked in: bus(+)
CPU: 0 Not tainted (2.6.29.4-FriendlyARM #1)
PC is at internal_create_group+0x38/0x1f0
LR is at sysfs_create_group+0x18/0x1c
pc : [<c00cb578>] lr : [<c00cb764>] psr: a0000013
sp : c3983e14 ip : c3983e4c fp : c3983e48
r10: bf000750 r9 : 00000000 r8 : e1a0c00d
r7 : c0429f30 r6 : bf000750 r5 : bf000038 r4 : 00000000
r3 : c3919d20 r2 : e1a0c00d r1 : 00000000 r0 : bf000750
Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: c000717f Table: 3396c000 DAC: 00000015
Process insmod (pid: 478, stack limit = 0xc3982268)
Stack: (0xc3983e14 to 0xc3984000)
3e00: 00000000 bf000750 c3983e58
3e20: 00000000 bf000038 bf000750 c0429f30 00000000 00000000 bf000750 c3983e58
3e40: c3983e4c c00cb764 c00cb550 c3983e78 c3983e5c c0165688 c00cb75c 00000000
3e60: bf00070c bf000774 c0429f30 c3983ec0 c3983e7c c0165d74 c0165654 00000000
3e80: 00000001 c3983ea8 c3983e94 c012e0b0 c012f014 bf00070c bf00070c 000cb070
3ea0: 00000000 c3982000 c002968c bf003000 c03ff260 c3983ed8 c3983ec4 c0166054
3ec0: c0165b68 00000000 000cb070 c3983eec c3983edc bf003044 c0166048 00000f1e
3ee0: c3983f7c c3983ef0 c0028284 bf003010 00000011 00000009 00000000 c0165aa0
3f00: 0000003d 0000003d c009e320 00000002 00000002 c4827850 00000013 00000000
3f20: 00000013 00000013 bf0000ac 00000002 00000000 00000000 00000000 00000000
3f40: 00000000 00000f1e 000cb070 bf000818 00000000 00000f1e 000cb070 bf000818
3f60: 00000000 c002968c c3982000 00900071 c3983fa4 c3983f80 c005e79c c0028258
3f80: ffffffff befe8eac 00000f1e 000ca1b0 000cb050 00000080 00000000 c3983fa8
3fa0: c0028e60 c005e718 000ca1b0 000cb050 00900080 000cb248 00000f1e 000cb070
3fc0: 00000f1e 000ca1b0 000cb050 00000000 000cb060 befe88f8 000c7f7c 00000002
3fe0: befe6f98 befe6f8c 00052354 401b7a00 60000010 00900080 00000000 00000000
Backtrace:
[<c00cb540>] (internal_create_group+0x0/0x1f0) from [<c00cb764>] (sysfs_create_g
roup+0x18/0x1c)
[<c00cb74c>] (sysfs_create_group+0x0/0x1c) from [<c0165688>] (device_add_groups+
0x44/0x94)
[<c0165644>] (device_add_groups+0x0/0x94) from [<c0165d74>] (device_add+0x21c/0x
4e0)
r7:c0429f30 r6:bf000774 r5:bf00070c r4:00000000
[<c0165b58>] (device_add+0x0/0x4e0) from [<c0166054>] (device_register+0x1c/0x20
)
[<c0166038>] (device_register+0x0/0x20) from [<bf003044>] (my_bus_init+0x44/0x74
[bus])
r5:000cb070 r4:00000000
[<bf003000>] (my_bus_init+0x0/0x74 [bus]) from [<c0028284>] (__exception_text_en
d+0x3c/0x1bc)
r4:00000f1e
[<c0028248>] (__exception_text_end+0x0/0x1bc) from [<c005e79c>] (sys_init_module
+0x94/0x1a0)
[<c005e708>] (sys_init_module+0x0/0x1a0) from [<c0028e60>] (ret_fast_syscall+0x0
/0x2c)
r7:00000080 r6:000cb050 r5:000ca1b0 r4:00000f1e
Code: e59a3018 e3530000 03e07015 0a00004f (e5981000)
---[ end trace 28f0769bc03ffed0 ]---
Segmentation fault
删除驱动也无法删
# rmmod bus
rmmod: bus: Device or resource busy
实验源码:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
MODULE_AUTHOR("W");
MODULE_LICENSE("Dual BSD/GPL");
static char *Version = "$Revision: 1.9 $";
static int my_match(struct device *dev, struct device_driver *driver)
{
return !strncmp(dev->bus_id, driver->name, strlen(driver->name));
}
static void my_bus_release(struct device *dev)
{
printk(KERN_DEBUG "my bus release\n");
}
struct device my_bus = {
.bus_id = "my_bus0",
.release = my_bus_release
};
struct bus_type my_bus_type = {
.name = "my_bus",
.match = my_match,
};
EXPORT_SYMBOL(my_bus);
EXPORT_SYMBOL(my_bus_type);
/*
* Export a simple attribute.
*/
static ssize_t show_bus_version(struct bus_type *bus, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", Version);
}
static BUS_ATTR(version, S_IRUGO, show_bus_version, NULL);
static int __init my_bus_init(void)
{
int ret;
/*注册总线*/
ret = bus_register(&my_bus_type);
if (ret)
return ret;
/*创建属性文件*/
if (bus_create_file(&my_bus_type, &bus_attr_version))
printk(KERN_NOTICE "Fail to create version attribute!\n");
/*注册总线设备*/
ret = device_register(&my_bus);
if (ret)
printk(KERN_NOTICE "Fail to register device:my_bus!\n");
return ret;
}
static void my_bus_exit(void)
{
device_unregister(&my_bus);
bus_unregister(&my_bus_type);
}
module_init(my_bus_init);
module_exit(my_bus_exit);