【ARM】Linux驅動移植

文章目錄


#1驅動模塊移植過程
##1.1模塊的第一種編譯方法——改kconfig

  • 第一步:改kconfig

文件在:Drivers/char/kconfig;
tristate三態表示可以編譯在模塊<M>
bool表示只能被選擇編[*]或不編[ ]
這裏寫圖片描述

  • 第二步:配置內核

make menuconfig後會自動生成供編譯的.config文件。

wuchengbing@ubuntu:~/linux/kernel-2.6.13$ make menuconfig

 Device Drivers  --->  Character devices  ---> 
 
  [*] S3C2410 RTC Driver                                         │ │  
  <M> QQ2440/mini2440 LEDs Driver                                │ │  
  <M> QQ2440/mini2440 PWM beeper Driver                          │ │  
  <M> QQ2440/mini2440 Hello Module sample                        │ │  
  <M> QQ2440 Buttons                         

這裏寫圖片描述
如果make menuconfig沒有出來該選項,可先cp config_n35 .config->make-> make menuconfig,然後成生如下.config文件。

wuchengbing@ubuntu:~/linux/kernel-2.6.13$ gedit .config
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
CONFIG_S3C2410_RTC=y
CONFIG_QQ2440_LEDS=m
CONFIG_QQ2440_PWM_BEEPER=y
CONFIG_QQ2440_HELLO_MODULE=m
… …

如果選擇是[*],即yes,則該驅動在系統運行自動加載;如果選擇是<M>,則要使用該驅動要手工加載。

  • 第三步:編譯內核得到驅動模塊

make,後生成對應的驅動模塊.ko文件。

wuchengbing@ubuntu:~/linux/kernel-2.6.13$make
… …
  LD      vmlinux
  SYSMAP  System.map
  SYSMAP  .tmp_System.map
  OBJCOPY arch/arm/boot/Image
  Kernel: arch/arm/boot/Image is ready
  AS      arch/arm/boot/compressed/head.o
  GZIP    arch/arm/boot/compressed/piggy.gz
  AS      arch/arm/boot/compressed/piggy.o
  CC      arch/arm/boot/compressed/misc.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
  Building modules, stage 2.
  MODPOST
  CC      drivers/char/mini2440_backlight.mod.o
  LD [M]  drivers/char/mini2440_backlight.ko
  CC      drivers/char/qq2440_buttons.mod.o
  LD [M]  drivers/char/qq2440_buttons.ko
  CC      drivers/char/qq2440_hello_module.mod.o
  LD [M]  drivers/char/qq2440_hello_module.ko
  CC      drivers/char/qq2440_leds.mod.o
  LD [M]  drivers/char/qq2440_leds.ko
  CC      drivers/char/qq2440_pwm.mod.o
  LD [M]  drivers/char/qq2440_pwm.ko
wuchengbing@ubuntu:~/linux/kernel-2.6.13$

qq2440_leds.ko

wuchengbing@ubuntu:~/linux/kernel-2.6.13$ ls driver/char/
…
-rw-rw-r-- 1 wuchengbing wuchengbing   1368 Apr 17 20:38 qq2440_hello_module.o
-rw-rw-r-- 1 wuchengbing wuchengbing   3108 Apr 17 20:38 qq2440_pwm.o
-rw-rw-r-- 1 wuchengbing wuchengbing   1412 Apr 17 20:39 qq2440_hello_module.mod.o
-rw-rw-r-- 1 wuchengbing wuchengbing   2247 Apr 17 20:39 qq2440_hello_module.ko
-rw-rw-r-- 1 wuchengbing wuchengbing   1404 Apr 17 20:39 qq2440_leds.mod.o
-rw-rw-r-- 1 wuchengbing wuchengbing   3133 Apr 17 20:39 qq2440_leds.ko
-rw-rw-r-- 1 wuchengbing wuchengbing   1404 Apr 17 20:39 qq2440_pwm.mod.o
-rw-rw-r-- 1 wuchengbing wuchengbing   3957 Apr 17 20:39 qq2440_pwm.ko

./mkimage.sh

wuchengbing@ubuntu:~/linux/kernel-2.6.13$ cd arch/arm/boot/
wuchengbing@ubuntu:~/linux/kernel-2.6.13/arch/arm/boot$ ./mkimage.sh 
Image Name:   linux-2.6.13
Created:      Mon Apr 17 20:33:08 2017
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    1537008 Bytes = 1500.98 kB = 1.47 MB
Load Address: 0x30008000
Entry Point:  0x30008040
wuchengbing@ubuntu:~/linux/kernel-2.6.13/arch/arm/boot$
  • 第四步:拷貝到文件系統,掛載板子,插入模塊

這裏寫圖片描述
運行示例程序編譯出來的./a.out,板子的LED就會亮了。
License問題很需要在驅動代碼加入MODULE_LICENSE("GPL");

... ...
module_init(qq2440_leds_init);
module_exit(qq2440_leds_exit);

MODULE_LICENSE("GPL");
  • 示例程序

