内核加载错误linux,linux - 插入我的内核模块时,INSMOD退出,错误为“地址错误”,并警告“内核不匹配” - 堆栈内存溢出...

我正在为自定义设备开发此模块,实际上,该模块是将4 * 8位io端口连接到地址为0x0120-0x0123的ISA总线的。 该驱动程序基于Alessandro Rubini和Jonathan Corbet的“ scull”。 我的操作系统是Ubuntu 10.04,内核是2.6.32-74,我使用面向控制台的内置编译器gcc。 使用“ insmod”插入已编译模块时,出现错误“错误地址”,并且模块未加载。 我尝试使用“ printk”对其进行调试,发现我的模块成功获取了一系列io端口,主数字和次数字,然后,当尝试执行“ Reset_Port”功能时,它将生成错误“错误地址”并退出。

谁能告诉我,我在做什么错?

这是我模块的__exit和__init函数

void __exit ET3201_exit(void)

{

int i;

dev_t devno = MKDEV(ET3201_major, ET3201_minor);

/* Get rid of our char dev entries */

if (ET3201_devices) {

for (i = 0; i < ET3201_nr_devs; i++) {

ET3201_trim(ET3201_devices + i);

cdev_del(&ET3201_devices[i].cdev);

}

kfree(ET3201_devices);

}

#ifdef ET3201_DEBUG /* use proc only if debugging */

ET3201_remove_proc();

#endif

/* cleanup_module is never called if registering failed */

unregister_chrdev_region(devno, ET3201_nr_devs);

if ( ! port ) release_region(BaseIO, 8);

printk(KERN_INFO "Goodbye, cruel world - ET3201 is unloaded\n");

/* and call the cleanup functions for friend devices */

/*ET3201_access_cleanup();*/

}

/*----------------------------------------------------------------------------*/

/* Set up the char_dev structure for this device. */

static void ET3201_setup_cdev(struct ET3201_dev *dev, int index)

{

int err, devno = MKDEV(ET3201_major, ET3201_minor + index);

cdev_init(&dev->cdev, &ET3201_fops);

dev->cdev.owner = THIS_MODULE;

dev->cdev.ops = &ET3201_fops;

dev->CAMAC_Module_Number = CAMAC_Nmod;

dev->CAMAC_Command_Adress = CAMAC_Adcom;

dev->Driver_Number = ET3201_minor + index;

err = cdev_add (&dev->cdev, devno, 1);

/* Fail gracefully if need be */

if (err)

printk(KERN_NOTICE "Error %d adding ET3201%d", err, index);

}

/*----------------------------------------------------------------------------*/

int __init ET3201_init(void)

{

int result = 0;

int i;

dev_t dev = 0;

BaseIO = Base;

/* Get a range of minor numbers to work with, asking for a dynamic

major unless directed otherwise at load time. */

if (ET3201_major) {

dev = MKDEV(ET3201_major, ET3201_minor);

result = register_chrdev_region(dev, ET3201_nr_devs, "ET3201");

} else {

result = alloc_chrdev_region(&dev, ET3201_minor, ET3201_nr_devs, "ET3201");

ET3201_major = MAJOR(dev);

}

if (result < 0) {

printk(KERN_WARNING "ET3201: can't get major %d\n", ET3201_major);

return result;

}

port = request_region(BaseIO, 8, "ET3201");

if ( port == NULL ) {

printk(KERN_WARNING "ET3201 cannot reserve i-o ports %lu \n", BaseIO);

return -ENODEV;

goto fail;

}

/*

* allocate the devices -- we can't have them static, as the number

* can be specified at load time

*/

ET3201_devices = kmalloc(ET3201_nr_devs * sizeof(struct ET3201_dev), GFP_KERNEL);

if (! ET3201_devices) {

result = -ENOMEM;

printk(KERN_ALERT "ET3201: can't get memory \n");

goto fail; /* Fail gracefully if need be */

}

memset(ET3201_devices, 0, ET3201_nr_devs * sizeof(struct ET3201_dev));

/* Initialize each device. */

for (i = 0; i < ET3201_nr_devs; i++) {

ET3201_devices[i].quantum = ET3201_quantum;

ET3201_devices[i].qset = ET3201_qset;

init_MUTEX(&ET3201_devices[i].sem);

ET3201_setup_cdev(&ET3201_devices[i], i);

}

/* At this point call the init function for any friend device */

dev = MKDEV(ET3201_major, ET3201_minor + ET3201_nr_devs);

/*dev += ET3201_access_init(dev);*/

printk(KERN_INFO "ET3201 is initialized with major %d\n", ET3201_major);

if ( port != NULL ){

printk(KERN_INFO "ET3201 is trying to reset %d devices\n", ET3201_nr_devs);

result = Reset_Port();

}

if ( result != 0 ) {

printk(KERN_ALERT "ET3201: device cannot reset with result %d\n", result);

result = -EFAULT;

goto fail;

}

#ifdef ET3201_DEBUG /* only when debugging */

ET3201_create_proc();

#endif

return 0; /* succeed */

fail:

ET3201_exit();

return result;

}

/*----------------------------------------------------------------------------*/

module_init(ET3201_init);

module_exit(ET3201_exit);

MODULE_LICENSE("GPL");

MODULE_ALIAS_MISCDEV(ET3201_minor);

接下来是Reset_Port()

static int Reset_Port(void)

{

int result = -EIO;

int count;

if (port == NULL) goto fail;

for ( count = 0; count < ET3201_nr_devs; count++ )

{

outb(0x00, ports[count]);

}

wmb(); /*write memory barrier*/

LastOp = E_Reset;

result = 0; /* success */

fail:

return result;

}

EXPORT_SYMBOL(Reset_Port);

现在,修复“ int Reset_Port(void)”后,我遇到了另一个问题-

“警告:modpost:发现1个部分不匹配。” 调试后,我看到这是从“ module_init()”调用“ ET3201_exit()”的结果-当我标记此调用时,警告消失了。 令人惊讶的是,在受尊敬的作者的“ scull”驱动程序中进行了完全相同的调用-并且它起作用。 问题:什么会导致此代码中的内核不匹配?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值