Genèse d’un pilote Linux (Part2)

Dans l’épisode précédent nous avons pu démontrer
fonctionnement du MCP79400 sur une AFP51, nous
allons maintenant pouvoir l’intégrer au kernel Linux avec un driver adequate.

Plongée dans l’univers du kernel: fouinons !

L’idée consiste à écrire le moins possible de code et à copier au maximum ce
qui existe déjà dans le kernel. Pour cela un petit tour dans le code de Linux
s’impose. Dans le cas d’Armadeus le code du kernel (patché pour
le projet se trouve dans le répertoire
buildroot/output/build/linux-2.6.38.8 on peut aussi browser le net
à la recherche de driver similaire, mais il est important d’essayer de coller au
kernel utilisé.

Le MCP79400 est une RTC, et nous avons de la chance l’api RTC est déjà
supporté depuis longtemps dans Linux, donc nous avons une bonne documentation
dans le code : Documentation/rtc.txt

Mais comme on ne veut surtout pas se fouler, l’objectif est de trouver un
composant très proche du notre et de le recopier à coup de
cherher/remplacer.

Résumons:

  • Notre composant est une rtc: allons voir dans le répertoire
    Drivers/rtc/ si nous n’y trouverions pas notre bonheurs.
  • $ ls linux-2.6.38.8/drivers/rtc
    class.c           rtc-ds1511.c    rtc-max8998.c       rtc-rs5c313.c
    hctosys.c         rtc-ds1553.c    rtc-mc13xxx.c       rtc-rs5c348.c
    rtc-ab8500.c      rtc-ds3232.c    rtc-mpc5121.c       rtc-rx8581.c
    rtc-at32ap700x.c  rtc-ds3234.c    rtc-mrst.c          rtc-s35390a.c
    rtc-at91rm9200.c  rtc-efi.c       rtc-msm6242.c       rtc-s3c.c
    rtc-at91sam9.c    rtc-ep93xx.c    rtc-mv.c            rtc-sa1100.c
    rtc-au1xxx.c      rtc-fm3130.c    rtc-mxc.c           rtc-sh.c
    rtc-bfin.c        rtc-generic.c   rtc-mxc_v2.c        rtc-starfire.c
    rtc-bq32k.c       rtc-imxdi.c     rtc-nuc900.c        rtc-stk17ta8.c
    rtc-bq4802.c      rtc-isl12022.c  rtc-omap.c          rtc-stmp3xxx.c
    rtc-cmos.c        rtc-isl1208.c   rtc-pcap.c          rtc-sun4v.c
    rtc-coh901331.c   rtc-jz4740.c    rtc-pcf2123.c       rtc-sysfs.c
    rtc-davinci.c     rtc-lib.c       rtc-pcf50633.c      rtc-test.c
    rtc-dev.c         rtc-lpc32xx.c   rtc-pcf8563.c       rtc-twl.c
    rtc-dm355evm.c    rtc-m41t80.c    rtc-pcf8583.c       rtc-tx4939.c
    rtc-ds1216.c      rtc-m41t94.c    rtc-pl030.c         rtc-v3020.c
    rtc-ds1286.c      rtc-m48t35.c    rtc-pl031.c         rtc-vr41xx.c
    rtc-ds1302.c      rtc-m48t59.c    rtc-proc.c          rtc-wm831x.c
    rtc-ds1305.c      rtc-m48t86.c    rtc-ps3.c           rtc-wm8350.c
    rtc-ds1307.c      rtc-max6900.c   rtc-pxa.c           rtc-x1205.c
    rtc-ds1374.c      rtc-max6902.c   rtc-r9701.c
    rtc-ds1390.c      rtc-max8925.c   rtc-rp5c01.c
  • Le nombre de composant supporté est relativement élevé, voyons voir ceux
    qui sont piloté par bus i²c comme le notre :
  • 
    $ grep -Rn "i2c.h" *
    rtc-bq32k.c:12:#include  <linux/i2c.h>
    rtc-ds1307.c:16:#include <linux/i2c.h>
    rtc-ds1374.c:23:#include <linux/i2c.h>
    rtc-ds1672.c:12:#include <linux/i2c.h>
    rtc-ds3232.c:21:#include <linux/i2c.h>
    rtc-fm3130.c:13:#include <linux/i2c.h>
    rtc-isl12022.c:14:#include <linux/i2c.h>
    rtc-isl1208.c:14:#include <linux/i2c.h>
    rtc-m41t80.c:17:#include <linux/i2c.h>
    rtc-max6900.c:15:#include <linux/i2c.h>
    rtc-max8925.c:13:#include <linux/i2c.h>
    rtc-max8998.c:16:#include <linux/i2c.h>
    rtc-pcf8563.c:17:#include <linux/i2c.h>
    rtc-pcf8583.c:16:#include <linux/i2c.h>
    rtc-rs5c372.c:13:#include <linux/i2c.h>
    rtc-rx8025.c:26:#include <linux/i2c.h>
    rtc-rx8581.c:16:#include <linux/i2c.h>
    rtc-s35390a.c:14:#include <linux/i2c.h>
    rtc-x1205.c:20:#include <linux/i2c.h>
    
  • Cela réduit déjà le nombre cela reste élevé. Le composant de chez Dallas
    DS1374 semble néanmoins assez intéressant car il est court et
    surtout il est déjà utilisé dans certain projet Armadeus
    donc bien connu.

Notre nouveau driver devrait donc pouvoir s’insérer dans ce répertoire sans
problème, appelons le rtc-mcp7940x.c histoire de coller aux autres.
Pour l’ajouter, trois fichiers doivent-être modifiés:

  • drivers/rtc/KConfig: Pour ajouter le driver dans le
    menuconfig de linux
  • [...]
    	  watchdog timer in the ST M41T60 and M41T80 RTC chips series.
    
    config RTC_DRV_MCP7940X
    	tristate "Microchip MCP7940X"
    	depends on RTC_CLASS && I2C
    	help
    	  If you say yes here you get support for Microchip
    	  MCP7940x real-time clock chips.
    	  The alarm functionality is not supported.
    
    	  This driver can also be built as a module. If so, the module
    	  will be called rtc-mcp7940x.
    
    config RTC_DRV_BQ32K
    [...]    
  • drivers/rtc/Makefile:
  • [...]
    obj-$(CONFIG_RTC_DRV_MC13XXX)	+= rtc-mc13xxx.o
    obj-$(CONFIG_RTC_DRV_MCP7940X)	+= rtc-mcp7940x.o
    obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
    [...]
  • drivers/rtc/rtc-mcp7940x.c: le source du driver proprement
    dit

Un bon développeur kernel porte le quilt chez Armadeus.

On vient juste de voir quels fichiers il était nécessaire de modifier pour
ajouter notre driver, néanmoins notre objectif final est quand même de partager
ce driver et, dans un premier temps, de le proposer à la communautée d’Armadeus
Project. Pour cela nous allons avoir besoin de réaliser un patch.

Le kernel utilisé pour le projet armadeus est déjà noyé de patches, si bien
qu’il est difficile de gérer son pauvre petit patches parmis les autres. Il est
donc conseillé d’utiliser le programme Quilt pour gérer des piles
de patche.

quilt est relativement bien intégré au projet; pour s’en servir
il est nécessaire de quiltifier Linux avec la commande
suivante à la racine du projet :

$ ./scripts/quiltify
--- What do you want to quiltify today ? ;-)
1) Linux
2) Buildroot
3) U-Boot
\> 1

