我尝试从我学习的 Linux 驱动程序书中运行一个示例程序。
但是它崩溃了,我不知道为什么。
是否有可能控制 DEVICE_ATTR 宏?因为也许有问题。
这是我的代码:
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#define DRIVER_MAJOR 240
static struct file_operations fops;
static DECLARE_COMPLETION( dev_obj_is_free );
static int frequenz;
static void mydevice_release( struct device *dev )
struct platform_device mydevice = {
.name = "MyDevice",
.id = 0,
.dev = {
.release = mydevice_release,
}
};
static struct device_driver mydriver = {
.name = "MyDevice",
.bus = &platform_bus_type,
};
static ssize_t read_freq( struct device *dev, struct device_attribute *attr,
char *buf )
{
snprintf(buf, 256, "frequenz: %d", frequenz );
return strlen(buf)+1;
}
static ssize_t write_freq( struct device *dev, struct device_attribute *attr,
const char *buf, size_t count )
{
frequenz = simple_strtoul( buf, NULL, 0 );
return strlen(buf)+1;
}
static DEVICE_ATTR( freq ,S_IRUGO|S_IWUGO, read_freq, write_freq );
static int __init drv_init(void)
{
if(register_chrdev(DRIVER_MAJOR, "MyDevice", &fops) == 0) {
driver_register(&mydriver); // register the driver
platform_device_register( &mydevice );// register the device
mydevice.dev.driver = &mydriver; // now tie them together
device_bind_driver( &mydevice.dev ); // links the driver to the device
device_create_file( &mydevice.dev, &dev_attr_freq );
return 0;
}
return -EIO;
}
static void __exit drv_exit(void)
{
device_remove_file( &mydevice.dev, &dev_attr_freq );
device_release_driver( &mydevice.dev );
platform_device_unregister( &mydevice );
driver_unregister(&mydriver);
unregister_chrdev(DRIVER_MAJOR,"MyDevice");
wait_for_completion( &dev_obj_is_free );
}
module_init( drv_init );
module_exit( drv_exit );
MODULE_LICENSE("GPL");
这是糟糕的消息:
Unable to handle kernel paging request for data at address 0x00000001
Faulting instruction address: 0xc01661b0
Oops: Kernel access of bad area, sig: 11 [#1]
SBC8548
last sysfs file:
Modules linked in: temp(+)
NIP: c01661b0 LR: c0166194 CTR: c0166170
REGS: cf8a3d50 TRAP: 0300 Not tainted (2.6.36)
MSR: 00029000 <EE,ME,CE> CR: 84000424 XER: 00000000
DEAR: 00000001, ESR: 00000000
TASK = cf9fd240[994] 'insmod' THREAD: cf8a2000
GPR00: c0166194 cf8a3e00 cf9fd240 00000001 c02ca2c8 00000000 c0164cdc 00000020
GPR08: 000003c0 c02d3298 00001386 cf81f940 84000442 1004950c 00000240 00000000
GPR16: 10103980 1009ea94 100f0000 100f7ac8 00000000 101039a8 101052b8 bfd6ecc8
GPR24: c02e0000 c02d3140 00000000 cfafc540 c02ca2c0 d102b2f8 c02ca2c8 00000001
NIP [c01661b0] platform_match+0x40/0xcc
LR [c0166194] platform_match+0x24/0xcc
Call Trace:
[cf8a3e00] [c0166194] platform_match+0x24/0xcc (unreliable)
[cf8a3e20] [c0164d0c] __driver_attach+0x30/0xa8
[cf8a3e40] [c0163bb0] bus_for_each_dev+0x60/0x9c
[cf8a3e70] [c01647b4] driver_attach+0x24/0x34
[cf8a3e80] [c0164444] bus_add_driver+0xb8/0x274
[cf8a3eb0] [c0164fe4] driver_register+0x70/0x168
[cf8a3ed0] [d102e058] drv_init+0x58/0xe0 [temp]
[cf8a3ef0] [c0001ef8] do_one_initcall+0x16c/0x1b8
[cf8a3f20] [c005ff8c] sys_init_module+0xd4/0x1e4
[cf8a3f40] [c000dae0] ret_from_syscall+0x0/0x3c
--- Exception: c01 at 0xff3b388
LR = 0x10000dbc
Instruction dump:
90010024 7c9d2378 80640014 7fc4f378 48017051 2f830000 38600001 409e005c
83fd0038 3b9efff8 2f9f0000 419e0078 <881f0000> 2f800000 419e0054 83defff8
---[ end trace 2c20538ad6d3f6d6 ]---
Segmentation fault
-bash-3.2#
Message from syslogd@ at Thu Jan 1 01:00:11 1970 ...