{"id":419,"date":"2012-10-11T21:29:40","date_gmt":"2012-10-11T19:29:40","guid":{"rendered":"http:\/\/www.martoni.fr\/wordpress\/?p=419"},"modified":"2013-10-07T17:05:49","modified_gmt":"2013-10-07T15:05:49","slug":"genese-dun-pilote-linux-part2","status":"publish","type":"post","link":"https:\/\/www.fabienm.eu\/wordpress\/2012\/10\/11\/genese-dun-pilote-linux-part2\/","title":{"rendered":"Gen\u00e8se d&rsquo;un pilote Linux (Part2)"},"content":{"rendered":"<p>Dans l&rsquo;<a href=\"http:\/\/www.martoni.fr\/wordpress\/?p=394\">\u00e9pisode pr\u00e9c\u00e9dent<\/a> nous avons pu d\u00e9montrer<br \/>\nfonctionnement du  <a href=\"http:\/\/www.microchip.com\/wwwproducts\/Devices.aspx?dDocName=en551550\">MCP79400<\/a> sur une <a href=\"http:\/\/www.armadeus.com\/francais\/produits-cartes_microprocesseur-apf51.html\">AFP51<\/a>, nous<br \/>\nallons maintenant pouvoir l&rsquo;int\u00e9grer au kernel Linux avec un driver adequate.<\/p>\n<h2>Plong\u00e9e dans l&rsquo;univers du kernel: fouinons !<\/h2>\n<p>L&rsquo;id\u00e9e consiste \u00e0 \u00e9crire le moins possible de code et \u00e0 copier au maximum ce<br \/>\nqui existe d\u00e9j\u00e0 dans le kernel. Pour cela un petit tour dans le code de Linux<br \/>\ns&rsquo;impose. Dans le cas d&rsquo;<a href=\"http:\/\/www.armadeus.com\/wiki\/index.php?title=Main_Page\">Armadeus<\/a> le code du kernel (patch\u00e9 pour<br \/>\nle projet se trouve dans le r\u00e9pertoire<br \/>\n<samp>buildroot\/output\/build\/linux-2.6.38.8<\/samp> on peut aussi browser le net<br \/>\n\u00e0 la recherche de driver similaire, mais il est important d&rsquo;essayer de coller au<br \/>\nkernel utilis\u00e9.<\/p>\n<p>Le MCP79400 est une RTC, et nous avons de la chance l&rsquo;api RTC est d\u00e9j\u00e0<br \/>\nsupport\u00e9 depuis longtemps dans Linux, donc nous avons une bonne documentation<br \/>\ndans le code : <samp> Documentation\/rtc.txt<\/samp><\/p>\n<p>Mais comme on ne veut surtout pas se fouler, l&rsquo;objectif est de trouver un<br \/>\ncomposant tr\u00e8s proche du notre et de le recopier \u00e0 coup de<br \/>\ncherher\/remplacer.<\/p>\n<p>\nR\u00e9sumons:\n<\/p>\n<ul>\n<li>Notre composant est une rtc: allons voir dans le r\u00e9pertoire<br \/>\n    <samp>Drivers\/rtc\/<\/samp> si nous n&rsquo;y trouverions pas notre bonheurs.<\/li>\n<pre><code>$ ls linux-2.6.38.8\/drivers\/rtc\r\nclass.c           rtc-ds1511.c    rtc-max8998.c       rtc-rs5c313.c\r\nhctosys.c         rtc-ds1553.c    rtc-mc13xxx.c       rtc-rs5c348.c\r\nrtc-ab8500.c      rtc-ds3232.c    rtc-mpc5121.c       rtc-rx8581.c\r\nrtc-at32ap700x.c  rtc-ds3234.c    rtc-mrst.c          rtc-s35390a.c\r\nrtc-at91rm9200.c  rtc-efi.c       rtc-msm6242.c       rtc-s3c.c\r\nrtc-at91sam9.c    rtc-ep93xx.c    rtc-mv.c            rtc-sa1100.c\r\nrtc-au1xxx.c      rtc-fm3130.c    rtc-mxc.c           rtc-sh.c\r\nrtc-bfin.c        rtc-generic.c   rtc-mxc_v2.c        rtc-starfire.c\r\nrtc-bq32k.c       rtc-imxdi.c     rtc-nuc900.c        rtc-stk17ta8.c\r\nrtc-bq4802.c      rtc-isl12022.c  rtc-omap.c          rtc-stmp3xxx.c\r\nrtc-cmos.c        rtc-isl1208.c   rtc-pcap.c          rtc-sun4v.c\r\nrtc-coh901331.c   rtc-jz4740.c    rtc-pcf2123.c       rtc-sysfs.c\r\nrtc-davinci.c     rtc-lib.c       rtc-pcf50633.c      rtc-test.c\r\nrtc-dev.c         rtc-lpc32xx.c   rtc-pcf8563.c       rtc-twl.c\r\nrtc-dm355evm.c    rtc-m41t80.c    rtc-pcf8583.c       rtc-tx4939.c\r\nrtc-ds1216.c      rtc-m41t94.c    rtc-pl030.c         rtc-v3020.c\r\nrtc-ds1286.c      rtc-m48t35.c    rtc-pl031.c         rtc-vr41xx.c\r\nrtc-ds1302.c      rtc-m48t59.c    rtc-proc.c          rtc-wm831x.c\r\nrtc-ds1305.c      rtc-m48t86.c    rtc-ps3.c           rtc-wm8350.c\r\nrtc-ds1307.c      rtc-max6900.c   rtc-pxa.c           rtc-x1205.c\r\nrtc-ds1374.c      rtc-max6902.c   rtc-r9701.c\r\nrtc-ds1390.c      rtc-max8925.c   rtc-rp5c01.c<\/code><\/pre>\n<li>Le nombre de composant support\u00e9 est relativement \u00e9lev\u00e9, voyons voir ceux<br \/>\n    qui sont pilot\u00e9 par bus i\u00b2c comme le notre :\n    <\/li>\n<pre><code><xmp>\r\n$ grep -Rn \"i2c.h\" *\r\nrtc-bq32k.c:12:#include  <linux\/i2c.h>\r\nrtc-ds1307.c:16:#include <linux\/i2c.h>\r\nrtc-ds1374.c:23:#include <linux\/i2c.h>\r\nrtc-ds1672.c:12:#include <linux\/i2c.h>\r\nrtc-ds3232.c:21:#include <linux\/i2c.h>\r\nrtc-fm3130.c:13:#include <linux\/i2c.h>\r\nrtc-isl12022.c:14:#include <linux\/i2c.h>\r\nrtc-isl1208.c:14:#include <linux\/i2c.h>\r\nrtc-m41t80.c:17:#include <linux\/i2c.h>\r\nrtc-max6900.c:15:#include <linux\/i2c.h>\r\nrtc-max8925.c:13:#include <linux\/i2c.h>\r\nrtc-max8998.c:16:#include <linux\/i2c.h>\r\nrtc-pcf8563.c:17:#include <linux\/i2c.h>\r\nrtc-pcf8583.c:16:#include <linux\/i2c.h>\r\nrtc-rs5c372.c:13:#include <linux\/i2c.h>\r\nrtc-rx8025.c:26:#include <linux\/i2c.h>\r\nrtc-rx8581.c:16:#include <linux\/i2c.h>\r\nrtc-s35390a.c:14:#include <linux\/i2c.h>\r\nrtc-x1205.c:20:#include <linux\/i2c.h>\r\n<\/xmp><\/code><\/pre>\n<li>Cela r\u00e9duit d\u00e9j\u00e0 le nombre cela reste \u00e9lev\u00e9. Le composant de chez Dallas<br \/>\n    <a href=\"http:\/\/git.kernel.org\/?p=linux\/kernel\/git\/stable\/linux-stable.git;a=blob_plain;f=drivers\/rtc\/rtc-ds1374.c;hb=0e51793e162ca432fc5f04178cf82b80a92c2659\">DS1374<\/a> semble n\u00e9anmoins assez int\u00e9ressant car il est court et<br \/>\n    surtout il est d\u00e9j\u00e0 utilis\u00e9 dans certain projet <a href=\"http:\/\/www.armadeus.com\/wiki\/index.php?title=I2C\">Armadeus<\/a><br \/>\n    donc bien connu.<\/li>\n<\/ul>\n<p>Notre nouveau driver devrait donc pouvoir s&rsquo;ins\u00e9rer dans ce r\u00e9pertoire sans<br \/>\nprobl\u00e8me, appelons le <samp>rtc-mcp7940x.c<\/samp> histoire de coller aux autres.<br \/>\nPour l&rsquo;ajouter, trois fichiers doivent-\u00eatre modifi\u00e9s:<\/p>\n<ul>\n<li><samp>drivers\/rtc\/KConfig<\/samp>: Pour ajouter le driver dans le<br \/>\n    menuconfig de linux<\/li>\n<pre><code><xmp>[...]\r\n\t  watchdog timer in the ST M41T60 and M41T80 RTC chips series.\r\n\r\nconfig RTC_DRV_MCP7940X\r\n\ttristate \"Microchip MCP7940X\"\r\n\tdepends on RTC_CLASS && I2C\r\n\thelp\r\n\t  If you say yes here you get support for Microchip\r\n\t  MCP7940x real-time clock chips.\r\n\t  The alarm functionality is not supported.\r\n\r\n\t  This driver can also be built as a module. If so, the module\r\n\t  will be called rtc-mcp7940x.\r\n\r\nconfig RTC_DRV_BQ32K\r\n[...]    <\/xmp><\/code><\/pre>\n<li><samp>drivers\/rtc\/Makefile<\/samp>: <\/li>\n<pre><code><xmp>[...]\r\nobj-$(CONFIG_RTC_DRV_MC13XXX)\t+= rtc-mc13xxx.o\r\nobj-$(CONFIG_RTC_DRV_MCP7940X)\t+= rtc-mcp7940x.o\r\nobj-$(CONFIG_RTC_DRV_MSM6242)\t+= rtc-msm6242.o\r\n[...]<\/xmp><\/code><\/pre>\n<li><samp>drivers\/rtc\/rtc-mcp7940x.c<\/samp>: le source du driver proprement<br \/>\n    dit<\/li>\n<\/ul>\n<h2>Un bon d\u00e9veloppeur kernel porte le quilt chez Armadeus.<\/h2>\n<p>On vient juste de voir quels fichiers il \u00e9tait n\u00e9cessaire de modifier pour<br \/>\najouter notre driver, n\u00e9anmoins notre objectif final est quand m\u00eame de partager<br \/>\nce driver et, dans un premier temps, de le proposer \u00e0 la communaut\u00e9e d&rsquo;Armadeus<br \/>\nProject. Pour cela nous allons avoir besoin de r\u00e9aliser un <a href=\"http:\/\/www.armadeus.com\/wiki\/index.php?title=GIT#Providing_modifications\">patch<\/a>.\n<\/p>\n<p>Le kernel utilis\u00e9 pour le projet armadeus est d\u00e9j\u00e0 noy\u00e9 de patches, si bien<br \/>\nqu&rsquo;il est difficile de g\u00e9rer son pauvre petit patches parmis les autres. Il est<br \/>\ndonc conseill\u00e9 d&rsquo;utiliser le programme <a href=\"http:\/\/www.armadeus.com\/wiki\/index.php?title=Quilt\">Quilt<\/a> pour g\u00e9rer des piles<br \/>\nde patche.<\/p>\n<p><samp>quilt<\/samp> est relativement bien int\u00e9gr\u00e9 au projet; pour s&rsquo;en servir<br \/>\nil est n\u00e9cessaire de <em>quiltifier<\/em> Linux avec la commande<br \/>\nsuivante \u00e0 la racine du projet :<\/p>\n<pre><code>$ .\/scripts\/quiltify\r\n--- What do you want to quiltify today ? ;-)\r\n1) Linux\r\n2) Buildroot\r\n3) U-Boot\r\n\\> 1\r\n<\/code><\/pre>\n<p>Le script va empiler tous les patches n\u00e9cessaire au projet armadeus puis<br \/>\nrecompiler Linux. Une fois fait nous n&rsquo;avons plus qu&rsquo;\u00e0 nous rendre dans<br \/>\nl&rsquo;arborescence du code: <\/p>\n<pre><code><xmp>$ cd buildroot\/output\/build\/linux-2.6.38.8\r\nbuildroot\/output\/build\/linux-2.6.38.8$ quilt applied\r\n[...]\r\n442-freescale-0034-ENGR00126692-3-1-add_drivers_mxc_directory.patch\r\n442-freescale-0034-ENGR00126692-3-add_hw-events_and_srtc_drivers.patch\r\n442-freescale-0034-ENGR00126692-3-add_hw-vpu_driver.patch\r\n442-freescale-0034-ENGR00126692-3-add_iim_driver.patch\r\n442-freescale-0034-ENGR00126692-3-add_mx23_mx25_mx28_security_stuff.patch\r\n442-freescale-0197-ENGR00131650-add_scc2_and_sahara_drivers_without_rng.patch\r\n442-freescale-0535-ENGR00136875-1-Add-function-pgprot_writethru.patch\r\n442-freescale-0536-ENGR00136875-2-make-video-buffer-cacheable-to-improv.patch\r\n444-armadeus-sunrpc-silent_annoying_svc_message_when_mounting_NFS_drives.patch\r\n445-armadeus-add_freescale_mxc_dvfs_driver.patch\r\n446-armadeus-add_freescale_ipu3_driver.patch\r\n447-armadeus-add_freescale_ipu_based_framebuffer_driver.patch\r\n448-armadeus-pps51-adding_HX8369_display_driver.patch\r\n449-armadeus-add_pps51_baseboard.patch\r\n[...]<\/xmp><\/code><\/pre>\n<p>La commande <samp>quilt applied<\/samp> affiche tous les patches appliqu\u00e9s au<br \/>\nnoyau. Pour ajouter notre driver nous allons donc cr\u00e9er un nouveau patche:<\/p>\n<pre><code><xmp>$ quilt new 450-armadeus-add_mcp7940x_rtc_driver.patch<\/xmp><\/code><\/pre>\n<p>Et ajouter les fichiers que nous allons modifier <em>avant<\/em> de les<br \/>\nmodifier.<\/p>\n<pre><code><xmp>\r\n$ quilt add drivers\/rtc\/Makefile\r\n$ quilt add drivers\/rtc\/Kconfig\r\n$ quilt add drivers\/rtc-mcp7940x.c\r\n<\/xmp><\/code><\/pre>\n<p>Nous sommes maintenant pr\u00eat \u00e0 \u00e9crire le code proprement dit, comme nous allons le voir dans le prochain \u00e9pisode<\/p>\n<p><a href=\"http:\/\/www.martoni.fr\/wordpress\/?p=438\">[\u00c0 suivre &#8230;]<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dans l&rsquo;\u00e9pisode pr\u00e9c\u00e9dent nous avons pu d\u00e9montrer fonctionnement du MCP79400 sur une AFP51, nous allons maintenant pouvoir l&rsquo;int\u00e9grer au kernel Linux avec un driver adequate. Plong\u00e9e dans l&rsquo;univers du kernel: fouinons ! L&rsquo;id\u00e9e consiste \u00e0 \u00e9crire le moins possible de &hellip; <a href=\"https:\/\/www.fabienm.eu\/wordpress\/2012\/10\/11\/genese-dun-pilote-linux-part2\/\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[106,10,123],"tags":[],"class_list":["post-419","post","type-post","status-publish","format-standard","hentry","category-embarque","category-informatique","category-kernel-programmation"],"_links":{"self":[{"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/posts\/419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/comments?post=419"}],"version-history":[{"count":15,"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/posts\/419\/revisions"}],"predecessor-version":[{"id":584,"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/posts\/419\/revisions\/584"}],"wp:attachment":[{"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/media?parent=419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/categories?post=419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fabienm.eu\/wordpress\/wp-json\/wp\/v2\/tags?post=419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}