首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译linux内核模块时未定义的函数

编译linux内核模块时未定义的函数
EN

Stack Overflow用户
提问于 2016-09-25 19:47:36
回答 1查看 3.9K关注 0票数 3

我正在尝试使用linux软件。有一个使用linux/interrupt.h中定义的linux系统调用的简单程序。

代码语言:javascript
复制
//
// Created by kivi on 24.09.16.
//

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/stat.h>

#define SHARED_IRQ 17

static int irq = SHARED_IRQ, my_dev_id, irq_counter = 0;
module_param( irq, int, S_IRUGO );

/* The interrupt handler */ 
static irqreturn_t xxx_interrupt( int irq, void *dev_id ) { 
    printk( KERN_INFO "In the top-half: counter = %d\n", irq_counter );
   raise_softirq( XXX_SOFT_IRQ ); 
   return IRQ_HANDLED; 
}

/* The bottom half */ 
void xxx_analyze(struct softirq_action *str) { 
    irq_counter++;
    printk( KERN_INFO "In the bottom-half: counter = %d\n", irq_counter );
}

static int __init my_init( void ) {
    request_irq( irq, xxx_interrupt, 0, "xxx", NULL );
    open_softirq( XXX_SOFT_IRQ, xxx_analyze); 
    printk( KERN_INFO "Successfully set softirq handler on IRQ %d\n", irq );
    return 0;
}

static void __exit my_exit( void ) {
    synchronize_irq( irq );
    free_irq( irq, &my_dev_id );
    printk( KERN_INFO "Successfully unloading, irq_counter = %d\n", irq_counter );
}

module_init( my_init );
module_exit( my_exit );
MODULE_LICENSE( "GPL v2" );

当我试图编译这个模块时,我得到没有定义open_softirq()raise_softirq()函数的链接器错误:

代码语言:javascript
复制
kivi@kivi-pc:~/sp_labs/irq_exc/softirq$ make
make -C /lib/modules/4.7.5-custom/build M=/home/kivi/sp_labs/irq_exc/softirq modules
make[1]: Entering directory '/home/kivi/Downloads/linux-4.7.5'
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "open_softirq" [/home/kivi/sp_labs/irq_exc/softirq/softirq.ko] undefined!
WARNING: "raise_softirq" [/home/kivi/sp_labs/irq_exc/softirq/softirq.ko] undefined!
make[1]: Leaving directory '/home/kivi/Downloads/linux-4.7.5'

有趣的是函数request_irq() e.t.c。也是在interrupt.h文件中定义的,但它们不会造成任何问题。

这是我的Makefile:

代码语言:javascript
复制
obj-m += softirq.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

有人能帮我解决我的问题吗。

我在谷歌上搜索了我的问题,并找到了一些建议,我在编译时应该添加KBUILD_EXTRA_SYMBOLS=*module path*/Module.symvers,但这并没有帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-26 04:25:54

问题是open_softirqraise_softirq函数没有导出,因此不能链接到它们。导出的函数被标记为EXPORT_SYMBOLEXPORT_SYMBOL_GPL宏。

另一方面,您将看到request_irq是如何导出的(实际上,内嵌request_threaded_irq导出的)。

您可以找到大量有关EXPORT_SYMBOL宏的信息。例如,下面是的一个解释罗伯特洛夫。

现在,您可能想知道为什么不导出这些函数。那么,软内核是一种低级别机制,用于其他高级设施,因此其意图是防止它在非核心内核代码中的使用。

模块应该使用更高级的工具(例如计时器)。

检查内核有多少软has用户很有趣。

代码语言:javascript
复制
$ git grep open_softirq
block/blk-softirq.c:    open_softirq(BLOCK_SOFTIRQ, blk_done_softirq);
include/linux/interrupt.h:extern void open_softirq(int nr, void (*action)(struct softirq_action *));
kernel/rcu/tiny.c:      open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
kernel/rcu/tree.c:      open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
kernel/sched/fair.c:    open_softirq(SCHED_SOFTIRQ, run_rebalance_domains);
kernel/softirq.c:void open_softirq(int nr, void (*action)(struct softirq_action *))
kernel/softirq.c:       open_softirq(TASKLET_SOFTIRQ, tasklet_action);
kernel/softirq.c:       open_softirq(HI_SOFTIRQ, tasklet_hi_action);
kernel/time/timer.c:    open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
lib/irq_poll.c: open_softirq(IRQ_POLL_SOFTIRQ, irq_poll_softirq);
net/core/dev.c: open_softirq(NET_TX_SOFTIRQ, net_tx_action);
net/core/dev.c: open_softirq(NET_RX_SOFTIRQ, net_rx_action);

只有12个!

这种模式在整个内核中重复:维护人员认为低级别的东西并不是导出的,只用于核心内核代码。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39691131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档