linux驱动被哪些进程使用,Linux驱动程序开发的经验总结

在尝试编写一些驱动模块时,其中就是遇到一些编译错误之类的,一种错误有很多种原因,总结下我遇到的一些问题,供你们参考:

1.编写一个内核程序spinlock.c:

#include

#include

#include

#include

#include

MODULE_LICENSE(“GPL”);

#define MAJOR_NUM 224

static ssize_t simplespin_read(struct file *, char , size_t, loff_t);

static ssize_t simplespin_write(struct file *, const char , size_t, loff_t);

static int simplespin_open(struct inode *inode, struct file *filp);

static int simplespin_release(struct inode *inode, struct file *filp);

struct file_operations simplespin_fops =

{

.read=simplespin_read,

.write=simplespin_write,

.open=simplespin_open,

.release=simplespin_release,

};

static int simplespin_var = 0;

static int simplespin_count = 0;

static spinlock_t spin;

static int simplespin_open(struct inode *inode, struct file *filp)

{

/获得自选锁/

spin_lock(&spin);

/*临界资源访问*/

if (simplespin_count)

{

spin_unlock(&spin);

return - EBUSY;

}

simplespin_count++;

/*释放自选锁*/

spin_unlock(&spin);

return 0;

}

static int simplespin_release(struct inode *inode, struct file *filp)

{

simplespin_count–;

return 0;

}

static ssize_t simplespin_read(struct file *filp, char buf, size_t len, loff_toff)

{

return 0;

}

static ssize_t simplespin_write(struct file *filp, const char *buf, size_t len,loff_t *off)

{

return 0;

}

static int __init simplespin_init(void)

{

int ret;

spin_lock_init(&spin);

/注册设备驱动/

ret = register_chrdev(MAJOR_NUM, “chardev”, &simplespin_fops);

if (ret)

{

printk(“chardev register failure\n”);

}

else

{

printk(“chardev register success\n”);

}

return ret;

}

static void __exit simplespin_exit(void)

{

/注销设备驱动/

unregister_chrdev(MAJOR_NUM, “chardev”);

}

module_init(simplespin_init);

module_exit(simplespin_exit);

2.写一个test.c进行测试:

#include

#include

#include

#include

#include

#include

#include

void main()

{

int fd;

fd=open("/dev/jrb",O_RDWR);/By read and write method open /dev/fgj/

if(fd==-1)

{

perror(“error open\n”);

exit(-1);

}

printf(“open /dev/jrb successfully\n”);

while(1);

close(fd);

}

3.编写Makefile:

ifeq ($(KERNELRELEASE),)

ARCH=x86

PWD:= (shellpwd)CROSSCOMPILE=x8664−linux−gnu−CC=(shell pwd)

CROSS_COMPILE=x86_64-linux-gnu-

CC=(shellpwd)CROSSC​OMPILE=x866​4−linux−gnu−CC=(CROSS_COMPILE)gcc

#CROSS_COMPILE=arm-linux-gnueabi-

KERNELDIR=/usr/src/linux-headers-4.13.0-36-generic

lkm.ko: spinlock.c

