zoukankan      html  css  js  c++  java
  • ubuntu下使用qemu模拟ARM(六)------驱动程序【转】

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

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

    1.源码

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


    2.电脑上的Makefile

    [cpp] view plain copy
     
    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.    
    11. clean:  
    12.     rm -rf *.o *~core.depend.*.cmd *.ko *.mod.c.tmp versions  
    13.    

    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 plain copy
     
    1. ifneq ($(KERNELRELEASE),)  
    2.    
    3. obj-m := helloworld.o  
    4.    
    5. else  
    6. KDIR := /qemu_arm/linux-kernel/linux-3.16.39/  
    7. all:  
    8.     make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-  
    9. clean:  
    10.     rm -f *.ko *.o *.mod.o *.mod.c *.symvers  
    11.    
    12. 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 plain copy
     
    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 plain copy
     
    1. book@book-virtual-machine:/qemu_arm/driver$ file helloworld.ko   
    2. helloworld.ko: ELF 32-bit LSB relocatable, <span style="color:#ff0000;">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 plain copy
     
    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 plain copy
     
    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 plain copy
     
    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
  • 相关阅读:
    阿里云上的Centos 7.6的一次Nginx+Mysql+PHP7.3 部署
    Spring系列-SpringBoot 学习路径
    想做公众号,总要写点什么--第008期博文
    我关注的那些公众号-第007期博文
    Ruby on Rails,一对多关联(One-to-Many)
    ruby新建web项目步骤,使用mysql数据库
    ruby select 方法,可用于先查询结果后,再次用条件限制
    cron和crontab命令详解 crontab 每分钟、每小时、每天、每周、每月、每年定时执行 crontab每5分钟执行一次
    nginx做rails项目web服务器缓存配置方法
    ruby----%使用法
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/8614327.html
Copyright © 2011-2022 走看看