應用程序,通過驅動調用板子LED。

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdlib.h>
int main(void)
{
   int fd;
   int i = 0;
   fd = open("/dev/leds",O_RDONLY);
   if(fd==-1)
   {
      perror("open failed");
      exit(1);
   }
   while(1)
   {
       ioctl(fd,0,0);
       ioctl(fd,0,1);
       ioctl(fd,0,2);
       ioctl(fd,0,3);
       sleep(1);
       ioctl(fd,1,0);
       ioctl(fd,1,1);
       ioctl(fd,1,2);
       ioctl(fd,1,3);
       sleep(1);
   }
   return 0;
}

##1.2模塊的第二種編譯方法——Makefile

  • 第一步:寫Makefile

這裏寫圖片描述

  • 第二步:直接把內核驅動拷貝出來

這裏寫圖片描述

  • 第三步:編譯

這裏寫圖片描述

  • 第四步:安裝

這裏寫圖片描述

  • 第五步:插入模塊看現象

這裏寫圖片描述
#2Linux驅動原理
##2.0從哪裏切入
開發板自帶的led程序(qq2440_leds_init)【被module_init調用----知道這裏就行了】
這裏寫圖片描述
##2.1什麼是註冊
這裏寫圖片描述
##2.2register_chrdev提交哪些數據
這裏寫圖片描述
###2.2.1設備號爲什麼是231
怎麼知道設置231
這裏寫圖片描述

http://blog.csdn.net/zjjyliuweijie/article/details/7001383
設置爲231是因爲231沒有人使用。
###2.2.2設備名隨便給
這裏寫圖片描述
###2.2.3文件操作結構體怎麼設置
這裏寫圖片描述

file_operations中各項解析
http://blog.csdn.net/sunsea1026/article/details/6586143
####什麼是THIS_MODULE?
THIS_MODULE在代碼中複製給了owner,owner顧名思義是屬主的意思,當把THIS_MODULE複製給owner,表示該結構體屬於當前模塊,那麼當前模塊又是誰呢?當前模塊就是:
這裏寫圖片描述
####Open,close,read這些都好理解

##2.3register_chrdev返回什麼?
這裏寫圖片描述
###2.3.1 簡潔而高效的goto
用不用goto一直是一個著名的爭議話題,Linux內核源碼中對goto的應用非常廣泛,但一般只侷限於錯誤處理中!這種goto用於錯誤處理的用法實在是簡單而高效,只需保證在錯誤處理的時候記得註銷,釋放資源等!(與正常的註冊,申請資源順序相反)
###2.3.2 還記得什麼是三目運算符嗎?
這裏寫圖片描述
###2.3.3 返回0表示什麼?
當major爲真的時候返回0,是什麼意思呢?
Major爲真的情況,只有可能>0,因爲major的類型是unsigned。所以,當major大於0的時候,函數返回0,表示函數執行成功!
###2.3.4 什麼情況下返回cd->major?
Major爲假的情況,只有一種情況,等於零。那麼major=0,表示什麼呢?
當在調用register_chrdev函數的時候,

  • 如果傳進去的major=0,表示自己不定義設備號,由系統自動分配!
  • 如果傳進去的major>0,表示傳入自己定義的設備號,不用系統自動分配!

我們是怎麼知道的?
這裏寫圖片描述
###2.3.5 次設備號怎麼分配呢?
這裏寫圖片描述
###2.3.6 出錯返回什麼?
這裏寫圖片描述

ENOMEM是什麼?
這裏寫圖片描述

現在能猜出cdev_add返回什麼嗎?
這裏寫圖片描述
##2.4字符設備到底註冊到了哪裏?

##2.5devfs_mk_cdev實現了什麼?
Device FileSystem Make CharDevice
這裏寫圖片描述

主要實現在文件系統下面建立一個設備文件,設備文件的名稱就是DEVICE_NAME;
這裏寫圖片描述
###2.5.1 devfs_mk_cdev參數怎麼用?
這裏寫圖片描述
###2.5.2 MKDEV功能
Make Device
這裏寫圖片描述

###2.5.3 訪問模式
Chmod ,0777,umask
這裏寫圖片描述

[轉載]stat函數與結構體
http://blog.sina.com.cn/s/blog_6dd1df4e0100o50q.html
###2.5.4 現象
下面是驅動成功註冊後,在文件系統中生成的設備文件。
這裏寫圖片描述
##2.6file_operations結構體如何實現
這裏寫圖片描述
###2.6.1 qq2440_leds_ioctl要實現哪些功能?
這裏寫圖片描述
###2.6.2 s3c2410_gpio_setpin在哪裏
這裏寫圖片描述
##2.7引腳控制
這裏s3c2410_gpio_cfgpins3c2410_gpio_setpin就對接上篇文章《ARM接口技術》原理了。
這裏寫圖片描述
##2.8代碼調用關係
這裏寫圖片描述
##2.9module_init函數
參考《linux驅動的入口函數module.docx》
#附錄
工具下載鏈接:
https://github.com/1040003585/Mini2440/tree/master/Tools

Wu_Being 博客聲明:本人博客歡迎轉載,請標明博客原文和原鏈接!謝謝!
《【ARM】Linux驅動移植》
http://blog.csdn.net/u014134180/article/details/72887673

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章