(MAKE)ARCH=(MAKE) ARCH=(MAKE)ARCH=(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C (KERNELDIR)M=(KERNELDIR) M=(KERNELDIR)M=(PWD) modules

else

obj-m += spinlock.o

endif

test: test.c

arm-linux-gnueabi-gcc $< -o $@ -g

clean:

rm -rf *.o *.ko .mod.c ..cmd *.markers *.order *.symvers .tmp_versions test

主要时Makefile里面的一些参数比较重要,直接关系到你是否能够编译成功的关键:

KERNELRELEASE:是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容,

ARCH:如果我们用本机内核编译的话,就应配置本机的cpu架构,inter处理器就是x86,如果是开发板那就是arm,如何看是什么archtechture呢?

robin@robin:~$ uname -a

Linux robin 4.13.0-36-generic #40~16.04.1-Ubuntu SMP Fri Feb 16 23:25:58 UTC 2018 x86_64 x86_64

x86_64 GNU/Linux

uname -a之后就知道我们的处理器时x86/64位处理器,使用的内核版本是4.13.0-36-generic,一般我们的内核版本在/usr/src/下面:

robin@robin:~$ cd /usr/src/linux-

linux-headers-4.13.0-36/ linux-headers-4.15.0-42/ linux-headers-4.8.0-58-

generic/ linux-source-4.8.0/

linux-headers-4.13.0-36-generic/ linux-headers-4.8.0-58/ linux-source-4.15.0/

CROSS_COMPILE:就表示我们使用的本机交叉编译工具链,如何看本机工具链是什么?从刚才的uname -a其实我们已经看出来了,使用的是x86。但是具体的编译工具是什么呢?还是进入刚才我们的那个/usr/路径下面,看一下本机有哪些交叉编译工具链?

robin@robin:~$ cd /usr/

arm-linux-androideabi/ arm-linux-gnueabihf/ games/ lib/ local/

sbin/ src/ arm-linux-gnueabi/ bin/ include/

lib32/ locale/ share/ x86_64-linux-gnu/

从上面可以看出本机用到的交叉编译工具链有x86_64-linux-gnu-gcc,arm-linux-gnueabih-gcc,arm-linux-androideabi-gcc,arm-linux-gnueabi-gcc,我们之前使用的uname -a已经告诉我们本机的cpu型号和内核版本,因此我们就需要配置为x86_64-linux-gnu-,后面记得加一个-,不能跟gcc哦。

KERNELDIR:表示本机运行的内核位置,一般在/usr/src/下面先要用uname -r确定一下正在使用的内核的版本,然后在进行选择。

4.常见编译报错:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -C /usr/src/linux-headers-4.13.0-36-generic M=/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock modules

make[1]: Entering directory ‘/usr/src/linux-headers-4.13.0-36-generic’

CC [M] /home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o

In file included from ./include/asm-generic/int-ll64.h:10:0,

from ./arch/arm/include/uapi/asm/types.h:4,

from ./include/uapi/linux/types.h:4,

from ./include/linux/types.h:5,

from ./include/linux/list.h:4,

from ./include/linux/module.h:9,

from /home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.c:2:

./include/uapi/asm-generic/int-ll64.h:11:29: fatal error: asm/bitsperlong.h: 没有那个文件或目录

compilation terminated.

scripts/Makefile.build:315: recipe for target ‘/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o’ failed

make[2]: *** [/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o] Error 1

Makefile:1550: recipe for target ‘module/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock’ failed

make[1]: *** [module/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock] Error 2

make[1]: Leaving directory ‘/usr/src/linux-headers-4.13.0-36-generic’

Makefile:10: recipe for target ‘lkm.ko’ failed

make: *** [lkm.ko] Error 2

这个错误就是ARCH配置不正确导致的,按照上面的方法重新配置。

make ARCH=x86 CROSS_COMPILE=arm-linux-gnueabi- -C /usr/src/linux-headers-4.13.0-36-generic M=/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock modules

make[1]: Entering directory ‘/usr/src/linux-headers-4.13.0-36-generic’

arch/x86/Makefile:153: CONFIG_X86_X32 enabled but no binutils support

CC [M] /home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-sse’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-mmx’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-sse2’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-3dnow’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-m64’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-red-zone’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mcmodel=kernel’

scripts/Makefile.build:315: recipe for target ‘/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o’ failed

make[2]: *** [/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o] Error 1

Makefile:1550: recipe for target ‘module/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock’ failed

make[1]: *** [module/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock] Error 2

make[1]: Leaving directory ‘/usr/src/linux-headers-4.13.0-36-generic’

Makefile:11: recipe for target ‘lkm.ko’ failed在尝试编写一些驱动模块时,其中就是遇到一些编译错误之类的,一种错误有很多种原因,总结下我遇到的一些问题,供你们参考:

1.编写一个内核程序spinlock.c:

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

#define MAJOR_NUM 224

static ssize_t simplespin_read(struct file *, char *, size_t, loff_t*);

static ssize_t simplespin_write(struct file *, const char *, size_t, loff_t*);

static int simplespin_open(struct inode *inode, struct file *filp);

static int simplespin_release(struct inode *inode, struct file *filp);

struct file_operations simplespin_fops =

{

.read=simplespin_read,

.write=simplespin_write,

.open=simplespin_open,

.release=simplespin_release,

};

static int simplespin_var = 0;

static int simplespin_count = 0;

static spinlock_t spin;

static int simplespin_open(struct inode *inode, struct file *filp)

{

/*获得自选锁*/

spin_lock(&spin);

/*临界资源访问*/

if (simplespin_count)

{

spin_unlock(&spin);

return - EBUSY;

}

simplespin_count++;

/*释放自选锁*/

spin_unlock(&spin);

return 0;

}

static int simplespin_release(struct inode *inode, struct file *filp)

{

simplespin_count--;

return 0;

}

static ssize_t simplespin_read(struct file *filp, char *buf, size_t len, loff_t*off)

{

return 0;

}

static ssize_t simplespin_write(struct file *filp, const char *buf, size_t len,loff_t *off)

{

return 0;

}

static int __init simplespin_init(void)

{

int ret;

spin_lock_init(&spin);

/*注册设备驱动*/

ret = register_chrdev(MAJOR_NUM, "chardev", &simplespin_fops);

if (ret)

{

printk("chardev register failure\n");

}

else

{

printk("chardev register success\n");

}

return ret;

}

static void __exit simplespin_exit(void)

{

/*注销设备驱动*/

unregister_chrdev(MAJOR_NUM, "chardev");

}

module_init(simplespin_init);

module_exit(simplespin_exit);

2.写一个test.c进行测试:

#include

#include

#include

#include

#include

#include

#include

void main()

{

int fd;

fd=open("/dev/jrb",O_RDWR);/*By read and write method open /dev/fgj*/

if(fd==-1)

{

perror("error open\n");

exit(-1);

}

printf("open /dev/jrb successfully\n");

while(1);

close(fd);

}

3.编写Makefile:

ifeq ($(KERNELRELEASE),)

ARCH=x86

PWD:= $(shell pwd)

CROSS_COMPILE=x86_64-linux-gnu-

CC=$(CROSS_COMPILE)gcc

#CROSS_COMPILE=arm-linux-gnueabi-

KERNELDIR=/usr/src/linux-headers-4.13.0-36-generic

lkm.ko: spinlock.c

$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules

else

obj-m += spinlock.o

endif

test: test.c

arm-linux-gnueabi-gcc $< -o $@ -g

clean:

rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers .tmp_versions test

主要时Makefile里面的一些参数比较重要,直接关系到你是否能够编译成功的关键:

KERNELRELEASE:是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义,所以make将读取执行else之后的内容,

ARCH:如果我们用本机内核编译的话,就应配置本机的cpu架构,inter处理器就是x86,如果是开发板那就是arm,如何看是什么archtechture呢?

robin@robin:~$ uname -a

Linux robin 4.13.0-36-generic #40~16.04.1-Ubuntu SMP Fri Feb 16 23:25:58 UTC 2018 x86_64 x86_64

x86_64 GNU/Linux

uname -a之后就知道我们的处理器时x86/64位处理器,使用的内核版本是4.13.0-36-generic,一般我们的内核版本在/usr/src/下面:

robin@robin:~$ cd /usr/src/linux-

linux-headers-4.13.0-36/ linux-headers-4.15.0-42/ linux-headers-4.8.0-58-

generic/ linux-source-4.8.0/

linux-headers-4.13.0-36-generic/ linux-headers-4.8.0-58/ linux-source-4.15.0/

CROSS_COMPILE:就表示我们使用的本机交叉编译工具链,如何看本机工具链是什么?从刚才的uname -a其实我们已经看出来了,使用的是x86。但是具体的编译工具是什么呢?还是进入刚才我们的那个/usr/路径下面,看一下本机有哪些交叉编译工具链?

robin@robin:~$ cd /usr/

arm-linux-androideabi/ arm-linux-gnueabihf/ games/ lib/ local/

sbin/ src/ arm-linux-gnueabi/ bin/ include/

lib32/ locale/ share/ x86_64-linux-gnu/

从上面可以看出本机用到的交叉编译工具链有x86_64-linux-gnu-gcc,arm-linux-gnueabih-gcc,arm-linux-androideabi-gcc,arm-linux-gnueabi-gcc,我们之前使用的uname -a已经告诉我们本机的cpu型号和内核版本,因此我们就需要配置为x86_64-linux-gnu-,后面记得加一个-,不能跟gcc哦。

KERNELDIR:表示本机运行的内核位置,一般在/usr/src/下面先要用uname -r确定一下正在使用的内核的版本,然后在进行选择。

4.常见编译报错:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -C /usr/src/linux-headers-4.13.0-36-generic M=/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock modules

make[1]: Entering directory '/usr/src/linux-headers-4.13.0-36-generic'

CC [M] /home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o

In file included from ./include/asm-generic/int-ll64.h:10:0,

from ./arch/arm/include/uapi/asm/types.h:4,

from ./include/uapi/linux/types.h:4,

from ./include/linux/types.h:5,

from ./include/linux/list.h:4,

from ./include/linux/module.h:9,

from /home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.c:2:

./include/uapi/asm-generic/int-ll64.h:11:29: fatal error: asm/bitsperlong.h: 没有那个文件或目录

compilation terminated.

scripts/Makefile.build:315: recipe for target '/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o' failed

make[2]: *** [/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o] Error 1

Makefile:1550: recipe for target '_module_/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock' failed

make[1]: *** [_module_/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock] Error 2

make[1]: Leaving directory '/usr/src/linux-headers-4.13.0-36-generic'

Makefile:10: recipe for target 'lkm.ko' failed

make: *** [lkm.ko] Error 2

这个错误就是ARCH配置不正确导致的,按照上面的方法重新配置。

make ARCH=x86 CROSS_COMPILE=arm-linux-gnueabi- -C /usr/src/linux-headers-4.13.0-36-generic M=/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock modules

make[1]: Entering directory '/usr/src/linux-headers-4.13.0-36-generic'

arch/x86/Makefile:153: CONFIG_X86_X32 enabled but no binutils support

CC [M] /home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-sse’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-mmx’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-sse2’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-3dnow’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-m64’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mno-red-zone’

arm-linux-gnueabi-gcc: error: unrecognized command line option ‘-mcmodel=kernel’

scripts/Makefile.build:315: recipe for target '/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o' failed

make[2]: *** [/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock/spinlock.o] Error 1

Makefile:1550: recipe for target '_module_/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock' failed

make[1]: *** [_module_/home/robin/workspace/project/Linux_driver_2nd/samples/3synchronous/3-1spinlock] Error 2

make[1]: Leaving directory '/usr/src/linux-headers-4.13.0-36-generic'

Makefile:11: recipe for target 'lkm.ko' failed

make: *** [lkm.ko] Error 2

这类错误表示ARCH和CROSS_COMPILE不一致导致,两者应该都为我们本地Linux正在运行的架构和交叉编译工具链。所以应当仔细检查。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值