bierdaci 发表于 2003-9-6 16:09:36

编译一个简单的设备驱动程序模块出错帮我看看

这是Makefile文件

DFLAGS = -D__KERNEL__ -DMODULE -Wall -DLINUX -O2 -o

mydrv.o:        mydrv.c /usr/include/linux/version.h
        gcc$(DFLAGS) -c mydrv.c

clean:
        rm -f *.o
这是源码
#include <linux/kernel.h>
#include <linux/module.h>
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif

#include <linux/fs.h>
#include <linux/wrapper.h>

#include <asm/uaccess.h>

#define DEVICE_NAME "char_dev"
#define BUF_LEN 100
static int Device_Open = 0;
static char Message;
static char *Message_Ptr;
static int Major;

static int device_open(struct inode *inode, struct file *file)
{
        static int counter = 0;
       
        printk("Device: %d.%d\n", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
        if (Device_open)
                return -EBUSY;
        Device_Open++;

        sprintf(Message, "If I told you once, I told you %d times - %s",
                counter++, "Hello, world\n");
        Message_Ptr = Message;
        MOD_INC_USE_COUNT;
        return SUCCESS;
}

static int device_release(struct inode *inode, struct file *file)
{
        Device_Open--;
        MOD_DEC_USE_COUNT;
        return 0;
}

static ssize_t device_read(struct file *file,char *buffer,
                        size_t length, loff_t *offset)
{
        int bytes_read = 0;
        if (*Message_Ptr == 0)
                return 0;
        while (length && *Message_Ptr) {
                copy_to_user(buffer++, *(Message_Ptr++), length--);
                bytes_read++;
        }
        return bytes_read;
}

static ssize_t device_write(struct file *file, const char *buffer,
                        size_t length, loff_t *offset)       
{
        int i;
        copy_from_user(Message, buffer, length);
        Message_Ptr = Message;
        return i;
}

struct file_operations Fops = {
        read:                device_read,
        write:                device_write,
        open:                device_open,
        release:        device_release
};

init init_module()
{
        Major = module_register_chrdev(0, DEVICE_NAME, &Fops);
        if (Major < 0) {
                printk ("%s device failed with %d\n",
                        "Sorry, registering the character",
                        Major);
                return Major;
        }
        printk ("%s The Major device number is %d.\n",
                "Registeration is a success.",
                Major);
        printk("If you want to talk to the device driver,\n");
        printk("you'll have to create a device file.\n");
        printk("We suggest you use:\n");
        printk("mknod <name> c %d <minor>\n", Major);
        printk("You can try different minor numbers %s",
                "and see what happens.\n");
        return 0;
}

void cleanup_module()
{
        int ret;
        ret = module_unregister_chrdev(Major, DEVICE_NAME);
        if (ret < 0)
                printk("Eror in unregister_chrdev: %d\n", ret);
}


下面有出错贴图

Dragonfly 发表于 2003-9-7 01:00:10

try to use this makefile

CC = gcc

CFLAGS:= -O2 -Wall -D__KERNEL__ -DMODULE
INCLUDEDIR = /usr/src/linux/include

CFLAGS += -I$(INCLUDEDIR)

TARGET = hello
OBJS = $(TARGET).o
SRC = $(TARGET).c

all: $(TARGET).o

clean:
      rm -f *.o *~ core

bierdaci 发表于 2003-9-7 21:36:00

好的我回去试一试,只是我没怎么看MAKE语法,CFLAGS += -I$(INCLUDEDIR) 这个是什么意思?

bierdaci 发表于 2003-9-7 21:44:05

我看懂CFLAGS += -I$(INCLUDEDIR) 了,仔细一看就知道是什么意思了,只是all: $(TARGET).o 这句不理解

Dragonfly 发表于 2003-9-8 06:37:42

the important thing is the includedir.

for all... syntax, check make manual. dependency relationship.

bierdaci 发表于 2003-9-10 17:46:02

问题基本上都解决了,主要是加参数-I 后面带源码包含路径,这样编译后warning:implicit declaration of function 'printk'
这句警告也没有了,加载模块也可以正常加载只是那些加载信息(用printk打印的信息)需要在init 1后才能看到,不知道怎么样能在不用init 1就可以看到加载信息。
除了上面的可能还会出现一些问题,因为这两天回家了我是在回家前当天凌晨5点调试那些错误的,下午就坐车回家了,所以还没有来得及调试其它可能出现的问题。不过我编了一个简单的打开设备的程序没能正常工作也没有来得及研究,希望斑主能尽量把一些可能出现的问题帮我写出来,因为回家朋友这里有刻录机我可以多刻些东西回去。

Dragonfly 发表于 2003-9-11 01:32:19

should have no relationship with init 1:?

bierdaci 发表于 2003-9-12 20:45:13

打错了,是int 1

Dragonfly 发表于 2003-9-13 08:39:07

打错了,是int 1

what u mean this "int l"?:?:

bierdaci 发表于 2003-9-13 20:27:06

不对还是init1,还有这个小驱动程序我已经搞定了书上有错误稍微改一下就可以正常运行了

bierdaci 发表于 2003-9-13 20:28:40

告诉我怎么样才能在不用init 1就能在init 5下看到insmod 的模块加载信息?

Dragonfly 发表于 2003-9-13 23:04:36

no idea why u can not see it from init 5.
u can check the printk usage from LDD, try to adjust the different log level, and check the dmesg -n with different level. and check if u klogd is there.
页: [1]
查看完整版本: 编译一个简单的设备驱动程序模块出错帮我看看