字符设备驱动程序 之 使用&分析

insmod: error inserting 'main.ko': -1 Unknown symbol in module


ldd3第三章的字符设备驱动是在2.6.10内核上写的,如果要在更高的版本上使用,则编译和使用都需要进行修改。

关于编译方面进行的修改,网上相关的很多,自己也可以根据自己的进行修改。

1、在书上配套的代码中,动态加载主设备的设备驱动程序,使用了一个脚本,该脚本在自己的系统中不能正常使用,提示mknod 命令错误,

该问题留待进行解决。

2、自己用命令的方式如下:

读取  /proc/devices 获得新分配的设备号。

mknod  /dev/scull0 c 250 0  创建相应的设备文件。

注意修改设备 文件的访问权限 chmod 0+w  /dev/scull   否则,只有超级用户才可以进行访问该设备文件。

然后就可以对该设备文件,进行相应的测试了。

3、关于SCULL内存使用

图表可以见书65页。 注意每个设备都是一个指针链表,scull_qset 结构中(每一个这样的结构可以引用4 000 000 bytes),4 000 000 = 1 000(量子集) * 4 000(量子)

对这种设备布局的理解是读懂程序的关键。而读懂程序,scull_read 中的一段更具代表性。

ssize_t scull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)

{

    struct scull_dev *dev = filp->private_data;

    struct scull_qset *dptr;    / * the first listitem (listitem prefers to scull_qset)* /

    int quantum  = dev->quantum, qset = dev->qset;

    int itemsize = quantum * qset; / * how many bytes in the listitem * /

    int item, s_pos, q_pos, rest;

    ssize_t retval = 0;

    if (down_interruptible(&dev->sem))

    {

        return -ERESTARTSYS;

    }

    if (*f_pos >= dev->size)

    {

        goto out;

    }

    if (*f_pos + count > dev->size)

    {

        count = dev->size - *f_pos;

    }

    / * find listitem, qset index, and offset in the quantum * /

    item  = (long)*f_pos / itemsize;    //定位要读取的数据在那个scull_qset

    rest  = (long)*f_pos % itemsize;    //定位要读取的数据scull_qset中的偏移量,是中间变量。

    s_pos = rest / quantum;             //定位要读取的数据在哪个quantum

    q_pos = rest % quantum;             //定位要读取的数据在quantum中的偏移量

    / * follow the list up to the right position (defined elsewhere) * /

    dptr = scull_follow(dev, item);

    if ((dptr == NULL) || !dptr->data || !dptr->data[s_pos])

    {

        goto out;

    }             / * don't fill holes * /

    / * read only up to the end of this quantum * / 

    / * 该函数一次只读取一个的quantum,跨quantum的数据不能全部读取* /

    if (count > quantum - q_pos)

    {

        count = quantum - q_pos;

    }

/ *

Function copy_to_user and copy_from_user copy a whole segment of data to or from 

the user address space. 

* /

    if (copy_to_user(buf, dptr->data[s_pos] + q_pos, count))

    {

        retval = -EFAULT;

        goto out;

    }

    *f_pos += count;

    retval = count;

out:

    up(&dev->sem);

    return retval;

}

4、为了对程序有更好的理解,要自己重新 对程序进行修改,加上打印信息。
然后,我把main.c和 那个头文件拷贝到其他的目录下,自己写的Makefiel,编译可以通过,但是在 插入模块时,发生下面的错误:

insmod: error inserting 'main.ko': -1 Unknown symbol in module

在网上说,内核中使用了以前内核是用的宏之类的东西。

可以使用 日志文件来查看错误信息 : /var/log/message

Apr  8 15:46:20 ubuntu kernel: [21786.371081] main: Unknown symbol scull_access_cleanup (err 0)


所以,问题是 scull_access_cleanup()在另一文件中国定义。

所以,把scull文件夹里的代码全部拷贝了过来,

注意要重新修改Makefile了。

KVER = $(shell uname -r)

scull-objs := main.o pipe.o access.o

obj-m	:= scull.o

kernel_modules:
	 make -C /lib/modules/$(KVER)/build  M=$(PWD) modules

clean:
	 make -C /lib/modules/$(KVER)/build  M=$(PWD) clean

在插入模块后,查看 日志文件的打印信息入下:

Apr  8 16:01:53 ubuntu kernel: [22716.931129] scullsingle registered at fa00008
Apr  8 16:01:53 ubuntu kernel: [22716.931149] sculluid registered at fa00009
Apr  8 16:01:53 ubuntu kernel: [22716.931152] scullwuid registered at fa0000a
Apr  8 16:01:53 ubuntu kernel: [22716.931154] sullpriv registered at fa0000b


小知识:如何删除在 /dev目录下的一个设备节点。

sudo rm /dev/scu_dev
root@ubuntu:/home/wangkai/Documents/test# sudo chmod o+w /dev/scull0   
上面这个一定要注意啊。。
为了调试,可以在代码中,加上自己的一下诶调试信息,
 
 

在函数 scull_write()的入口加上下面的调试信息:

printk("Debug by wang_kai:scull_write\n");


然后,想设备写内容。 打开   /vzr/log/message 后,就可以看到调试信息了

Apr  8 16:17:38 ubuntu kernel: [23659.823762] Debug by wang_kai:scull_write

 

但是,一直不能在日志文件中,看到打印信息。原因在于,我是这样添加的:

printk(KERN_ALERT "Debug by wang_kai :scull_init_nodule\n");

加上了,KERN_ALERT.,不能显示。     原因不知道,留有以后分析。

 





 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值