免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2123 | 回复: 0
打印 上一主题 下一主题

[Linux] 加载驱动程序出错Unknown symbol [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-05-03 14:57 |只看该作者 |倒序浏览
我在主机编译一个驱动。编译过程没有出错。代码如下:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <asm/gptimers.h>
#include <asm/irq.h>
#include <asm/bfin_simple_timer.h>
#include <asm/bfin-global.h>

#define AUTHOR "Axel Weiss (awe@aglaia-gmbh.de)"
#define DESCRIPTION "simple timer char-device interface for the bf5xx_timers driver"
#define LICENSE "GPL"
#define TIMER_MAJOR 238

#define DPRINTK(fmt, args...) printk(KERN_NOTICE "%s: " fmt, __FUNCTION__ , ## args)
#define DRV_NAME            "bfin_simple_timer"

MODULE_AUTHOR     (AUTHOR);
MODULE_DESCRIPTION(DESCRIPTION);
MODULE_LICENSE    (LICENSE);

#if defined(BF533_FAMILY) || defined(BF537_FAMILY)
#define IRQ_TIMER0    IRQ_TMR0         /*Timer 0 */
#define IRQ_TIMER1    IRQ_TMR1         /*Timer 1 */
#define IRQ_TIMER2    IRQ_TMR2         /*Timer 2 */
#if (MAX_BLACKFIN_GPTIMERS > 3)
#define IRQ_TIMER3    IRQ_TMR3         /*Timer 3 */
#define IRQ_TIMER4    IRQ_TMR4         /*Timer 4 */
#define IRQ_TIMER5    IRQ_TMR5         /*Timer 5 */
#define IRQ_TIMER6    IRQ_TMR6         /*Timer 6 */
#define IRQ_TIMER7    IRQ_TMR7         /*Timer 7 */
#endif
#endif

static unsigned long sysclk = 0;
module_param(sysclk, long, 0);
MODULE_PARM_DESC(sysclk, "actual SYSCLK frequency in Hz. Default: 120000000 = 120 MHz.";

static volatile unsigned long isr_count[MAX_BLACKFIN_GPTIMERS];
static const struct {
        unsigned short id, bit;
        unsigned long irqbit;
        int irq;
} timer_code[MAX_BLACKFIN_GPTIMERS] = {
        {TIMER0_id,  TIMER0bit,  TIMER_STATUS_TIMIL0,  IRQ_TIMER0},
        {TIMER1_id,  TIMER1bit,  TIMER_STATUS_TIMIL1,  IRQ_TIMER1},
        {TIMER2_id,  TIMER2bit,  TIMER_STATUS_TIMIL2,  IRQ_TIMER2},
#if (MAX_BLACKFIN_GPTIMERS > 3)
        {TIMER3_id,  TIMER3bit,  TIMER_STATUS_TIMIL3,  IRQ_TIMER3},
        {TIMER4_id,  TIMER4bit,  TIMER_STATUS_TIMIL4,  IRQ_TIMER4},
        {TIMER5_id,  TIMER5bit,  TIMER_STATUS_TIMIL5,  IRQ_TIMER5},
        {TIMER6_id,  TIMER6bit,  TIMER_STATUS_TIMIL6,  IRQ_TIMER6},
        {TIMER7_id,  TIMER7bit,  TIMER_STATUS_TIMIL7,  IRQ_TIMER7},
#endif
#if (MAX_BLACKFIN_GPTIMERS >
        {TIMER8_id,  TIMER8bit,  TIMER_STATUS_TIMIL8,  IRQ_TIMER8},
        {TIMER9_id,  TIMER9bit,  TIMER_STATUS_TIMIL9,  IRQ_TIMER9},
        {TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10},
        {TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11},
#endif
};

static int timer_ioctl(struct inode *inode, struct file *filp, uint cmd, unsigned long arg){
        int minor = MINOR(inode->i_rdev);
        unsigned long n;
        switch (cmd){
        case BFIN_SIMPLE_TIMER_SET_PERIOD:
                if (arg < 2) return -EFAULT;
                n = ((sysclk / 1000) * arg) / 1000;
                if (n > 0xFFFF) n = 0xFFFF;
                set_gptimer_period(timer_code[minor].id, n);
                set_gptimer_pwidth(timer_code[minor].id, n >> 1);
                printk("timer_ioctl TIMER_SET_PERIOD: arg=%lu, period=%lu, width=%lu\n",
                        arg, n, n>>1);
                break;
        case BFIN_SIMPLE_TIMER_START:
                enable_gptimers(timer_code[minor].bit);
                break;
        case BFIN_SIMPLE_TIMER_STOP:
                disable_gptimers(timer_code[minor].bit);
                break;
        case BFIN_SIMPLE_TIMER_READ:
                *((unsigned long*)arg) = isr_count[minor];
                break;
        default:
                return -EINVAL;
        }
        return 0;
}

static irqreturn_t timer_isr(int irq, void *dev_id)
{
        int minor = (int)dev_id;
#if (MAX_BLACKFIN_GPTIMERS >
        int octet = BFIN_TIMER_OCTET(minor);
        unsigned long state = get_gptimer_status(octet);
        if (state & timer_code[minor].irqbit){
                set_gptimer_status(octet, timer_code[minor].irqbit);
                ++isr_count[minor];
        }
#else
        unsigned long state = get_gptimer_status(0);
        if (state & timer_code[minor].irqbit){
                set_gptimer_status(0,timer_code[minor].irqbit);
                ++isr_count[minor];
        }
#endif
        return IRQ_HANDLED;
}

static int timer_open(struct inode *inode, struct file *filp){
        int minor = MINOR(inode->i_rdev);
        int err = 0;
        if(!sysclk)
          sysclk = get_sclk();
        if (minor >= MAX_BLACKFIN_GPTIMERS) return -ENODEV;
        err = request_irq(timer_code[minor].irq, timer_isr, IRQF_DISABLED, DRV_NAME, (void *)minor);
        if (err < 0){
                printk(KERN_ERR "request_irq(%d) failed\n", timer_code[minor].irq);
                return err;
        }
        set_gptimer_config(timer_code[minor].id, OUT_DIS | PWM_OUT | PERIOD_CNT | IRQ_ENA);
        DPRINTK("device(%d) opened\n", minor);
        return 0;
}

static int timer_close(struct inode *inode, struct file *filp){
        int minor = MINOR(inode->i_rdev);
        disable_gptimers(timer_code[minor].bit);
        free_irq(timer_code[minor].irq, (void*)minor);
        DPRINTK("device(%d) closed\n", minor);
        return 0;
}

int timer_read_proc(char *buf, char **start, off_t offset, int cnt, int *eof, void *data){
        int ret = 0, i;
        for (i=0; i<MAX_BLACKFIN_GPTIMERS; ++i){
                ret += sprintf(buf + ret, "timer %2d isr count: %lu\n", i, isr_count);
        }
        return ret;
}

static ssize_t timer_status_show(struct class *timer_class, char *buf)
{
        char *p;
        unsigned short i;
        p = buf;

        for (i=0; i<MAX_BLACKFIN_GPTIMERS; ++i){
                p += sprintf(p, "timer %2d isr count: %lu\n", i, isr_count);
        }

        return p - buf;
}

static struct proc_dir_entry *timer_dir_entry;
static struct file_operations fops = {
   .owner   = THIS_MODULE,
   .ioctl   = timer_ioctl,
   .open    = timer_open,
   .release = timer_close,
};

static struct class *timer_class;

static CLASS_ATTR(status, S_IRUGO, &timer_status_show, NULL);

int __init timer_initialize(void){
        int minor;
        char minor_name[8];
        int err;
        err = register_chrdev(TIMER_MAJOR, DRV_NAME, &fops);
        if (err < 0){
                DPRINTK("could not register device %s\n", DRV_NAME);
                return err;
        }
        timer_dir_entry = create_proc_entry(DRV_NAME, 0444, &proc_root);
        if (timer_dir_entry) timer_dir_entry->read_proc = &timer_read_proc;

        timer_class = class_create(THIS_MODULE, "timer";
        if ((err = class_create_file(timer_class, &class_attr_status)) != 0) {
                remove_proc_entry(DRV_NAME, &proc_root);
                unregister_chrdev(TIMER_MAJOR, DRV_NAME);
                return err;
        }
        for (minor = 0; minor < MAX_BLACKFIN_GPTIMERS; minor++) {
                sprintf(minor_name, "timer%d", minor);
                device_create(timer_class, NULL,
                              MKDEV(TIMER_MAJOR, minor), minor_name);
        }
       
        DPRINTK("module loaded\n";
        return 0;
}

void __exit timer_cleanup(void){
        remove_proc_entry(DRV_NAME, &proc_root);
        unregister_chrdev(TIMER_MAJOR, DRV_NAME);
        DPRINTK("module unloaded\n";
}

module_init(timer_initialize);
module_exit(timer_cleanup);


但是当在目标板加载的时候就出现错误了:insmod: cannot insert 'drive.ko': Unknown symbol in module (-1): No such file or directory
通过查找log ,我看到如下的提示:
Jan  1 04:15:31 lean user.warn kernel: pwm: Unknown symbol _enable_gptimers
Jan  1 04:15:31 lean user.warn kernel: pwm: Unknown symbol _get_gptimer_status
Jan  1 04:15:31 lean user.warn kernel: pwm: Unknown symbol _disable_gptimers
Jan  1 04:15:31 lean user.warn kernel: pwm: Unknown symbol _set_gptimer_pwidth
Jan  1 04:15:31 lean user.warn kernel: pwm: Unknown symbol _set_gptimer_config
Jan  1 04:15:31 lean user.warn kernel: pwm: Unknown symbol _set_gptimer_status
Jan  1 04:15:31 lean user.warn kernel: pwm: Unknown symbol _set_gptimer_period

请教是什么原因呢》
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP