Chinaunix
标题:
请问怎么把Linux 多个C文件编译成一个ko文件呢?(C文件里都有module_init)
[打印本页]
作者:
牡丹岩
时间:
2014-08-26 11:50
标题:
请问怎么把Linux 多个C文件编译成一个ko文件呢?(C文件里都有module_init)
是这样的:我用platform平台总线做驱动,有两个文件:
(1)平台设备led_dev.c
(2)平台驱动led_drv.c
l现在问题是,
led_dev.c中有:
int __init led_dev_init(void)
{
platform_device_register(&led_device);
return 0;
}
module_init(led_dev_init);
led_drv.c中有:
int __init led_drv_init(void)
{
platform_driver_register(&led_driver);
return 0;
}
module_init(led_drv_init);
采用编译成模块时,
Makefile这样写:obj-m += led_dev.o led_drv.o
是可以把led_dev.c编译成led_dev.ko
把led_drv.c编译成led_drv.ko
然后加载时insmod两次就行了!
但现在我想:能不能仅编译成一个ko文件,
加载时只需insmod一次就行了?
为达到此效果,我的Makefile改成这样:
obj-m += led.o
led-objs := led_dev.o led_drv.o
但编译会报错: multiple definition of `init_module'
请问:各位有什么方法呢?不妨赐教啊!小弟谢过~
作者:
lamp_lighter
时间:
2014-08-26 14:32
两个模块如果有关联,可以试试modprobe。要是觉得输入太多insmod麻烦,干脆写个脚本算了
作者:
牡丹岩
时间:
2014-08-26 16:49
谢谢 我的两个模块 有关联的,一个是平台设备,一个平台驱动。你说的写脚本 是指利用脚本去完成多个ko文件的insmod吗?还是编译成一个ko文件呢?
作者:
lamp_lighter
时间:
2014-08-26 17:13
回复
3#
牡丹岩
关联的意思是模块具有依赖性,比如说一个模块会用到另一个模块的函数。modprobe会检查这种依赖性,然后先把依赖的模块的装上,再装其他的模块。脚本就是:
#/bin/bash
insmod **
insmod **
insmod **
*********
然后sudo运行
作者:
牡丹岩
时间:
2014-08-26 17:37
嗯 谢啦。不过 有没有办法 编译成一个ko文件呢?
再问个问题:我insmod 加载驱动模块时,开发板会自动重启,这是为啥啊?
作者:
lamp_lighter
时间:
2014-08-26 17:45
回复
5#
牡丹岩
这我就不知道了,等其他人答吧
作者:
牡丹岩
时间:
2014-08-26 18:24
本帖最后由 牡丹岩 于 2014-08-26 18:27 编辑
写个脚本 效果 还真不错 相见恨晚啊 谢了 !
内核重启时提示错误如下:
kernel bug at kernel/timer.c:662!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
自动重启.png
(82.49 KB, 下载次数: 95)
下载附件
2014-08-26 18:23 上传
作者:
baron_zz
时间:
2014-08-28 10:30
内核遇到空指针时,必然会重启。说明,你的驱动注册过程中,有野指针之类的错误出现。不信你把 platform_device_register(&led_device)和platform_driver_register(&led_driver)注释掉,看看,保证不重启。检查代码错误吧!
作者:
baron_zz
时间:
2014-08-28 10:31
内核重启时提示错误如下:
kernel bug at kernel/timer.c:662!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
另外看你的Log提示, NULL pointer ,分明就是野指针。。再看溢出文件:timer.c:662!,定时器/看门狗退出
所以,检查你的源文件吧
作者:
牡丹岩
时间:
2014-08-28 13:07
本帖最后由 牡丹岩 于 2014-08-28 13:13 编辑
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/gpio.h>
#include <linux/timer.h>
static struct input_dev *p_button_dev = NULL;//定义输入设备
struct timer_list my_timer;//定义定时器
//定义定时器超时处理函数
void timer_func(unsigned long data)
{
int key_value = gpio_get_value(S5PV210_GPH2(0));
//上报事件给input核心层
input_report_key(p_button_dev, KEY_A, !key_value);//按下为1,释放为0
//告诉input子系统上报已经完成
input_sync(p_button_dev);
}
//中断处理函数
static irqreturn_t button_interrupt(int irq, void *dev_id)
{
mod_timer(&my_timer, jiffies + 5);//启动定时器以及设置超时时间
return IRQ_HANDLED;
}
//初始化按钮
static int __init button_init(void)
{
int ret;
ret = gpio_request(S5PV210_GPH2(0), "key2");
if (ret)
{
printk(KERN_ERR "gpio_request Failed to register device\r\n");
goto error1;
}
//为新输入设备分配内存并初始化
p_button_dev = input_allocate_device();
if (!p_button_dev)
{
printk(KERN_ERR "can't allocate input mem!\r\n");
goto error2;
}
p_button_dev->name = "gec_input";
p_button_dev->id.bustype = 0x1;
p_button_dev->id.product = 0x2;
p_button_dev->id.vendor = 0x3;
p_button_dev->id.version = 0x4;
p_button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);
p_button_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);
//注册一个输入设备
ret = input_register_device(p_button_dev);
if (ret)
{
printk(KERN_ERR "Failed to register device\r\n");
goto error3;
}
//申请中断注册中断处理函数
ret = request_irq(IRQ_EINT(16), button_interrupt,
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_DISABLED,
"button", NULL);
if (ret)
{
printk(KERN_ERR "Can't request irq %d\r\n", IRQ_EINT(16));
goto error4;
}
//定时器
init_timer(&my_timer);//初始化定时器
my_timer.function = timer_func;//注册定时器超时处理函数
return 0;
error4:
free_irq(IRQ_EINT(16), NULL);//释放分配给已定中断的内存
input_unregister_device(p_button_dev);
error3:
input_free_device(p_button_dev);
error2:
ret = -ENOMEM;
error1:
gpio_free(S5PV210_GPH2(0));
return ret;
}
static void __exit button_exit(void)
{
gpio_free(S5PV210_GPH2(0));
free_irq(IRQ_EINT(16), NULL);
input_unregister_device(p_button_dev);
del_timer(&my_timer);//删除内核定时器
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_LICENSE("GPL");
复制代码
作者:
chzfmx
时间:
2015-06-07 00:47
回复
1#
牡丹岩
多个.c文件变异成一个.ko文件时,多个.c文件中只能有一个module_init()和module_exit(),不能有多个
作者:
牡丹岩
时间:
2015-06-13 20:12
回复
11#
chzfmx
好的
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2