ubuntu下使用qemu模拟ARM,六------驱动程序【转】

转自:http://blog.csdn.net/rfidunion/article/details/54709843

驱动程序分为在ubuntu上运行和在ARM开发板上运行两种,我们分别来进行测试

1.源码

[plain]view plaincopy

  1. empty#include <linux init.h="">
  2. #include <linux module.h="">
  3. static int hello_init(void)
  4. {
  5. printk(KERN_EMERG "Enter Hello abc World!\n");
  6. return 0;
  7. }
  8. static void hello_exit(void)
  9. {
  10. printk(KERN_EMERG "Exit hello world!\n");
  11. }
  12. module_init(hello_init);
  13. module_exit(hello_exit);
  14. MODULE_AUTHOR("RFIDUNION");
  15. MODULE_LICENSE("GPL v2");
  16. MODULE_DESCRIPTION("A simple driver");
  17. MODULE_ALIAS("a simple test module");
  18. empty</linux></linux>

2.电脑上的Makefile

[cpp]view plaincopy

  1. ifneq ($(KERNELRELEASE),)
  2. module-objs := helloworld.o
  3. obj-m := helloworld.o
  4. else
  5. KERNELDIR := /lib/modules/$(shell uname -r)/build
  6. PWD := $(shell pwd)
  7. modules:
  8. $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  9. endif
  10. clean:
  11. rm -rf *.o *~core.depend.*.cmd *.ko *.mod.c.tmp versions

KERNELRELEASE 内核顶层目录Makefile的一个变量。

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

内核源码树目录。

该Makefile 共读取两次,在输入Makefile时,$(KERNELDIR) 第一次读取KERNELRELEASE并没有被定义,然后就开始读取内核源码的目录,开始定义KERNELRELEASE,然后到当前模块的目录里面,M=$(PWD) 进入该Makefile时KERNELRELEAS已经被定义了,读取要编译的模块,然后再返回到modules

编译完成,产生.KO文件

3.ARM开发板上的Makefile

[cpp]view plaincopy

  1. ifneq ($(KERNELRELEASE),)
  2. obj-m := helloworld.o
  3. else
  4. KDIR := /qemu_arm/linux-kernel/linux-3.16.39/
  5. all:
  6. make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
  7. clean:
  8. rm -f *.ko *.o *.mod.o *.mod.c *.symvers
  9. endif

KDIR := /qemu_arm/linux-kernel/linux-3.16.39/

KDIR 指定开发板内核所在目录。

CROSS_COMPILE=arm-none-linux-gnueabi- 指定编译器

4.Makefile注意事项

Makefile的拼写不能出错,不是makefile,Makefile用要用Tab键

常见的错误:

提示:missing separator 在这一行要用Tab键开头

5.在电脑上测试驱动

将源码和Makefile两个文件放在同一个目录中,然后用make命令编译(注意此处的Makefile是用第2步中的Makefile)

[cpp]view plaincopy

  1. book@book-virtual-machine:/qemu_arm/driver$ make
  2. make -C /lib/modules/4.8.0-34-generic/build M=/qemu_arm/driver modules
  3. make[1]: Entering directory '/usr/src/linux-headers-4.8.0-34-generic'
  4. CC [M] /qemu_arm/driver/helloworld.o
  5. Building modules, stage 2.
  6. MODPOST 1 modules
  7. CC /qemu_arm/driver/helloworld.mod.o
  8. LD [M] /qemu_arm/driver/helloworld.ko
  9. make[1]: Leaving directory '/usr/src/linux-headers-4.8.0-34-generic'
  10. book@book-virtual-machine:/qemu_arm/driver$

编译完成后用file命令查看下是否是在PC机上运行的模块,不要和ARM开发板上运行的搞混了。

[cpp]view plaincopy

  1. book@book-virtual-machine:/qemu_arm/driver$ file helloworld.ko
  2. helloworld.ko: ELF 32-bit LSB relocatable, <span >Intel 80386,</span> version 1 (SYSV), BuildID[sha1]=53c0e5e95e8d1c4683f92a7da49c23a5c4d205a8, not stripped
  3. book@book-virtual-machine:/qemu_arm/driver$
看到80386即是在电脑上使用。

加载模块

卸载模块

注意在控制台中无法开到printk打印的信息,原因不知。

可以用下面的命令来查看

dmesg | tail -8

6.在Qemu上模拟ARM开发板测试

将源码和Makefile两个文件放在同一个目录中,然后用make命令编译(注意此处的Makefile是用第3步中的Makefile)

[cpp]view plaincopy

  1. book@book-virtual-machine:/qemu_arm/driver$ make
  2. make -C /qemu_arm/linux-kernel/linux-3.16.39/ M=/qemu_arm/driver modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
  3. make[1]: Entering directory '/qemu_arm/linux-kernel/linux-3.16.39'
  4. CC [M] /qemu_arm/driver/helloworld.o
  5. Building modules, stage 2.
  6. MODPOST 1 modules
  7. CC /qemu_arm/driver/helloworld.mod.o
  8. LD [M] /qemu_arm/driver/helloworld.ko
  9. make[1]: Leaving directory '/qemu_arm/linux-kernel/linux-3.16.39'
  10. book@book-virtual-machine:/qemu_arm/driver$

编译完成后用file命令查看下是否是在ARM开发板上运行的模块,不要和PC机上运行的搞混了。

[plain]view plaincopy

  1. book@book-virtual-machine:/qemu_arm/driver$ file helloworld.ko
  2. helloworld.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=a8f903d9a908203d02cbdac6b23a9d258c21e783, not stripped
  3. book@book-virtual-machine:/qemu_arm/driver$

看到ARM即是用在开发板上的。

将编译好的helloworld.ko文件拷到根文件系统中,然后用Qemu模拟运行,

qemu-system-arm -M vexpress-a9 -m 512M -kernel /qemu_arm/linux-kernel/linux-3.16.39/arch/arm/boot/zImage -nographic -append "root=/dev/mmcblk0 console=ttyAMA0" -sd /qemu_arm/root_system/a9rootfs.ext3

启动完成后在加载模块显示如下:

[plain]view plaincopy

  1. / # insmod helloworld.ko
  2. Enter Hello World!
  3. / #

参考文章:

http://blog.chinaunix.net/uid-24219701-id-3035689.html 简单的驱动makefile解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/rfidunion/article/details/54709843