第一个字符驱动,我不想要他夭折,大家帮帮我吧~

sakuragirl   2009-4-19 20:18 楼主
用makefile(linux程序设计的)
说有2个错误

用gcc,错误一大片:
[root@ForATIW Drivers]# gcc -c simple_chrdev.c
simple_chrdev.c:8:26: error: linux/module.h: No such file or directory
simple_chrdev.c:9:24: error: linux/init.h: No such file or directory
simple_chrdev.c:10:24: error: linux/cdev.h: No such file or directory
simple_chrdev.c:16: error: expected declaration specifiers or ‘...’ before string constant
simple_chrdev.c:16: warning: data definition has no type or storage class
simple_chrdev.c:17: error: expected declaration specifiers or ‘...’ before string constant
。。。。。。。。。。。。。。。。。。。

源码:
书上的例子!

#include
#include
#include
#include
#include
#include
//#include
#define _NO_VERSION_

MODULE_AUTHOR("For_ATIW");
MODULE_DESCRIPTION("SIMPLE Character");
MODULE_LICENSE("GPL");

#define CDRIVER_NAME "Simple_chrdev"

int CDRIVER_MAJOR = 0;
int CDRIVER_MINOR = 0;
int count =1;        //one device

//file operations funcs

//函数名:simple_llseek
//参数:flip, file指针用于指名当前文件,loff_t 一个长的偏移量32和64位的数据宽度,int
//功能: 修改文档的当前读写位置
//返回值:正值,新位置file结构中的位置计算器的值,负值,出错
loff_t simple_llseek(struct file *filp, loff_t off, int whence);

//函数名:simple_ioctl
//参数:inode* 文件索引结点指针,file 文件 ,int命令,long 命令的参数
//功能:执行设备特定的命令(eg:格式化软盘的某个磁道,既不读,也不写)
//返回值:非负调用成功,将值返回给调用程序以表示调用成功
int simple_ioctl(struct inode *inode,struct file *filp ,unsigned int cmd, unsigned long arg);

//函数名:simple_open
//参数:inode 文件索引结点,file* 文件指针
//功能:打开文件
//返回值:成功为0 ,失败为非0
int simple_open(struct inode *inode , struct file *filp );

//函数名:simple_relese
//参数:inode 文件索引结点,file* 文件指针
//功能:打开文件
//返回值:成功为0 ,失败为非0
int simple_release(struct inode *inode , struct file *flip);

extern struct file_operations simple_fops;

struct cdev *simple_cdev;
dev_t simple_dev;

struct file_operations simple_fops=
        {
        .owner =THIS_MODULE,
        .llseek=simple_llseek,
        .open  =simple_open,
        .release=simple_release,
        };

/******************************************************/
/*name:simple_llseek          */
/*                            */
loff_t simple_llseek(struct file* filp,loff_t off, int whence)
{
        //Do....
        return 0;
}

/*****************************************************/
/***                                                ******/
int simple_open(struct inode *inode ,struct file *flip)
{
        printk("simple Device is opened \n");
        try_module_get(THIS_MODULE);
        return 0;
}

/****************************************************/
/**release                                        ***/
int simple_release(struct inode *inode ,struct file *filp)
{
        printk("simple device is released!\n");
        module_put(THIS_MODULE);
        return 0;
}

/****************************************************/
/**init                                          ***/
static int __init simple_init(void)
{
        int result;
        //register major and the minor
        if(CDRIVER_MAJOR)
        {
                simple_dev=MKDEV(CDRIVER_MAJOR,CDRIVER_MINOR);
                result=register_chrdev_region(simple_dev,count,CDRIVER_NAME);               
        }
        else
        {
        //dynamic assgin major
                result=alloc_chrdev_region(&simple_dev,CDRIVER_MINOR,count,CDRIVER_NAME);
                CDRIVER_MAJOR=MAJOR(simple_dev);
        }
        if(result<0)
        {
                printk(KERN_ERR"Cannot get major %d!\n",CDRIVER_MAJOR );
                return -1;
        }
       
        //register char device driver
        simple_dev=cdev_alloc();
        if(simple_dev!=NULL)
        {
                cdev_init(simple_cdev,&simple_fops);
                simple_cdev->ops=&simple_fops;
                simple_cdev->owner=THIS_MODULE;
                if(cdev_add(simple_cdev,simple_dev,count))
                        printk(KERN_NOTICE"Someting wrong when adding simple_cdev!\n");
                else
                        printk("Success adding simple_cdev!\n");
        }
        else
        {
                printk(KERN_ERR"Register simple_dev error!\n");
                return -1;
        }
        return 0;
}

static void __exit simple_exit(void)
{
        printk("Unloading simple_cdev now..\n");
        cdev_del(simple_cdev);
        unregister_chrdev_region(simple_dev,count);
}

module_init(simple_init);                //内核模块入口,相当于main()函数
module_exit(simple_exit);                //内核模块出口,用于卸载


Makefile也贴出来吧!
#·???±ê×???Makefile???????????????????????à??????
#???????????ò??????proc????????????????×?·?±?????????????????proc????????????????·?·???????
#/proc/scullmem
#??·?·? /proc/scullseq
DEBUG = y       


# Add your debugging flag (or not) to CFLAGS
ifeq ($(DEBUG),y)
  DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
else
  DEBFLAGS = -O2