Le script va empiler tous les patches nécessaire au projet armadeus puis
recompiler Linux. Une fois fait nous n’avons plus qu’à nous rendre dans
l’arborescence du code:

$ cd buildroot/output/build/linux-2.6.38.8
buildroot/output/build/linux-2.6.38.8$ quilt applied
[...]
442-freescale-0034-ENGR00126692-3-1-add_drivers_mxc_directory.patch
442-freescale-0034-ENGR00126692-3-add_hw-events_and_srtc_drivers.patch
442-freescale-0034-ENGR00126692-3-add_hw-vpu_driver.patch
442-freescale-0034-ENGR00126692-3-add_iim_driver.patch
442-freescale-0034-ENGR00126692-3-add_mx23_mx25_mx28_security_stuff.patch
442-freescale-0197-ENGR00131650-add_scc2_and_sahara_drivers_without_rng.patch
442-freescale-0535-ENGR00136875-1-Add-function-pgprot_writethru.patch
442-freescale-0536-ENGR00136875-2-make-video-buffer-cacheable-to-improv.patch
444-armadeus-sunrpc-silent_annoying_svc_message_when_mounting_NFS_drives.patch
445-armadeus-add_freescale_mxc_dvfs_driver.patch
446-armadeus-add_freescale_ipu3_driver.patch
447-armadeus-add_freescale_ipu_based_framebuffer_driver.patch
448-armadeus-pps51-adding_HX8369_display_driver.patch
449-armadeus-add_pps51_baseboard.patch
[...]

La commande quilt applied affiche tous les patches appliqués au
noyau. Pour ajouter notre driver nous allons donc créer un nouveau patche:

$ quilt new 450-armadeus-add_mcp7940x_rtc_driver.patch

Et ajouter les fichiers que nous allons modifier avant de les
modifier.


$ quilt add drivers/rtc/Makefile
$ quilt add drivers/rtc/Kconfig
$ quilt add drivers/rtc-mcp7940x.c

Nous sommes maintenant prêt à écrire le code proprement dit, comme nous allons le voir dans le prochain épisode

[À suivre …]

Ce contenu a été publié dans embarqué, informatique, kernel. Vous pouvez le mettre en favoris avec ce permalien.

2 réponses à Genèse d’un pilote Linux (Part2)

  1. samuel dit :

    La suite ! La suite ! La suite !

    Je cherche à étendre les fonction du driver “rtc-pcf8563.c” pour y ajouter la gestion de l’alarme et je rame un peu dans le code des drivers du kernel linux …

  2. admin dit :

    Promis je fait ça avant la fin de la semaine !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *