创建一个字符设备1.1

      在开始之前,我们先了解什么是内核模块。

内核模块是一种没有经过链接,不能独立运行的目标文件,是在内核空间运行的程序。

内核模块可以让操作系统内核需要的时候加载,不需要的时候由操作系统进行卸载。拓展了操作系统的功能,不会让操作系统变得很臃肿。

------------------------------------------------------------------------------------------------------------------------------------------------

内核模块与应用程序区别

     应用程序       驱动程序
运行   用户空间            内核空间
入口   main           module_init(初始化函数)
出口    无            module_exit(卸载函数)
编译        gcc -c                           Makefile
链接         ld            insmod
运行   ./                                  insmod

 

        由上面阐述可知,应用程序和驱动程序存在不同空间,操作的方法也不同。而且,又由于驱动是内核的一部分。

所以,我们在编写驱动程序的时候要非常仔细,像不做出错处理、忘记释放内存等动作在我们的驱动程序的编写中都是不允许的!

========================================================================================

                下面,我们来说下如何创建一个简单的字符设备驱动。

1. 我们在写驱动时,首先要查阅芯片厂商提供的源代码。看它如何创建,然后我们依葫芦画瓢地进行我们驱动的编写。如本人用的是三星公司的S5PV210 cortex-A8架构的芯片。

2. 创建一个设备初始化函数、设备退出函数   如下:

  int __init gec210_led_init(void)
  {
    printk("hello gec210 led driver\n");

  return 0;

  }

  void __exit gec210_led_exit(void)
  {
    printk("exit gec210 led driver\n");
  }

其中: 我们的加载指令insmod    卸载指令rmmod分别对应如下函数

  module_init(gec210_led_init); //insmod
  module_exit(gec210_led_exit); //rmmod

最后,我们需要加上设备的相关信息

  MODULE_AUTHOR("Mr.Jin_Fa");                                 作者
  MODULE_DESCRIPTION("S5PV210 LED driver");        功能描述
  MODULE_LICENSE("GPL");            设置宏定义,遵守GPL证书 如不写或写其他参数,编译可能会失败。

以上代码能实现最基本的加载、卸载驱动过程。 不过这里有几点需要注意的

  1)不能使用C语言的库函数
  printf memcpy memset .......

  2)使用GNU C语言,会跟ANSI C语言有所出入,如在初始化结构体的方法上。

  3)内核编程的时候不要使用浮点数,因为浮点数的运算需要库的支持 (本人之前在做ARM裸机开发的时候,就遇到过不支持浮点运算的问题

                   解决办法是 在Makefile上加上arm-linux-gcc 库的路径,并且在主函数那里加一个空的raise()函数)

 

-------------------------------------------------------------------------------------------------------------------------------------------------------------

                    用于管理编译模块的Makefile的编写

obj-m +=led_drv.o    将led_drv.c文件编译为led_drv.o文件(通过查找下面的规则),然后将led_drv.o文件再链接成一个独立的module(led_drv.ko)
KERN_DIR=/home/gec/android-kernel-samsung-dev             定义了一个已经正确编译过的内核源代码的路径,编译过程中,要去内核源代码拿编译工具,使用相应的头文件。
PWD:=$(shell pwd)                                                                  指出当前路径

modules:                       // 目标moudules 的生成规则如下
$(MAKE) -C $(KERN_DIR) M=$(PWD) modules             编译的时候,去内核源代码目录下,找编译工具(Makefile、Kbuild)和头文件;然后回到当前路径下,将驱动文件编译为一个module。

          

clean:         将过程文件和 .ko模块文件clean掉
$(MAKE) -C $(KERN_DIR) M=$(PWD) modules clean

 

                   写完管理编译工具Makefile后 我们就可以编译我们的模块了

=================================================================================================

                    实现效果

gec@ubuntu:/mnt/hgfs/share/001/demo1$ make
make -C /home/gec/android-kernel-samsung-dev M=/mnt/hgfs/share/001/demo1 modules
make[1]: Entering directory `/home/gec/android-kernel-samsung-dev'            这里可以看到 Makefile进入我们制定的源代码路径找工具...
CC [M] /mnt/hgfs/share/001/demo1/led_drv.o                                                
Building modules, stage 2.
MODPOST 1 modules
CC /mnt/hgfs/share/001/demo1/led_drv.mod.o                                                 生成  .o 文件
LD [M] /mnt/hgfs/share/001/demo1/led_drv.ko                                                 连接成  .ko文件
make[1]: Leaving directory `/home/gec/android-kernel-samsung-dev'

 

 

编译完后,在ubuntu当中查看驱动信息

gec@ubuntu:/mnt/hgfs/share/001/demo1$ modinfo led_drv.ko
filename: led_drv.ko
license: GPL
description: S5PV210 LED driver
author: Mr.Jin_Fa
depends:
vermagic: 2.6.35.7-GEC210 preempt mod_unload ARMv7

 

然后愉快地上传到开发板看看...

  在开发板测试与卸载驱动
  [root@GEC210 /]# insmod led_drv.ko              //加载驱动
  [ 58.687003] hello gec210 led driver


  [root@GEC210 /]# lsmod                //显示当前的led_drv.ko是否加载成功
  led_drv 540 0 - Live 0xbf011000
  ...........


  [root@GEC210 /]# rmmod led_drv           //卸载驱动
  [ 102.104536] exit gec210 led driver

 

PS:  这里能正常运行是因为 我们开发板的内核版本、本地版本和 编译模块是一致的,这是保证模块和内核的兼容性,是一种安全措施。 

版本为:2.6.35.7-GEC210          2.6.35.7 为内核版本           -GEC210 为本地版本

 

如何写一个硬件相关的字符设备驱动,在《创建一个字符设备1.2》这篇细讲...

 

posted @ 2017-05-11 16:27  得了白学症  阅读(229)  评论(0编辑  收藏  举报