endif

CFLAGS += $(DEBFLAGS)
CFLAGS += -I$(LDDINC)

ifneq ($(KERNELRELEASE),)
# call from kernel build system

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

obj-m        := simple_chrdev.o

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules

endif



clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

depend .depend dep:
        $(CC) $(CFLAGS) -M *.c > .depend


ifeq (.depend,$(wildcard .depend))
include .depend
endif


同志们~谢谢了。。我/usr/src/kernel/.../include 下面灭有那几个文件,我重其他地方拷了过去的~~还是不行。。

回复评论 (7)

贴的 Makefile 看不清楚,不过貌似有问题啊...
1、最好的办法就是你先配置并编译一下核心,在核心及模块均编译成功的情况下,再来编译你的程序,
   另外最好将你写的驱动 simple_chrdev.c 链接到核心的 driver/char 目录下,修改一下其 Makefile,
   加上一条编译规则使其能够编译 simple_chrdev.c
2、如果要手工命令行编译 simple_chrdev.c,那么就先用
[code]
   看看在你的系统中它编译的命令行 gcc 带了哪些参数,就用那些参数,将其 .c 文件换成你的 simple_chrdev.c,其 .o 文件换成你的 simple_chrdev.o 或者 simple_chrdev.ko

其命令行参数比较多,你可以看看,例如:
  gcc -Wp,-MD,drivers/acpi/acpica/.nsinit.o.d  -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/4.3.2/include -Iinclude  -I/root/linux-2.6.29/arch/x86/include -include include/linux/autoconf.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -m32 -msoft-float -mregparm=3 -freg-struct-return -mpreferred-stack-boundary=2 -march=i686 -mtune=generic -Wa,-mtune=generic32 -ffreestanding -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iarch/x86/include/asm/mach-default -fno-stack-protector -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pg -Wdeclaration-after-statement -Wno-pointer-sign -fwrapv -Os -DACPI_DEBUG_OUTPUT  -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(nsinit)"  -D"KBUILD_MODNAME=KBUILD_STR(nsinit)" -D"DEBUG_HASH=53" -D"DEBUG_HASH2=2" -c -o drivers/acpi/acpica/.tmp_nsinit.o drivers/acpi/acpica/nsinit.c
点赞  2009-4-19 21:06

  1. [root@bache char]# pwd
  2. /root/linux-2.6.29/drivers/char
  3. [root@bache char]# make -C ../../ -f Makefile drivers/char/
  4. make: Entering directory `/root/linux-2.6.29'
  5.   CHK     include/linux/version.h
  6.   CHK     include/linux/utsrelease.h
  7.   SYMLINK include/asm -> include/asm-x86
  8.   CALL    scripts/checksyscalls.sh
  9.   CC      drivers/char/misc.o
  10.   CC      drivers/char/vt_ioctl.o
  11.   CC      drivers/char/vc_screen.o
  12.   CC      drivers/char/selection.o
  13.   CC      drivers/char/keyboard.o
  14.   CC      drivers/char/consolemap.o
  15.   CONMK   drivers/char/consolemap_deftbl.c
  16.   CC      drivers/char/consolemap_deftbl.o
  17.   CC      drivers/char/vt.o
  18.   SHIPPED drivers/char/defkeymap.c
  19.   CC      drivers/char/defkeymap.o
  20.   CC      drivers/char/tty_audit.o
  21.   CC      drivers/char/sysrq.o
  22.   CC      drivers/char/rocket.o
点赞  2009-4-19 21:20
谢谢一楼!
。。。。
不过

第二个看不大懂额。。

第一个,要不我去重新编译一下内核,然后

另外最好将你写的驱动 simple_chrdev.c 链接到核心的 driver/char 目录下,修改一下其 Makefile,
  加上一条编译规则使其能够编译 simple_chrdev.c

这个如何实现链接到目录呢~
点赞  2009-4-19 21:52
ln 命令可以做符号链接,当然你也可以将 simple_chrdev.c 拷贝到 drivers/char/ 目录下。
貌似:

ln -s simple_chrdev.c /usr/src/linux-2.6.x/drivers/char/simple_chrdev.c

具体你可以查 man ln 即可!
点赞  2009-4-19 21:57
up









-----------------------------
分享视频赚钱
点赞  2009-4-20 23:43

非常感谢你们在我的帖子中点拨愚人,呵呵。。
在帖子中你说最好是重新编译一下内核,我也赞同你的观点,因为我发现我的系统fedora10(2.6.27)中没有你上面显示的那些文件夹,比如:/usr/src/linux-2.6.27。。。我的目录内容/usr/src/kernel。。里面全是makefile。。没有源代码。。。
就是想写驱动,ldd书里面的makefile中用到的路径KERNELDIR ?= /lib/modules/$(shell uname -r)/build 也没有。。

所以我下了2.6.29的源码包。。重新编译了内核。。
结果我的磁盘满了。。

现在想写驱动。。能有其他解决方案吗。。除了,重新分区,重装系统,


我很想写驱动。。就是被这些环境限制了。。

大哥们帮帮忙阿~
点赞  2009-4-25 11:19
不用重新编译内核吧?应该是你内核的路径没设置好,头文件都找不到。

用虚拟机的吗?如果是是可以用工具改大的。
点赞  2009-4-27 11:26
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复