实战Linux设备驱动--万事开头难--HelloWorld

已经被玩坏了的Hello World

在程序员的世界里,一般开始学习某种语言,或者某一套架构都会先写一个HelloWorld作为示例,OK,我们也不例外。
- helloworld.c代码解析
- Makefile
- 编译运行
- 总结


helloworld.c

   #include <linux/init.h>
   #include <linux/module.h>
   #include <linux/kernel.h>

   static int __init hello_init(void)
   {
       printk(KERN_INFO "%s: Hello World init!\n", __func__);

       return 0;
  }

  static void __exit hello_exit(void)
  {
      printk(KERN_INFO "%s: Hello World exit!\n", __func__);
  }

  module_init(hello_init);
  module_exit(hello_exit);
  MODULE_AUTHOR("JayZhang");

代码很简单,一共就2个函数,hello_init和hello_exit,看字面意思大概就能看出来是什么意思了,注意的地方是,在Linux驱动中,入口是函数是定义在modile_init函数中的,也就是当我们insmod驱动的时候会调用到hello_init函数,然后打印出一条“Hello World init!”的log,当卸载驱动的时候会调用到hello_exit函数,然后打印出一条“Hello World exit!”的log。

Makefile

   obj-m := helloworld.o
   modules:
       $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
   clean:
       $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean

写的比较简单,为了便于理解,其实就是当我们在Linux下输入make的时候,会执行到“ (MAKE)C/lib/modules/ (shell uname -r)/build M=$(shell pwd) modules”
执行make clean的时候会执行到对应的clean命令,具体Makefile的讲解我这里不做太多的叙述,有兴趣的同学可以系统的学习一下,当然了我们也可以把Makefile写的规范一点。

   ifeq ($(KERNELRELEASE),)
       KERNELDIR ?= /lib/modules/$(shell uname -r)/build
       PWD ?= $(shell pwd)
   modules:
       $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
   clean:
       rm -rf *.o *~ *.depend .*.cmd *.ko *.mod.c .tmp_versions
   else
       obj-m := helloworld.o
  endif
obj-m := helloworld.o

代表了我们要构造的模块名为helloworld.ko,make的时候会在该陌路下自动找到helloworld.c文件进行编译。

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

-C (KERNELDIR)makefileM= (PWD)指定了模块源码的位置
modules目标指向obj-m变量中设定的模块。

编译运行

输入make进行编译,

jay@Jay:~/shizhanLinux/1-helloworld$ make
make -C /lib/modules/3.2.0-23-generic/build M=/home/jay/shizhanLinux/1-helloworld modules
make[1]: Entering directory `/usr/src/linux-headers-3.2.0-23-generic'
  CC [M]  /home/jay/shizhanLinux/1-helloworld/helloworld.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/jay/shizhanLinux/1-helloworld/helloworld.mod.o
  LD [M]  /home/jay/shizhanLinux/1-helloworld/helloworld.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.2.0-23-generic'
jay@Jay:~/shizhanLinux/1-helloworld$

生成helloworld.ko驱动模块,然后把驱动加载到系统:

sudo insmod helloworld.ko

查看运行状态:

jay@Jay:~/shizhanLinux/1-helloworld$ dmesg | tail -10
[147140.651992] usb 2-1.1: USB disconnect, device number 22
[157266.722345] usb 2-1.1: new high-speed USB device number 23 using ehci_hcd
[157358.929921] usb 2-1.1: USB disconnect, device number 23
[157378.015240] usb 2-1.1: new high-speed USB device number 24 using ehci_hcd
[159956.702131] usb 2-1.1: USB disconnect, device number 24
[160980.487568] usb 2-1.1: new high-speed USB device number 25 using ehci_hcd
[161100.773607] usb 2-1.1: USB disconnect, device number 25
[249643.386473] hello_init: Hello World init!

可以看到最后一行打印的log,然后卸载模块:

sudo rmmod helloworld

查看运行结果:

[157266.722345] usb 2-1.1: new high-speed USB device number 23 using ehci_hcd
[157358.929921] usb 2-1.1: USB disconnect, device number 23
[157378.015240] usb 2-1.1: new high-speed USB device number 24 using ehci_hcd
[159956.702131] usb 2-1.1: USB disconnect, device number 24
[160980.487568] usb 2-1.1: new high-speed USB device number 25 using ehci_hcd
[161100.773607] usb 2-1.1: USB disconnect, device number 25
[249643.386473] hello_init: Hello World init!
[249656.153638] hello_exit: Hello World exit!

能看到最后打印了exit的log。

总结

从Hello World的例子可以看到,其实写一个驱动并没有想象的那么难,但是这只是踏进Linux驱动开发的第一步,以后的学习中要遵循Linus大神的指导:

Read the fucking source code!

多读多看Linux内核源代码!


zhangjie201412@foxmail.com
JayZhang

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值