Professional Documents
Culture Documents
Embedded Linux Kernel and Drivers
Embedded Linux Kernel and Drivers
EmbeddedLinuxkernelanddriverdevelopment
MichaelOpdenacker FreeElectrons http://freeelectrons.com/
CreatedwithOpenOffice.org2.0
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
Rightstocopy
Copyright20042007 FreeElectrons feedback@freeelectrons.com Documentsources,updatesandtranslations: http://freeelectrons.com/training/drivers Corrections,suggestions,contributionsand translationsarewelcome!
AttributionShareAlike2.5 Youarefree tocopy,distribute,display,andperformthework tomakederivativeworks tomakecommercialuseofthework Underthefollowingconditions Attribution.Youmustgivetheoriginalauthorcredit. ShareAlike.Ifyoualter,transform,orbuilduponthiswork, youmaydistributetheresultingworkonlyunderalicense identicaltothisone. Foranyreuseordistribution,youmustmakecleartoothersthe licensetermsofthiswork. Anyoftheseconditionscanbewaivedifyougetpermissionfrom thecopyrightholder. Yourfairuseandotherrightsareinnowayaffectedbytheabove. Licensetext:http://creativecommons.org/licenses/bysa/2.5/legalcode
Bestviewedwith...
ThisdocumentisbestviewedwitharecentPDFreader orwithOpenOffice.orgitself! Takeadvantageofinternalorexternalhyperlinks. So,donthesitatetoclickonthem!Seenextpage. Findpagesquicklythankstoautomaticsearch Usethumbnailstonavigateinthedocumentinaquickway IfyourereadingapaperorHTMLcopy,youshouldgetyour copyinPDForOpenOffice.orgformaton http://freeelectrons.com/training/drivers!
Hyperlinksinthisdocument
Linkstoexternalsites Example:http://kernel.org/ UsableinthePDFandODPformats Trythemonthispage!
Kernelsourcefiles Ourlinksletyouviewtheminyourbrowser. Example:kernel/sched.c Kernelsourcecode: Identifiers:functions,macros,typedefinitions... Yougetaccesstotheirdefinition,implementationandw heretheyare used.Thisinvitesyoutoexplorethesourcebyyourself! wait_queue_head_tqueue; init_waitqueue_head(&queue); Tableofcontents Directlyjumptothecorrespondingsections. Example:Kernelconfiguration
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
click
Courseprerequisites
Skillstomaketheselecturesandlabsprofitable FamiliaritywithUnixconceptsanditscommandlineinterface Essentialtomanipulatesourcesandfiles Essentialtounderstandanddebugthesystemthatyoubuild Youshouldreadhttp://freeelectrons.com/training/intro_unix_linux ThisUnixcommandlineinterfacetrainingalsoexplainsU nixconcepts notrepeatedinthisdocument. ExperiencewithCprogramming OnlineCcoursescanbefoundon http://dmoz.org/Computers/Programming/Languages/C/Tutorials/
Contents(1)
Kerneloverview Linuxfeatures Kernelcode Kernelsubsystems Linuxversioningschemeanddevelopmentprocess Legalissues Kerneluserinterface
Contents(2)
Compilingandbooting Linuxkernelsources Kernelsourcemanagers Kernelconfiguration Compilingthekernel Overallsystemstartup Bootloaders Linuxdevicefiles Crosscompilingthekernel Basicdriverdevelopment Loadablekernelmodules Moduleparameters Addingsourcestothetree
Contents(3)
Driverdevelopment Memorymanagement I/Omemoryandports Characterdrivers Debugging Handlingconcurrency Processesandscheduling Sleeping,Interruptmanagement mmap,DMA
Contents(4)
Driverdevelopment Newdevicemodel,sysfs udevandhotplug Adviceandresources Choosingfilesystems Gettinghelpandcontributions Bugreportandpatchsubmission References Lastadvice
Contents(5)
Annexes Quizanswers Ubootdetails Grubdetails UsingEthernetoverUSB Initrunlevels
10
EmbeddedLinuxdriverdevelopment
Kerneloverview
Linuxfeatures
11
Studiedkernelversion:2.6
Linux2.6 Linux2.6.0wasreleasedinDecember2003. Lotsoffeaturesandnewdrivers havebeenaddedataquickpagesincethen. Itisgettingmoreandmoredifficulttogetsupportordrivers forrecenthardwarein2.4.Nocommunitysupportatall! ThesetrainingslidesarecompliantwithLinux2.6.19. It'sbesttostarttolearnaboutthemostrecentfeaturesand updates!
12
Linuxkernelkeyfeatures
Portabilityandhardwaresupport Runsonmostarchitectures. Scalability Canrunonsupercomputersas wellasontinydevices (4MBofRAMisenough). Compliancetostandardsand interoperability. Exhaustivenetworkingsupport. Security Itcan'thideitsflaws.Itscodeis reviewedbymanyexperts. Stabilityandreliability. Modularity Canincludeonlywhatasystem needsevenatruntime. Easytoprogram Youcanlearnfromexistingcode. Manyusefulresourcesonthenet.
13
Supportedhardwarearchitectures
Seethearch/directoryinthekernelsources Minimum:32bitprocessors,withorwithoutMMU 32bitarchitectures(arch/subdirectories) alpha,arm,arm26,avr32,cris,frv,h8300,i386,m32r, m68k,m68knommu,mips,parisc,powerpc,ppc,s390,sh, sparc,um,v850,xtensa 64bitarchitectures: ia64,mips64,powerpc,sh64,sparc64,x86_64 Seearch/<arch>/Kconfig,arch/<arch>/README,or Documentation/<arch>/fordetails
14
EmbeddedLinuxdriverdevelopment
Kerneloverview
Kernelcode
15
ImplementedinC
ImplementedinClikeallUnixsystems. (CwascreatedtoimplementthefirstUnixsystems) AlittleAssemblyisusedtoo: CPUandmachineinitialization,criticallibraryroutines. Seehttp://www.tux.org/lkml/#s153 forreasonsfornotusingC++ (mainreason:thekernelrequiresefficientcode).
16
CompiledwithGNUC
NeedGNUCextensionstocompilethekernel. So,youcannotuseanyANSICcompiler! SomeGNUCextensionsusedinthekernel:
InlineCfunctions Inlineassembly Structurememberinitialization inanyorder(alsoinANSIC99) Branchannotation(seenextpage)
17
Helpgcctooptimizeyourcode!
Usethelikelyandunlikelystatements( include/linux/compiler.h) Example: if(unlikely(err)){ ... } TheGNUCcompilerwillmakeyourcodefaster forthemostlikelycase. Usedinmanyplacesinkernelcode! Don'tforgettousethesestatements!
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
18
NoClibrary
Thekernelhastobestandaloneandcan'tuseuserspacecode. Userspaceisimplementedontopofkernelservices,nottheopposite. Kernelcodehastosupplyitsownlibraryimplementations (stringutilities,cryptography,uncompression...) So,youcan'tusestandardClibraryfunctionsinkernelcode. (printf(),memset(),malloc()...). YoucanalsousekernelCheaders. Fortunately,thekernelprovidessimilarCfunctionsforyour convenience,likeprintk(),memset(),kmalloc()...
19
Managingendianism
Linuxsupportsbothlittleandbigendianarchitectures Eacharchitecturedefines__BIG_ENDIANor__LITTLE_ENDIAN in<asm/byteorder.h> Canbeconfiguredinsomeplatformssupportingboth. Tomakeyourcodeportable,thekerneloffersconversionmacros (thatdonothingwhennoconversionisneeded).Mostusefulones: u32cpu_to_be32(u32); //CPUbyteordertobigendian u32cpu_to_le32(u32); //CPUbyteordertolittleendian u32be32_to_cpu(u32); //LittleendiantoCPUbyteorder u32le32_to_cpu(u32); //BigendiantoCPUbyteorder
20
Kernelcodingguidelines
Neverusefloatingpointnumbersinkernelcode.Yourcode mayberunonaprocessorwithoutafloatingpointunit(likeon arm).Floatingpointcanbeemulatedbythekernel,butthisis veryslow. Defineallsymbolsasstatic,exceptexportedones (toavoidnamespacepollution) SeeDocumentation/CodingStyleformoreguidelines It'salsogoodtofolloworatleastreadGNUcodingstandards: http://www.gnu.org/prep/standards.html
21
EmbeddedLinuxdriverdevelopment
Kerneloverview
Kernelsubsystems
22
Kernelarchitecture
App1 App2 Clibrary Systemcallinterface Process management Memory management Filesystem support Filesystem types CPUsupport code CPU/MMU supportcode Storage drivers Character devicedrivers Network devicedrivers Hardware CPU RAM Storage Device control Networking ... User space
Kernel space
23
Kernelmemoryconstraints
Whocanlookafterthekernel? Nomemoryprotection Accessingillegalmemory locationsresultin(oftenfatal) kerneloopses. Fixedsizestack(8or4KB) Unlikeinuserspace, nowaytomakeitgrow. Kernelmemorycan'tbeswapped out(forthesamereasons).
User process Attempt toaccess SIGSEGV,kill
Kernel Illegal memory location Exception (MMU) Userspacememorymanagement Usedtoimplement: memoryprotection stackgrowth memoryswappingtodisk
24
I/Oschedulers
MissionofI/Oschedulers:reorderreadsandwritestodiskto minimizediskheadmoves(timeconsuming!)
Slower
Faster
25
EmbeddedLinuxdriverdevelopment
Kerneloverview
Linuxversioningschemeanddevelopmentprocess
26
Linuxstablereleases
Majorversions 1majorversionevery2or3years Examples:1.0,2.0,2.4,2.6 Stablereleases 1stablereleaseevery1or2months Examples:2.0.40,2.2.26,2.4.27,2.6.7... Stablereleaseupdates(sinceMarch2005) Updatestostablereleasesuptoseveraltimesaweek Addressonlycriticalissuesinthelateststablerelease Examples:2.6.11.1to2.6.11.7 Evennumber
27
Linuxdevelopmentandtestingreleases
Testingreleases Severaltestingreleasespermonth,beforethenextstableone. Youcancontributetomakingkernelreleasesmorestableby testingthem! Example:2.6.12rc1 Developmentversions Unstableversionsusedbykerneldevelopers beforemakinganewstablemajorrelease Examples:2.3.42,2.5.74 Oddnumber
28
ChangessinceLinux2.6
Since2.6.0,kerneldevelopershavebeenabletointroducelots ofnewfeaturesonebyoneonasteadypace,withouthavingto makemajorchangesinexistingsubsystems. OpeninganewLinux2.7(or2.9)developmentbranchwillbe requiredonlywhenLinux2.6isnolongerabletoaccommodate keyfeatureswithoutundergoingtraumaticchanges. Thankstothis,morefeaturesarereleasedtousersatafasterpace.
29
NostableLinuxinternalAPI(1)
Ofcourse,theexternalAPImustnotchange(systemcalls,/proc, /sys),asitcouldbreakexistingprograms.Newfeaturescanbe added,butLinuxmuststaybackwardcompatiblewithearlierversions. TheinternalkernelAPIcannowundergochangesbetweentwo 2.6.xreleases.Astandalonemodulecompiledforagivenversion maynolongercompileorworkonamorerecentone. SeeDocumentation/stable_api_nonsense.txt inkernelsourcesorreasonswhy. WheneveradeveloperchangesaninternalAPI,(s)healsohasto updateallkernelcodewhichusesit.Nothingbroken! Worksgreatforcodeinthemainlinekerneltree. Difficulttokeepinlineforoutoftreeorclosedsourcedrivers!
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
30
NostableLinuxinternalAPI(2)
USBexample LinuxhasupdateditsUSBinternalAPIatleast3times(fixes, securityissues,supportforhighspeeddevices)andhasnowthe fastestUSBbusspeeds(comparedtoothersystems) WindowsXPalsohadtorewriteitsUSBstack3times.But,because ofclosedsource,binarydriversthatcan'tbeupdated,theyhadto keepbackwardcompatibilitywithallearlierimplementation.Thisis verycostly(development,security,stability,performance). SeeMyths,Lies,andTruthsabouttheLinuxKernel,byGregK.H., fordetailsaboutthekerneldevelopmentprocess: http://kroah.com/log/linux/ols_2006_keynote.html
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
31
Morestabilityforthe2.6kerneltree
Issue:securityfixesonlyreleasedforlast(orlasttwo)stable kernelversions(like2.6.16and2.6.17),andofcourseby distributionsfortheexactversionthatyou'reusing. Somepeopleneedtohavearecentkernel,butwithlongterm supportforsecurityupdates. That'swhyAdrianBunkproposedtomaintaina2.6.16stable tree,foraslongasneeded(years!).
32
What'snewineachLinuxrelease?(1)
commit 3c92c2ba33cd7d666c5f83cc32aa590e794e91b0 Author: Andi Kleen <ak@suse.de> Date: Tue Oct 11 01:28:33 2005 +0200 [PATCH] i386: Don't discard upper 32bits of HWCR on K8 Need to use long long, not long when RMWing a MSR. I think it's harmless right now, but still should be better fixed if AMD adds any bits in the upper 32bit of HWCR. Bug was introduced with the TLB flush filter fix for i386 Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
??!
...
33
What'snewineachLinuxrelease?(2)
Fortunately,asummaryofkeychanges withenoughdetailsisavailableon http://wiki.kernelnewbies.org/LinuxChanges
??!
34
EmbeddedLinuxdriverdevelopment
Kerneloverview
Legalissues
35
Linuxlicense
ThewholeLinuxsourcesareFreeSoftwarereleased undertheGNUGeneralPublicLicense(GPL) Seeourhttp://freeelectrons.com/training/intro_unix_linux trainingfordetailsaboutFreeSoftwareanditslicenses.
36
Linuxkernellicensingconstraints
Constraintsatreleasetime(noconstraintbefore!)
ForanydeviceembeddingLinuxandFreeSoftware,youhaveto releasesourcestotheenduser.Youhavenoobligationtorelease themtoanybodyelse! AccordingtotheGPL,onlyLinuxdriverswithaGPLcompatible licenseareallowed. Proprietarymodulesarelessandlesstolerated. Lawyerssaythattheyareillegal. Proprietarydriversmustnotbestaticallycompiledinthekernel. Youarenotallowedtoreusecodefromotherkerneldrivers(GPL) inaproprietarydriver.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
37
AdvantagesofGPLdrivers
Fromthedriverdeveloper/decisionmakerpointofview
Youdon'thavetowriteyourdriver fromscratch.Youcanreusecode fromsimilarfreesoftwaredrivers. Yougetfreecommunity contributions,support,codereview andtesting.Proprietarydrivers (evenwithsources)don'tgetany. Yourdriverscanbefreelyshipped byothers(mainlybydistributions). Closedsourcedriversoftensupport agivenkernelversion.Asystem withclosedsourcedriversfrom2 differentsourcesisunmanageable. Usersandthecommunitygeta positiveimageofyourcompany. Makesiteasiertohiretalented developers. Youdon'thavetosupplybinary driverreleasesforeachkernel versionandpatchversion(closed sourcedrivers). Moduleshaveallprivileges.You needthesourcestomakesurethat amoduleisnotasecurityrisk. Yourdriverscanbestatically compiledinthekernel.
38
Advantagesofintreekernelmodules
Advantagesofhavingyourdriversinthemainlinekernelsources Onceyoursourcesareacceptedinthemainlinetree,theyare maintainedbypeoplemakingchanges. Costfreemaintenance,securityfixesandimprovements. Easyaccesstoyoursourcesbyusers. Manymorepeoplereviewingyourcode.
39
LegalproprietaryLinuxdrivers(1)
WorkingaroundtheGPLbycreatingaGPLwrapper:
Wrapper SpecialAPI
Linuxkernel
40
LegalproprietaryLinuxdrivers(2)
2examplecases Nvidiagraphiccarddrivers Supportingwirelessnetworkcards usingWindowsdrivers. TheNdisWrapperproject (http://ndiswrapper.sourceforge.net/) implementstheWindowskernelAPI andNDIS(NetworkDriverInterface Specification)APIwithintheLinux kernel. Usefulforusingcardsforwhichno specificationsarereleased.
Drawbacks Stillsomemaintenanceissues. Example:Nvidiaproprietarydriver incompatiblewithX.org7.1. Performanceissues. Wrapperoverheadandoptimizations notavailable. Securityissues.Thedriversare executedwithfullkernelprivileges. ...andallotherissueswithproprietary drivers.Usersloosemostbenefitsof FreeSoftware.
41
Softwarepatentissuesinthekernel
LinuxKerneldriverissuesbecauseofpatentedalgorithms Checkforsoftwarepatentwarningswhenyouconfigureyourkernel!
Patentwarningsissuedinthe documentationofdrivers,showninthe kernelconfigurationinterface. FlashTranslationLayer drivers/mtd/ftl.c IntheUSA,thisdrivercanonlybe usedonPCMCIAhardware (MSystemspatent). NandFlashTranslationLayer IntheUSA,canonlybeusedon DiskOnChiphardware. Networkingcompression drivers/net/bsd_comp.c Can'tsendaCCPresetrequestasa resultofanerrordetectedafter decompression(Motorolapatent). OtherdriversnotacceptedinLinux releasesoralgorithmsnot implementedbecauseofsuchpatents! Otherwise,moreexampleswouldbe availableinthesourcecode.
42
EmbeddedLinuxdriverdevelopment
Kerneloverview
Kerneluserinterface
43
Mountingvirtualfilesystems
Linuxmakessystemandkernelinformationavailableinuser spacethroughvirtualfilesystems(virtualfilesnotexistingonany realstorage).Noneedtoknowkernelprogrammingtoaccessthis!
44
Kerneluserspaceinterface
Afewexamples: /proc/cpuinfo:processorinformation /proc/meminfo:memorystatus /proc/version:versionandbuildinformation /proc/cmdline:kernelcommandline /proc/<pid>/environ:callingenvironment /proc/<pid>/cmdline:processcommandline ...andmanymore!Seebyyourself!
45
Userspaceinterfacedocumentation
Lotsofdetailsaboutthe/procinterfaceareavailablein Documentation/filesystems/proc.txt (almost2000lines)inthekernelsources. Youcanalsofindotherdetailsintheprocmanualpage: manproc SeetheNewDeviceModelsectionfordetailsabout/sys
46
Userspacedevicedrivers(1)
Possibletoimplementdevicedriversinuserspace! Suchdriversjustneedaccesstothedevicesthrough minimum,generickerneldrivers. Examples: Printerandscannerdrivers (ontopofgenericparallelport/USBdrivers) Xdrivers:lowlevelkerneldrivers+userspaceXdrivers.
47
Userspacedevicedrivers(2)
Advantages Noneedforkernelcodingskills.Easiertoreusecodebetweendevices. Driverscanbekeptproprietary. Drivercodecanbekilledanddebugged.Cannotcrashthekernel. Canbeswappedout(kernelcodecannotbe). Lessinkernelcomplexity. Drawbacks Lessstraightforwardtohandleinterrupts. Increasedlatencyvs.kernelcode. Seehttp://freeelectrons.com/redirect/elc2006uld.html forpracticaldetailsandtechniquesforovercomingthedrawbacks.
48
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Linuxkernelsources
49
kernel.org
Downloadthemfrom http://kernel.org
50
Linuxsourcesstructure(1)
arch/<arch> arch/<arch>/mach<mach> COPYING CREDITS crypto/ Documentation/ drivers/ fs/ include/ include/asm<arch> include/linux init/ ipc/ Architecturespecificcode Machine/boardspecificcode Linuxcopyingconditions(G NUGPL) Linuxmaincontributors Cryptographiclibraries Kerneldocumentation.Don'tmissit! Alldevicedrivers(drivers/usb/,etc.) Filesystems(fs/ext3/,etc.) Kernelheaders Architectureandmachinedependentheaders Linuxkernelcoreheaders Linuxinitialization(including ain.c) m Codeusedforprocesscommunication
51
Linuxsourcesstructure(2)
kernel/ lib/ MAINTAINERS Makefile mm/ net/ README REPORTINGBUGS scripts/ security/ sound/ usr/ Linuxkernelcore(verysmall!) Misclibraryroutines(zlib,crc32...) Maintainersofeachkernelpart.V eryuseful! TopLinuxmakefile(setsarchandversion) Memorymanagementcode(smalltoo!) Networksupportcode(notdrivers) Overviewandbuildinginstructions Bugreportinstructions Scriptsforinternalorexternaluse Securitymodelimplementations( ELinux...) S Soundsupportcodeanddrivers Earlyuserspacecode(initramfs)
52
Linuxkernelsize(1)
Linux2.6.17sources: Rawsize:224MB(20400files,approx7millionlinesofcode) bzip2compressedtararchive:40MB(bestchoice) gzipcompressedtararchive:50MB MinimumcompiledLinuxkernelsize(withLinuxTinypatches) approx300KB(compressed),800KB(raw) Whyarethesesourcessobig? Becausetheyincludethousandsofdevicedrivers,manynetwork protocols,supportmanyarchitecturesandfilesystems... TheLinuxcore(scheduler,memorymanagement...)isprettysmall!
53
Linuxkernelsize(2)
SizeofLinuxsourcedirectories(KB)
arch block crypto Documentation drivers fs include init ipc kernel lib mm net scripts security sound usr 0 50000 100000
Linux2.6.17
Measured with: dusapparentsize
150000
54
GettingLinuxsources:2possibilities
Fullsources Theeasiestway,butlongertodownload. Example: http://kernel.org/pub/linux/kernel/v2.6/linux2.6.14.1.tar.bz2 Orpatchagainstthepreviousversion Assumingyoualreadyhavethefullsourcesofthepreviousversion Example: http://kernel.org/pub/linux/kernel/v2.6/patch2.6.14.bz2(2.6.13to2.6.14) http://kernel.org/pub/linux/kernel/v2.6/patch2.6.14.7.bz2(2.6.14to2.6.14.7)
55
Downloadingfullkernelsources
Downloadingfromthecommandline Withawebbrowser,identifytheversionyouneedonhttp://kernel.org Intherightdirectory,downloadthesourcearchiveanditssignature (copyingthedownloadaddressfromthebrowser):
wgethttp://kernel.org/pub/linux/kernel/v2.6/linux2.6.11.12.tar.bz2 wgethttp://kernel.org/pub/linux/kernel/v2.6/linux2.6.11.12.tar.bz2.sign
Checktheelectronicsignatureofthearchive:
gpgverifylinux2.6.11.12.tar.bz2.sign
~/.wgetrcconfigfileforproxies:
http_proxy=<proxy>:<port> ftp_proxy=<proxy>:<port> proxy_user=<user>(ifany) proxy_password=<passwd>(ifany)
Extractthecontentsofthesourcearchive:
tarjxvflinux2.6.11.12.tar.bz2
56
Downloadingkernelsourcepatches(1)
Assumingyoualreadyhavethelinuxx.y.<n1>version Identifythepatchesyouneedonhttp://kernel.orgwithawebbrowser Downloadthepatchfilesandtheirsignature:
Patchfrom2.6.10to2.6.11
wgetftp://ftp.kernel.org/pub/linux/kernel/v2.6/patch2.6.11.bz2 wgetftp://ftp.kernel.org/pub/linux/kernel/v2.6/patch2.6.11.bz2.sign
Patchfrom2.6.11to2.6.11.12(lateststablefixes)
wgethttp://www.kernel.org/pub/linux/kernel/v2.6/patch2.6.11.12.bz2 wgethttp://www.kernel.org/pub/linux/kernel/v2.6/patch2.6.11.12.bz2.sign
57
Downloadingkernelsourcepatches(2)
Checkthesignatureofpatchfiles:
gpgverifypatch2.6.11.bz2.sign gpgverifypatch2.6.11.12.bz2.sign
Applythepatchesintherightorder:
cdlinux2.6.10/ bzcat../patch2.6.11.bz2|patchp1 bzcat../patch2.6.11.12.bz2|patchp1 cd.. mvlinux2.6.10linux2.6.11.12
58
Checkingtheintegrityofsources
Kernelsourceintegritycanbecheckedthrough penPGPdigitalsignatures. O Fulldetailsonhttp://www.kernel.org/signature.html Ifneeded,readhttp://www.gnupg.org/gph/en/manual. tmlandcreateanew h privateandpublickeypairforyourself. ImportthepublicGnuPGkeyofkerneldevelopers:
gpgkeyserverpgp.mit.edurecvkeys0x517D0F0E
59
Anatomyofapatchfile
Apatchfileistheoutputofthediffcommand
diffcommandline diffNrua/Makefileb/Makefile a/Makefile2005030409:27:1508:00 Filedateinfo +++b/Makefile2005030409:27:1508:00 @@1,7+1,7@@ Linenumbersinfiles VERSION=2 Contextinfo:3linesbeforethechange PATCHLEVEL=6 Usefultoapplyapatchwhenlinenumberschanged SUBLEVEL=11 EXTRAVERSION= Removedline(s)ifany +EXTRAVERSION=.1 Addedline(s)ifany NAME=WoozyNumbat
#*DOCUMENTATION*
Contextinfo:3linesafterthechange
60
Usingthepatchcommand
Thepatchcommandapplieschangestofilesinthecurrentdirectory: Makingchangestoexistingfiles Creatingordeletingfilesanddirectories patchusageexamples: patchp<n><diff_file catdiff_file|patchp<n> bzcatdiff_file.bz2|patchp<n> zcatdiff_file.gz|patchp<n> n:numberofdirectorylevelstoskipinthefilepaths
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
61
ApplyingaLinuxpatch
Linuxpatches... Alwaystoapplytothex.y.<z1>version Alwaysproducedforn=1(that'swhateverybodydoes...doittoo!) Downloadableingzipandbzip2(muchsmaller)compressedfiles. Linuxpatchcommandlineexample: cdlinux2.6.10 bzcat../patch2.6.11.bz2|patchp1 cd..;mvlinux2.6.10linux2.6.11 Keeppatchfilescompressed:usefultochecktheirsignaturelater. Youcanstillview(orevenedit)theuncompresseddataw ithvi: vipatch2.6.11.bz2(onthefly(un)compression)
62
Accessingdevelopmentsources(1)
Kerneldevelopmentsourcesarenow managedwithgit YoucanbrowseLinus'gittree(ifyoujustneedtocheckafew files): http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux2.6.git;a= tree Getandcompilegitfromhttp://kernel.org/pub/software/scm/git/ Getandcompilethecogitofrontendfrom http://kernel.org/pub/software/scm/cogito/ Ifyouarebehindaproxy,setU nixenvironmentvariablesdefiningproxy settings.Example: exporthttp_proxy="proxy.server.com:8080" exportftp_proxy="proxy.server.com:8080"
63
Accessingdevelopmentsources(2)
Pickupagitdevelopmenttreeonhttp://kernel.org/git/ Getalocalcopy(clone)ofthistree. Example(Linustree,theoneusedforLinuxstablereleases):
cgclonehttp://kernel.org/pub/scm/linux/kernel/git/torvalds/linux2.6.git orcgclonersync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux2.6.git
64
Onlinekerneldocumentation
http://freeelectrons.com/kerneldoc/ Providedforallrecentkernelreleases Easierthandownloadingkernelsourcestoaccessdocumentation IndexedbyInternetsearchengines Makeskernelpiecesofdocumentationeasiertofind! Unlikemostothersitesofferingthisservicetoo,alsoincludesan HTMLtranslationofkerneldocumentsintheDocBookformat. Neverforgetdocumentationinthekernelsources!It'savery valuablewayofgettinginformationaboutthekernel.
65
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Kernelsourcemanagementtools
66
Cscope
http://cscope.sourceforge.net/ Tooltobrowsesourcecode (mainlyC,butalsoC++orJava) SupportshugeprojectsliketheLinuxkernel Takeslessthan1min.toindexLinux2.6.17 sources(fast!) Canbeusedfromeditorslikevimandemacs. InLinuxkernelsources,runitwith: cscopeRk (seemancscopefordetails)
Allowssearchingcodefor: allreferencestoasymbol globaldefinitions functionscalledbyafunction functionscallingafunction textstring regularexpressionpattern afile filesincludingafile
67
Cscopescreenshot
68
KScope
http://kscope.sourceforge.net AgraphicalfrontendtoCscope MakesiteasytobrowseandedittheLinuxkernelsources Candisplayafunctioncalltree Niceeditingfeatures:symbolcompletion,spellingchecker, automaticindentation... Usageguidelines: UsetheKernelsettingtoignorestandardCincludes. Makesuretheprojectnamedoesn'tcontainblankcharacters!
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
69
KScopescreenshots(1)
Project files
Querywindow
70
KScopescreenshots(2)
Calledfunctionstree
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
71
LXR:LinuxCrossReference
http://sourceforge.net/projects/lxr Genericsourceindexingtool andcodebrowser Webserverbased Veryeasyandfasttouse Identifierortextsearchavailable Veryeasytofindthedeclaration, implementationorusagesofsymbols SupportsCandC++ Supportshugecodeprojects suchastheLinuxkernel (274Minversion2.6.17). Takessometimeandpatiencetosetup (configuration,indexing,serverconfiguration). Initialindexingveryslow: Linux2.6.17:severalhoursonaserver withanAMDSempron2200+CPU. UsingKscopeistheeasiestandfastestsolution formodifiedkernelsources. Youdon'tneedtosetupLXRbyyourself. Useourhttp://lxr.freeelectrons.comserver! OtherserversavailableontheInternet: http://freeelectrons.com/community/kernel/lxr/ ThismakesLXRthesimplestsolution tobrowsestandardkernelsources.
72
LXRscreenshot
73
KetchupEasyaccesstokernelsourcetrees
http://www.selenic.com/ketchup/wiki/ Makesiteasytogetthelatestversionofagivenkernelsourcetree (2.4,2.6,2.6rc,2.6git,2.6mm,2.6rt...) Onlydownloadstheneededpatches. Revertspatcheswhenneededtoapplyamorerecentpatch. Alsochecksthesignatureofsourcesandpatches.
74
Ketchupexamples
Gettheversioninthecurrentdirectory: >ketchupm 2.6.10 Upgradetothelateststableversion: >ketchup2.6tip 2.6.10>2.6.12.5 Applyingpatch2.6.11.bz2 Applyingpatch2.6.12.bz2 Applyingpatch2.6.12.5.bz2 Youcangetbackto2.6.8: >ketchup2.6.8 Moreonhttp://selenic.com/ketchup/wiki/index.cgi/ExampleUsage
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
75
PracticallabKernelsources
TimetostartLab1! Getthesources Checktheauthenticityofsources Applypatches Getfamiliarwiththesources Useakernelsourceindexingtool
76
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Kernelconfiguration
77
Kernelconfigurationoverview
Makefileedition Settingtheversionandtargetarchitectureifneeded Kernelconfiguration:definingwhatfeaturestoincludeinthekernel:
make[config|xconfig|gconfig|menuconfig|oldconfig]
78
Makefilechanges
Toidentifyyourkernelimagewithothersbuildfromthe samesources,usetheEXTRAVERSIONvariable: VERSION=2 PATCHLEVEL=6 SUBLEVEL=15 EXTRAVERSION=acme1 unamerwillreturn: 2.6.15acme1
79
makexconfig
makexconfig NewQtconfigurationinterfaceforLinux2.6:qconf. MucheasiertousethaninLinux2.4! Makesureyouread help>introduction:usefuloptions! Filebrowser:easiertoloadconfigurationfiles
80
makexconfigscreenshot
81
Compilingstaticallyorasamodule
Compiledasamodule(separatefile) CONFIG_ISO9660_FS=m
Compiledstaticallyinthekernel CONFIG_UDF_FS=y
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
82
makemenuconfig
makemenuconfig Sameoldtextinterface asinLinux2.4. Usefulwhennographics areavailable.Pretty convenienttoo! Sameinterfacefoundin othertools:Busybox, buildroot...
83
makeconfig/makegconfig
makeconfig Asksyouthequestions1by1.Extremelylong! makegconfig NewGTKbasedgraphicalconfigurationinterface. Functionalitysimilartothatofmakexconfig.
84
makeoldconfig
makeoldconfig Neededveryoften! Usefultoupgradea.configfilefromanearlierkernel release Issueswarningsforobsoletesymbols Asksforvaluesfornewsymbols Ifyouedita.configfilebyhand,it'sstronglyrecommended torunmakeoldconfigafterwards!
85
makeallnoconfig
makeallnoconfig Onlysetsstronglyrecommendedsettingstoy. Setsallothersettingston. Veryusefulinembeddedsystemstoselectonlytheminimum requiredsetoffeaturesanddrivers. Muchmoreconvenientthanunselectinghundredsoffeatures onebyone!
86
makehelp
makehelp Listsallavailablemaketargets Usefultogetareminder,ortolookforneworadvanced options!
87
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Compilingthekernel
88
Compilingandinstallingthekernel
Compilingstep make Installsteps(loggedasroot!) makeinstall makemodules_install
89
Dependencymanagement
Whenyoumodifyaregularkernelsourcefile,makeonly rebuildswhatneedsrecompiling.That'swhatitisusedfor. However,theMakefileisquitepessimisticabout dependencies.Whenyoumakesignificantchangestothe .configfile,makeoftenredoesmuchofthecompilejob!
90
Compilingfasteronmultiprocessorhosts
Ifyouareusingaworkstationwithnprocessors,youmayroughly divideyourcompiletimebynbycompilingseveralfilesinparallel makej<n> Runsseveraltargetsinparallel,wheneverpossible Usingmakej2ormakej3onsingleprocessorworkstations. Thisdoesn'thelpmuch.Intheory,severalparallelcompilejobskeep theprocessorbusywhileotherprocessesarewaitingforfilestobe readofwritten.Inpractice,youdon'tgetanysignificantspeedup(not morethan10%),unlessyourI/Osareveryslow.
91
Compilingfasterwithccache
http://ccache.samba.org/ CompilercacheforCandC++,alreadyshippedbysomedistributions Muchfasterwhencompilingthesamefileasecondtime! Veryusefulwhen.configfilechangearefrequent. Useitbyaddingaccacheprefix totheCCandHOSTCCdefinitionsinMakefile: CC=ccache$(CROSS_COMPILE)gcc HOSTCC=ccachegcc Performancebenchmarks: 63%:withaFedoraCore3configfile(manymodules!) 82%:withanembeddedLinuxconfigfile(muchfewermodules!)
92
Kernelcompilingtips
Viewthefull(gcc,ld...)commandline: makeV=1 Cleanupgeneratedfiles (toforcerecompilingdrivers): makeclean Removeallgeneratedfiles (mainlytocreatepatches) Caution:alsoremovesyour.configfile! makemrproper
93
Generatedfiles
Createdwhenyourunthemakecommand vmlinux RawLinuxkernelimage,noncompressed. arch/<arch>/boot/zImage zlibcompressedkernelimage (defaultimageonarm)
94
Filescreatedbymakeinstall
/boot/vmlinuz<version> Compressedkernelimage.Sameastheoneinarch/<arch>/boot /boot/System.map<version> Storeskernelsymboladdresses /boot/initrd<version>.img(whenusedbyyourdistribution) InitialRAMdisk,storingthemodulesyouneedtomountyourroot filesystem.makeinstallrunsmkinitrdforyou! /etc/grub.confor/etc/lilo.conf makeinstallupdatesyourbootloaderconfigurationfilestosupport yournewkernel!Itreruns/sbin/liloifLILOisyourbootloader.
95
Filescreatedbymakemodules_install(1)
/lib/modules/<version>/:Kernelmodules+extras build/ Everythingneededtobuildmoremodulesforthiskernel:Makefile, .configfile,modulesymbolinformation(module.symVers), kernelheaders(include/andinclude/asm/) kernel/ Module.ko(KernelObject)files,inthesamedirectorystructureasin thesources.
96
Filescreatedbymakemodules_install(2)
/lib/modules/<version>/(continued) modules.alias Modulealiasesformoduleloadingutilities.Exampleline: aliassoundservice?0snd_mixer_oss modules.dep Moduledependencies(seetheLoadablekernelmodulessection) modules.symbols Tellswhichmoduleagivensymbolbelongsto. Allthefilesinthisdirectoryaretextfiles. Don'thesitatetohavealookbyyourself!
97
Compilingthekernelinanutshell
EditversioninformationintheMakefilefile makexconfig make makeinstall makemodules_install
98
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Overallsystemstartup
99
Linux2.4bootingsequence
Bootloader
ExecutedbythehardwareatafixedlocationinROM/Flash Initializessupportforthedevicewherethekernelimageisfound(localstorage,network, removablemedia) LoadsthekernelimageinRAM Executesthekernelimage(withaspecifiedcommandline)
Kernel
Uncompressesitself Initializesthekernelcoreandstaticallycompileddrivers(neededtoaccesstherootfilesystem) Mountstherootfilesystem(specifiedbytherootkernelparameter) Executesthefirstuserspaceprogram
Firstuserspaceprogram
Configuresuserspaceandstartsupsystemservices
100
Linux2.6bootingsequence
Bootloader
ExecutedbythehardwareatafixedlocationinROM/Flash Initializessupportforthedevicewheretheimagesarefound(localstorage,network,removablemedia) LoadsthekernelimageinRAM Executesthekernelimage(withaspecifiedcommandline)
Kernel
Userspace:/initscript(whatfollowsisjustatypicalscenario)
Userspace:/sbin/init
Runscommandstoconfigurethedevice(ifnotdoneyetintheinitramfs) Startsupsystemservices(daemons,servers)anduserprograms
101
Linux2.6bootingsequencewithinitrd
Bootloader
ExecutedbythehardwareatafixedlocationinROM/Flash Initializessupportforthedevicewheretheimagesarefound(localstorage,network,removablemedia) Loadsthekernelandinitramdisk(initrd)imagesinRAM Executesthekernelimage(withaspecifiedcommandline)
Kernel
Userspace:/linuxrcscriptininitrd(whatfollowsisjustatypicalsequence)
Userspace:/sbin/init
Runscommandstoconfigurethedevice(ifnotdoneyetintheinitrd) Startsupsystemservices(daemons,servers)anduserprograms
102
Linux2.4bootingsequencedrawbacks
Tryingtomountthefilesystemspecified bytherootkernelparameteriscomplex: Needdeviceandfilesystemdriverstobeloaded Specifyingtherootfilesystemrequiresuglyblackmagicdevice naming(suchas/dev/ram0,/dev/hda1...),while/doesn't existyet! Canrequireacomplexinitializationtoimplementwithinthe kernel.Examples:NFS(setupanIPaddress,connecttothe server...),RAID(rootfilesystemonmultiplephysicaldrives)... Inanutshell:toomuchcomplexityinkernelcode!
103
Extrainitramdiskdrawbacks
Initramdisksareimplementedasstandardblockdevices Needaramdiskandfilesystemdriver Fixedinsize:cannoteasilygrowinsize. Anyfreespacecannotbereusedbyanythingelse. Needstobecreatedandmodifiedlikeanyblockdevice: formatting,mounting,editing,unmounting. Rootpermissionsneeded. Likeinanyblockdevice,filesarefirstreadfromthestorage, andthencopiedtothefilecache. SlowandduplicationinRAM!!!
104
Initramfsfeaturesandadvantages(1)
Rootfilesystembuiltininthekernelimage (embeddedasacompressedcpioarchive) Veryeasytocreate(atkernelbuildtime). Noneedforrootpermissions(formountandmknod). Comparedtoinitramdisks, just1filetohandleinthebootloader. AlwayspresentintheLinux2.6kernel(emptybydefault). Justaplaincompressedcpioarchive. Neitherneedsablocknorafilesystemdriver.
105
Initramfsfeaturesandadvantages(2)
ramfs:implementedinthefilecache.N oduplicationinRAM,nofilesystemlayer tomanage.Justusesthesizeofitsfiles.Cangrow ifneeded.
Access tofile VirtualFile System Filesystem driver Block driver Copy Blockstorage File cache
Regular blockdevice
Ramdisk blockdevice
Access tofile
ramfs
File cache
RAM
RAM
106
Initramfsfeaturesandadvantages(3)
Loadedbythekernelearlier. Moreinitializationcodemovedtouserspace! Simplertomountcomplexfilesystemsfromflexibleuserspace scriptsratherthanfromrigidkernelcode.Morecomplexity movedouttouserspace! Nomoremagicnamingoftherootdevice. pivot_rootnolongerneeded.
107
Initramfsfeaturesandadvantages(4)
PossibletoaddnonGPLfiles(firmware,proprietarydrivers) inthefilesystem.Thisisnotlinking,justfileaggregation (notconsideredasaderivedw orkbytheGPL). Possibilitytoremovethesefilesw hennolongerneeded. Stillpossibletouseramdisks. Moretechnicaldetailsaboutinitramfs: seeDocumentation/filesystems/ramfsrootfsinitramfs.txt andDocumentation/earlyuserspace/READMEinkernelsources. Seealsohttp://www.linuxdevices.com/articles/A T4017834659.htmlforanice overviewofinitramfs(byRobLandley,new Busyboxmaintainer).
108
Howtopopulateaninitramfs
UsingCONFIG_INITRAMFS_SOURCE inkernelconfiguration(GeneralSetupsection) Eitherspecifyanexistingcpioarchive Orspecifyalistoffilesordirectories tobeaddedtothearchive. Orspecifyatextspecificationfile(seenextpage) CanuseatinyClibrary:klibc (ftp://ftp.kernel.org/pub/linux/libs/klibc/)
109
Initramfsspecificationfileexample
dir/dev75500 nod/dev/console64400c51 nod/dev/loop064400b70 dir/bin75510001000 slink/bin/shbusybox77700 file/bin/busyboxinitramfs/busybox75500 dir/proc75500 dir/sys75500 dir/mnt75500 file/initinitramfs/init.sh75500 Noneedforrootuseraccess! userid groupid
110
Howtohandlecompressedcpioarchives
Usefulwhenyouwanttobuildthekernelwithareadymadecpio archive.Betterletthekerneldothisforyou!
111
Howtocreateaninitrd
Incaseyoureallyneedaninitrd(why?). mkdir/mnt/initrd ddif=/dev/zeroof=initrd.imgbs=1kcount=2048 mkfs.ext2Finitrd.img mountoloopinitrd.img/mnt/initrd Filltheramdiskcontents:busybox,modules,/linuxrcscript MoredetailsintheFreeSoftwaretoolsforembeddedsystemstraining! umount/mnt/initrd gzipbestcinitrd.img>initrd MoredetailsonDocumentation/initrd.txtinthekernel sources!Alsoexplainspivotrooting.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
112
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Bootloaders
113
2stagebootloaders
Atstartup,thehardwareautomaticallyexecutesthebootloader fromagivenlocation,usuallywithverylittlespace(suchasthe bootsectoronaPCharddisk) Becauseofthislackofspace,2stagesareimplemented:
1ststage:minimumfunctionality.Justaccessesthesecondstageon abiggerlocationandexecutesit. 2ndstage:offersthefullbootloaderfunctionality.Nolimitinwhat canbeimplemented.Canevenbeanoperatingsystemitself!
114
x86bootloaders
LILO:LInuxLOad.OriginalLinuxbootloader.Stillinuse! http://freshmeat.net/projects/lilo/ Supports:x86 GRUB:GRandUnifiedBootloaderfromGNU.Morepowerful. http://www.gnu.org/software/grub/ Supports:x86 SeeourGrubdetailsannexfordetails. SYSLINUX:Utilitiesfornetworkandremovablemediabooting http://syslinux.zytor.com Supports:x86
115
Genericbootloaders
DasUBoot:UniversalBootloaderfromDenkSoftware Themostusedonarm. http://uboot.sourceforge.net/ Supports:arm,ppc,mips,x86 SeeourUbootdetailsannexfordetails. RedBoot:eCosbasedbootloaderfromRedHat http://sources.redhat.com/redboot/ Supports:x86,arm,ppc,mips,sh,m68k... uMon:MicroMonitorgeneralpurpose,multiOSbootloader http://microcross.com/html/micromonitor.html Supports:ARM,ColdFire,SH2,68K,MIPS,PowerPC,Xscale...
116
Otherbootloaders
LAB:LinuxAsBootloader,fromHandhelds.org http://handhelds.org/cgibin/cvsweb.cgi/linux/kernel26/lab/ Idea:useatrimmedLinuxkernelwithonlyfeaturesneededina bootloader(noscheduling,etc.).Reusesflashandfilesystemaccess, LCDinterface,withouthavingtoimplementbootloaderspecificdrivers. Supports:arm(stillexperimental) Andmanymore:lotsofplatformshavetheirown!
117
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Kernelbooting
118
Kernelcommandlineparameters
AsmostCprograms,theLinuxkernelacceptscommandline arguments Kernelcommandlineargumentsarepartofthebootloader configurationsettings. Usefultoconfigurethekernelatboottime,withouthavingto recompileit. Usefultoperformadvancedkernelanddriverinitialization, withouthavingtousecomplexuserspacescripts.
119
Kernelcommandlineexample
HPiPAQh2200PDAbootingexample: root=/dev/ram0\ rw\ init=/linuxrc\ console=ttyS0,115200n8\ console=tty0\ ramdisk_size=8192\ cachepolicy=writethrough Rootfilesystem(firstramdisk) Rootfilesystemmountingmode Firstuserspaceprogram Console(serial) Otherconsole(framebuffer) Miscparameters...
Hundredsofcommandlineparametersdescribedon Documentation/kernelparameters.txt
120
Bootingvariants
XIP(ExecuteInPlace) Thekernelimageisdirectlyexecutedfromthestorage CanbefasterandsaveRAM However,thekernelimagecan'tbecompressed Noinitramfs/initrd Directlymountingthefinalrootfilesystem (rootkernelcommandlineoption) Nonewrootfilesystem Runningthewholesystemfromtheinitramfs.
121
UsefulnessofrootfsonNFS
Oncenetworkingworks,yourrootfilesystemcouldbeadirectoryon yourGNU/Linuxdevelopmenthost,exportedbyNFS(NetworkFile System).Thisisveryconvenientforsystemdevelopment: Makesitveryeasytoupdatefiles(drivermodulesinparticular)on therootfilesystem,withoutrebooting.Muchfasterthanthroughthe serialport. Canhaveabigrootfilesystemevenifyoudon'thavesupportfor internalorexternalstorageyet. Therootfilesystemcanbehuge.Youcanevenbuildnativecompiler toolsandbuildallthetoolsyouneedonthetargetitself(betterto crosscompilethough).
122
NFSbootsetup(1)
OnthePC(NFSserver) Addthebelowlinetoyour/etc/exportsfile:
/home/rootfs192.168.0.202(rw,insecure,sync,no_wdelay,no_root_squash)
Ifnotrunningyet,youmayneedtostartportmap
/etc/init.d/portmapstart
clientaddress
NFSserveroptions
StartorrestartyourNFSserver: FedoraCore:
/etc/init.d/nfsrestart
Debian(Ubuntu,Knoppix,KernelKit):
/etc/init.d/nfsuserserverrestart
123
NFSbootsetup(2)
Onthetarget(NFSclient) CompileyourkernelwithCONFIG_NFS_FS=y, CONFIG_IP_PNP=y(configureIPatboottime) andCONFIG_ROOT_NFS=y Bootthekernelwiththebelowcommandlineoptions:
root=/dev/nfs virtualdevice ip=192.168.1.111:192.168.1.110:192.168.1.100:255.255.255.0:at91:eth0 localIPaddress serverIPaddress gateway netmask hostnamedevice nfsroot=192.168.1.110:/home/nfsroot NFSserverIPaddressDirectoryontheNFSserver
124
Firstuserspaceprogram
Specifiedbytheinitkernelcommandlineparameter Executedattheendofbootingbythekernel Takescareofstartingallotheruserspaceprograms (systemservicesanduserprograms). Getsthe1processnumber(pid) Parentorancestorofalluserspaceprograms Thesystemwon'tletyoukillit. Onlyotheruserspaceprogramcalledbythekernel: /sbin/hotplug
125
/linuxrc
1ofthe2defaultinitprograms (ifnoinitparameterisgiventothekernel) Traditionallyusedininitrdsorinsimplesystemsnotusing /sbin/init. Ismostofthetimeashellscript,basedonaverylightweight shell:nashorbusyboxsh Thisscriptcanimplementcomplextasks:detectingdriversto load,settingupnetworking,mountingpartitions,switching toanewrootfilesystem...
126
Theinitprogram
/sbin/initistheseconddefaultinitprogram Takescareofstartingsystemservices,andeventuallytheuser interfaces(sshd,Xserver...) Alsotakescareofstoppingsystemservices Lightweight,partialimplementationavailablethroughbusybox SeetheInitrunlevelsannexsectionformoredetailsaboutstarting andstoppingsystemserviceswithinit. However,simplestartupscriptsareoftensufficient inembeddedsystems.
127
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Linuxdevicefiles
128
Characterdevicefiles
Accessedthroughasequentialflowofindividualcharacters Characterdevicescanbeidentifiedbytheirctype(lsl):
crwrw1rootuucp4,64Feb232004/dev/ttyS0 crww1jdoetty136,1Feb232004/dev/pts/1 crw1rootroot13,32Feb232004/dev/input/mouse0 crwrwrw1rootroot1,3Feb232004/dev/null
Exampledevices:keyboards,mice,parallelport,IrDA, Bluetoothport,consoles,terminals,sound,video...
129
Blockdevicefiles
Accessedthroughdatablocksofagivensize.Blockscanbe accessedinanyorder. Blockdevicescanbeidentifiedbytheirbtype(lsl):
brwrw1rootdisk3,1Feb232004hda1 brwrw1jdoefloppy2,0Feb232004fd0 brwrw1rootdisk7,0Feb232004loop0 brwrw1rootdisk1,1Feb232004ram1 brw1rootroot8,1Feb232004sda1
Exampledevices:hardorfloppydisks,ramdisks,loopdevices...
130
Devicemajorandminornumbers
Asyoucouldseeinthepreviousexamples, devicefileshave2numbersassociatedtothem: Firstnumber:majornumber Secondnumber:minornumber Majorandminornumbersareusedbythekerneltobindadriver tothedevicefile.Devicefilenamesdon'tmattertothekernel! Tofindoutwhichdriveradevicefilecorrespondsto, orwhenthedevicenameistoocryptic, seeDocumentation/devices.txt.
131
Devicefilecreation
Devicefilesarenotcreatedwhenadriverisloaded. Theyhavetobecreatedinadvance: mknod/dev/<device>[c|b]<major><minor> Examples: mknod/dev/ttyS0c464 mknod/dev/hda1b31
132
Driverswithoutdevicefiles
Theydon'thaveanycorresponding/deventryyoucouldreador writethrougharegularUnixcommand. Networkdrivers Theyarerepresentedbyanetworkdevicesuchasppp0,eth1, usbnet,irda0(listedbyifconfiga). Otherdrivers Oftenintermediateorlowleveldriversjustinterfacingwithother ones.Example:usbcore.
133
PracticallabConfiguringandcompiling
TimetostartLab2! Configureyourkernel Compileit BootitonavirtualPC Modifyarootfilesystemimageby addingentriestothe/dev/directory
134
EmbeddedLinuxdriverdevelopment
CompilingandbootingLinux
Crosscompilingthekernel
135
Makefilechanges
Updatetheversionasusual Youshouldchangethedefaulttargetplatform. Example:ARMplatform,crosscompilercommand:armlinuxgcc ARCH ?=arm CROSS_COMPILE ?=armlinux (TheMakefiledefineslaterCC=$(CROSS_COMPILE)gcc) SeecommentsinMakefilefordetails
136
Configuringthekernel
makexconfig Sameasinnativecompiling. Don'tforgettosettherightboard/machinetype!
137
Readymadeconfigfiles
assabet_defconfigintegrator_defconfigmainstone_defconfig badge4_defconfigiq31244_defconfigmx1ads_defconfig bast_defconfigiq80321_defconfigneponset_defconfig cerfcube_defconfigiq80331_defconfignetwinder_defconfig clps7500_defconfigiq80332_defconfigomap_h2_1610_defconfig ebsa110_defconfigixdp2400_defconfigomnimeter_defconfig edb7211_defconfigixdp2401_defconfigpleb_defconfig enp2611_defconfigixdp2800_defconfigpxa255idp_defconfig ep80219_defconfigixdp2801_defconfigrpc_defconfig epxa10db_defconfigixp4xx_defconfigs3c2410_defconfig footbridge_defconfigjornada720_defconfigshannon_defconfig fortunet_defconfiglart_defconfigshark_defconfig h3600_defconfiglpd7a400_defconfigsimpad_defconfig h7201_defconfiglpd7a404_defconfigsmdk2410_defconfig h7202_defconfiglubbock_defconfigversatile_defconfig hackkit_defconfiglusl7200_defconfig
arch/arm/configsexample
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
138
Usingreadymadeconfigfiles
Defaultconfigurationfilesavailableformanyboards/machines! Checkifoneexistsinarch/<arch>/configs/foryourtarget. Example:ifyoufoundanacme_defconfigfile,youcanrun: makeacme_defconfig Usingarch/<arch>/configs/isaverygoodgoodwayof releasingadefaultconfigurationfileforagroupofusersordevelopers.
139
Crosscompilingsetup
Example IfyouhaveanARMcrosscompilingtoolchain in/usr/local/arm/3.3.2/ YoujusthavetoaddittoyourUnixsearchpath: exportPATH=/usr/local/arm/3.3.2/bin:$PATH Choosingatoolchain SeetheDocumentation/Changesfileinthesourcesfordetails aboutminimumtoolversionsrequirements. Moreabouttoolchains:FreeSoftwaretoolsforembeddedsystems training:http://freeelectrons.com/training/devtools/
140
Buildingthekernel
Run make Copy arch/<platform>/boot/zImage tothetargetstorage Youcancustomizearch/<arch>/boot/install.shsothat makeinstalldoesthisautomaticallyforyou. makeINSTALL_MOD_PATH=<dir>/modules_install andcopy<dir>/to/lib/modules/onthetargetstorage
141
Crosscompilingsummary
EditMakefile:setARCH,CROSS_COMPILEandEXTRA_VERSION Getthedefaultconfigurationforyourmachine: make<machine>_defconfig(ifexistinginarch/<arch>/configs) Refinetheconfigurationsettingsaccordingtoyourrequirements: makexconfig Addthecrosscompilerpathtoyour ATHenvironmentvariable P Compilethekernel:make Copythekernelimagefrom rch/<arch>/boot/tothetarget a Copymodulestoadirectoryw hichyoureplicateonthetarget: makeINSTALL_MOD_PATH=<dir>modules_install
142
PracticallabCrosscompiling
TimetostartLab3! Setupacrosscompilingenvironment ConfigurethekernelMakefile accordingly Crosscompilethekernelforanarm targetplatform
143
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Loadablekernelmodules
144
Loadablekernelmodules(1)
Modules:addagivenfunctionalitytothekernel(drivers, filesystemsupport,andmanyothers) Canbeloadedandunloadedatanytime,onlywhentheir functionalityisneed.Onceloaded,havefullaccesstothe wholekernel.Noparticularprotection. Usefultokeepthekernelimagesizetotheminimum (essentialinGNU/LinuxdistributionsforPCs).
145
Loadablekernelmodules(2)
Usefultosupportincompatibledrivers(eitherloadoneorthe other,butnotboth) Usefultodeliverbinaryonlydrivers(badidea)without havingtorebuildthekernel. Modulesmakeiteasytodevelopdriverswithoutrebooting: load,test,unload,rebuild,load... Modulescanalsobecompiledstaticallyintothekernel.
146
Moduledependencies
Moduledependenciesstoredin /lib/modules/<version>/modules.dep Theydon'thavetobedescribedbythemodulewriter. Theyareautomaticallycomputedduringkernelbuildingfrom moduleexportedsymbols.module2dependsonmodule1if module2usesasymbolexportedbymodule1. Youcanupdatethemodules.depfilebyrunning(asroot) depmoda[<version>]
147
hellomodule
/*hello.c*/ #include<linux/init.h> #include<linux/module.h> #include<linux/kernel.h> staticint__inithello_init(void) { printk(KERN_ALERT"Goodmorrow"); printk(KERN_ALERT"tothisfairassembly.\n"); return0; } staticvoid__exithello_exit(void) { printk(KERN_ALERT"Alas,poorworld,whattreasure"); printk(KERN_ALERT"hastthoulost!\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Greetingmodule"); MODULE_AUTHOR("WilliamShakespeare");
Exampleavailableonhttp://freeelectrons.com/doc/c/hello.c
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
148
Modulelicenseusefulness
Usedbykerneldeveloperstoidentifyissuescomingfrom proprietarydrivers,whichtheycan'tdoanythingabout. Usefulforuserstocheckthattheirsystemis100%free UsefulforGNU/Linuxdistributorsfortheirreleasepolicy checks.
149
Possiblemodulelicensestrings
Availablelicensestringsexplainedininclude/linux/module.h GPL GNUPublicLicensev2orlater GPLv2 GNUPublicLicensev2 GPLandadditional rights DualBSD/GPL GNUPublicLicensev2or BSDlicensechoice DualMPL/GPL GNUPublicLicensev2or Mozillalicensechoice Proprietary Nonfreeproducts
150
Compilingamodule
ThebelowMakefileshouldbereusableforanyLinux2.6module. Justrunmaketobuildthehello.kofile Caution:makesurethereisa[Tab]characteratthebeginningof the$(MAKE)line(makesyntax)
#Makefileforthehellomodule objm:=hello.o KDIR:=/lib/modules/$(shellunamer)/build PWD:=$(shellpwd) default: $(MAKE)C$(KDIR)SUBDIRS=$(PWD)modules Exampleavailableonhttp://freeelectrons.com/doc/c/Makefile
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
[Tab]! (nospaces)
151
Kernellog
Ofcourse,thekerneldoesn'tstoreitslogintoafile! Filesbelongtouserspace. Thekernelkeepsprintkmessagesinacircularbuffer (sothatdoesn'tconsumemorememorywithmanymessages) Kernellogmessagescanbeaccessedfromuserspacethroughsystem calls,orthrough/proc/kmsg Kernellogmessagesarealsodisplayedinthesystemconsole.
152
Accessingthekernellog
Manywaysareavailable!
Watchthesystemconsole syslogd Daemongatheringkernelmessages in/var/log/messages Followchangesbyrunning: tailf/var/log/messages Caution:thisfilegrows! Uselogrotatetocontrolthis dmesg Foundinallsystems Displaysthekernellogbuffer logread Same.Oftenfoundinsmall embeddedsystemswithno /var/log/messagesorno dmesg.ImplementedbyBusybox. cat/proc/kmsg Waitsforkernelmessagesand displaysthem. Usefulwhennoneoftheaboveuser spaceprogramsareavailable(tiny system)
153
Usingthemodule
Needtobeloggedasroot Loadthemodule: insmod./hello.ko Youwillseethefollowinginthekernellog: Goodmorrow tothisfairassembly Nowremovethemodule: rmmodhello Youwillsee: Alas,poorworld,whattreasure hastthoulost!
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
154
Understandingmoduleloadingissues
Whenloadingamodulefails, insmodoftendoesn'tgiveyouenoughdetails! Detailsareavailableinthekernellog. Example:
>insmod./intr_monitor.ko insmod:errorinserting'./intr_monitor.ko':1 Deviceorresourcebusy >dmesg [17549774.552000]Failedtoregisterhandlerfor irqchannel2
155
Moduleutilities(1)
modinfo<module_name> modinfo<module_path>.ko Getsinformationaboutamodule:parameters,license, description.Veryusefulbeforedecidingtoloadamoduleornot. insmod<module_name> insmod<module_path>.ko Triestoloadthegivenmodule,ifneededbysearchingforits .kofilethroughoutthedefaultlocations(canberedefinedby theMODPATHenvironmentvariable).
156
Moduleutilities(2)
modprobe<module_name> Mostcommonusageofmodprobe:triestoloadallthe modulesthegivenmoduledependson,andthenthismodule. Lotsofotheroptionsareavailable. lsmod Displaysthelistofloadedmodules Compareitsoutputwiththecontentsof/proc/modules!
157
Moduleutilities(3)
rmmod<module_name> Triestoremovethegivenmodule modprober<module_name> Triestoremovethegivenmoduleandalldependentmodules (whicharenolongerneededafterthemoduleremoval)
158
Createyourmoduleswithkdevelop
http://kdevelop.orgAvailableinmostdistros. Makesiteasytocreate amodulecodeskeleton fromareadymade template. Canalsobeusedto compileyourmodule.
159
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Moduleparameters
160
hellomodulewithparameters
/*hello_param.c*/ #include<linux/init.h> #include<linux/module.h> #include<linux/moduleparam.h> MODULE_LICENSE("GPL"); /*Acoupleofparametersthatcanbepassedin:howmanytimeswesay hello,andtowhom*/ staticchar*whom="world"; module_param(whom,charp,0); staticinthowmany=1; module_param(howmany,int,0); staticint__inithello_init(void) { inti; for(i=0;i<howmany;i++) printk(KERN_ALERT"(%d)Hello,%s\n",i,whom); return0; } staticvoid__exithello_exit(void) { printk(KERN_ALERT"Goodbye,cruel%s\n",whom); } module_init(hello_init); module_exit(hello_exit);
Exampleavailableonhttp://freeelectrons.com/doc/c/hello_param.c
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
161
Passingmoduleparameters
Throughinsmodormodprobe: insmod./hello_param.kohowmany=2whom=universe Throughmodprobe afterchangingthe/etc/modprobe.conffile: optionshello_paramhowmany=2whom=universe Throughthekernelcommandline,whenthemoduleisbuiltstatically intothekernel:
optionshello_param.howmany=2hello_param.whom=universe modulename moduleparametername moduleparametervalue
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
162
Declaringamoduleparameter
#include<linux/moduleparam.h> module_param( name, /*nameofanalreadydefinedvariable*/ type, /*eitherbyte,short,ushort,int,uint,long, ulong,charp,boolorinvbool (checkedatcompiletime!)*/ perm /*for/sys/module/<module_name>/<param> 0:nosuchmoduleparametervaluefile*/ ); Example intirq=5; module_param(irq,int,S_IRUGO);
163
Declaringamoduleparameterarray
#include<linux/moduleparam.h> module_param_array( name, /*nameofanalreadydefinedarray*/ type, /*sameasinmodule_param*/ num, /*numberofelementsinthearray,orNULL(nocheck?)*/ perm /*sameasinmodule_param*/ ); Example staticintbase[MAX_DEVICES]={0x820,0x840}; module_param_array(base,int,NULL,0);
164
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Addingsourcestothekerneltree
165
Newdirectoryinkernelsources(1)
Toaddanacme_drivers/directorytothekernelsources: Movetheacme_drivers/directorytotheappropriatelocation inkernelsources Createanacme_drivers/Kconfigfile Createanacme_drivers/Makefilefilebasedonthe Kconfigvariables IntheparentdirectoryKconfigfile,add sourceacme_drivers/Kconfig
166
Newdirectoryinkernelsources(2)
IntheparentdirectoryMakefilefile,add
obj$(CONFIG_ACME)+=acme_drivers/(just1condition)
or
objy+=acme_drivers/(severalconditions)
Runmakexconfigandseeyournewoptions! Runmakeandyournewfilesarecompiled!
SeeDocumentation/kbuild/fordetails
167
HowtocreateLinuxpatches
Downloadthelatestkernelsources Makeacopyofthesesources: rsyncalinux2.6.9rc2/linux2.6.9rc2patch/ Applyyourchangestothecopiedsources,andtestthem. Createapatchfile: diffNurplinux2.6.9rc2/\ linux2.6.9rc2patch/>patchfile Alwayscomparethewholesourcestructures (suitableforpatchp1) Patchfilename:shouldrecallwhatthepatchisabout.
ThankstoNicolasRougier(Copyright2003,http://webloria.loria.fr/~rougier/)fortheTuximage
168
PracticallabWritingmodules
TimetostartLab4! Writeakernelmodulewithparameters Setuptheenvironmenttocompileit Accesskernelinternals Adda/procinterface Addthemodulesourcestothekernel sourcetree Createakernelsourcepatch
169
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Memorymanagement
170
Physicalandvirtualmemory
Physicaladdressspace
0xFFFFFFFFF
0xFFFFFFFFF
Virtualaddressspaces
0xFFFFFFFFF
I/Omemory3
Kernel
I/Omemory2 I/Omemory1
0x00000000
Process1
0x00000000
Flash
MMU
Memory Management Unit
CPU
0xFFFFFFFFF
RAM1 RAM0
Process2
0x00000000
0x00000000
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
171
kmallocandkfree
Basicallocators,kernelequivalentsofglibc'smallocandfree.
#include<linux/slab.h> staticinlinevoid*kmalloc(size_tsize,intflags);
size:numberofbytestoallocate flags:priority(seenextpage)
voidkfree(constvoid*objp); Example: data=kmalloc(sizeof(*data),GFP_KERNEL); ... kfree(data);
172
kmallocfeatures
Quick(unlessit'sblockedwaitingformemorytobefreed). Doesn'tinitializetheallocatedarea. Youcanusekcallocorkzalloctogetzeroedmemory. TheallocatedareaiscontiguousinphysicalRAM. Allocatesby2nsizes,andusesafewmanagementbytes. So,don'taskfor1024whenyouneed1000!You'dget2048! Caution:driversshouldn'ttrytokmalloc morethan128KB(upperlimitinsomearchitectures). Minimumallocation:32or64bytes(pagesizedependent).
173
Mainkmallocflags(1)
Definedininclude/linux/gfp.h(GFP:__get_free_pages) GFP_KERNEL Standardkernelmemoryallocation.Mayblock.Fineformostneeds. GFP_ATOMIC AllocatedRAMfrominterrupthandlersorcodenottriggeredbyuser processes.Neverblocks. GFP_USER Allocatesmemoryforuserprocesses.Mayblock.Lowestpriority.
174
Mainkmallocflags(2)
Extraflags(canbeaddedwith|) __GFP_DMAorGFP_DMA AllocateinDMAzone __GFP_ZERO Returnsazeroedpage. __GFP_NOFAIL Mustnotfail.Nevergivesup. Caution:useonlywhen mandatory! __GFP_NORETRY Ifallocationfails,doesn'ttryto getfreepages. Example: GFP_KERNEL|__GFP_DMA Note:almostonly__GFP_DMA orGFP_DMAusedindevice drivers.
175
Slabcaches
Alsocalledlookasidecaches Slab:nameofthestandardLinuxmemoryallocator Slabcaches:Objectsthatcanholdanynumber ofmemoryareasofthesamesize. OptimumuseofavailableRAMandreducedfragmentation. MainlyusedinLinuxcoresubsystems:filesystems(openfiles,inode andfilecaches...),networking...Livestatson/proc/slabinfo. Maybeusefulindevicedriverstoo,thoughnotusedsooften. Linux2.6:usedbyUSBandSCSIdrivers.
176
SlabcacheAPI(1)
#include<linux/slab.h> Creatingacache: cache=kmem_cache_create( name, /*Namefor/proc/slabinfo*/ size, /*Cacheobjectsize*/ flags, /*Options:alignment,DMA...*/ constructor, /*Optional,calledaftereachallocation*/ destructor); /*Optional,calledbeforeeachrelease*/
177
SlabcacheAPI(2)
Allocatingfromthecache: object=kmem_cache_alloc(cache,flags); orobject=kmem_cache_zalloc(cache,flags); Freeinganobject: kmem_cache_free(cache,object); Destroyingthewholecache: kmem_cache_destroy(cache); MoredetailsandanexampleintheLinuxDeviceDriversbook: http://lwn.net/images/pdf/LDD3/ch08.pdf
178
Memorypools
Usefulformemoryallocationsthatcannotfail Kindoflookasidecachetryingtokeepaminimumnumber ofpreallocatedobjectsaheadoftime. Usewithcare:otherwisecanresultinalotofunused memorythatcannotbereclaimed!Useothersolutions wheneverpossible.
179
MemorypoolAPI(1)
#include<linux/mempool.h> Mempoolcreation: mempool=mempool_create( min_nr, alloc_function, free_function, pool_data);
180
MemorypoolAPI(2)
Allocatingobjects: object=mempool_alloc(pool,flags); Freeingobjects: mempool_free(object,pool); Resizingthepool: status=mempool_resize( pool,new_min_nr,flags); Destroyingthepool(caution:freeallobjectsfirst!): mempool_destroy(pool);
181
Memorypoolimplementation
mempool_create Callalloc functionmin_nr times
mempool_alloc
Callalloc function
No Success?
Yes Yes
mempool_free
Addfreed objecttopool
Newobject
182
Memorypoolsusingslabcaches
Idea:useslabcachefunctionstoallocateandfreeobjects. Themempool_alloc_slabandmempool_free_slab functionssupplyalinkwithslabcacheroutines. So,youwillfindmanycodeexampleslookinglike: cache=kmem_cache_create(...); pool=mempool_create( min_nr, mempool_alloc_slab, mempool_free_slab, cache);
183
Allocatingbypages
MoreappropriatewhenyouneedbigslicesofRAM: unsignedlongget_zeroed_page(intflags); Returnsapointertoafreepageandfillsitupwithzeros unsignedlong__get_free_page(intflags); Same,butdoesn'tinitializethecontents unsignedlong__get_free_pages(intflags, unsignedlongorder); ReturnsapointeronanareaofseveralcontiguouspagesinphysicalRAM. order:log2(<number_of_pages>) Ifvariable,canbecomputedfromthesizewiththeget_orderfunction. Maximum:8192KB(MAX_ORDER=11ininclude/linux/mmzone.h)
184
Freeingpages
voidfree_page(unsignedlongaddr); voidfree_pages(unsignedlongaddr, unsignedlongorder); Needtousethesameorderasinallocation.
185
vmalloc
vmalloccanbeusedtoobtaincontiguousmemoryzonesinvirtual addressspace(evenifpagesmaynotbecontiguousinphysical memory). void*vmalloc(unsignedlongsize); voidvfree(void*addr);
186
Memoryutilities
void*memset(void*s,intc,size_tcount); Fillsaregionofmemorywiththegivenvalue. void*memcpy(void*dest, constvoid*src, size_tcount); Copiesoneareaofmemorytoanother. Usememmovewithoverlappingareas. LotsoffunctionsequivalenttostandardClibraryonesdefinedin include/linux/string.h
187
MemorymanagementSummary
Smallallocations kmalloc,kzalloc (andkfree!) Slabcaches Memorypools Biggerallocations __get_free_page[s], get_zeroed_page, free_page[s] vmalloc,vfree Libclikememoryutilities memset,memcopy, memmove...
188
EmbeddedLinuxdriverdevelopment
Driverdevelopment
I/Omemoryandports
189
RequestingI/Oports
/proc/ioportsexample 0000001f:dma1 00200021:pic1 00400043:timer0 00500053:timer1 0060006f:keyboard 00700077:rtc 0080008f:dmapagereg 00a000a1:pic2 00c000df:dma2 00f000ff:fpu 0100013f:pcmcia_socket0 01700177:ide1 01f001f7:ide0 03760376:ide1 0378037a:parport0 03c003df:vga+ 03f603f6:ide0 03f803ff:serial 0800087f:0000:00:1f.0 08000803:PM1a_EVT_BLK 08040805:PM1a_CNT_BLK 0808080b:PM_TMR 08200820:PM2_CNT_BLK 0828082f:GPE0_BLK ...
structresource*request_region( unsignedlongstart, unsignedlonglen, char*name); Triestoreservethegivenregionandreturns ULLif N unsuccessful.Example: request_region(0x0170,8,"ide1"); voidrelease_region( unsignedlongstart, unsignedlonglen); Seeinclude/linux/ioport.hand kernel/resource.c
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
190
Reading/writingonI/Oports
Theimplementationofthebelowfunctionsandtheexactunsigned typecanvaryfromplatformtoplatform! bytes unsignedinb(unsignedport); voidoutb(unsignedcharbyte,unsignedport); words unsignedinw(unsignedport); voidoutw(unsignedcharbyte,unsignedport); "long"integers unsignedinl(unsignedport); voidoutl(unsignedcharbyte,unsignedport);
191
Reading/writingstringsonI/Oports
OftenmoreefficientthanthecorrespondingCloop, iftheprocessorsupportssuchoperations! bytestrings
voidinsb(unsignedport,void*addr,unsignedlongcount); voidoutsb(unsignedport,void*addr,unsignedlongcount);
wordstrings
voidinsw(unsignedport,void*addr,unsignedlongcount); voidoutsw(unsignedport,void*addr,unsignedlongcount);
longstrings
voidinsl(unsignedport,void*addr,unsignedlongcount); voidoutsl(unsignedport,void*addr,unsignedlongcount);
192
RequestingI/Omemory
/proc/iomemexample 000000000009efff:SystemRAM 0009f0000009ffff:reserved 000a0000000bffff:VideoRAMarea 000c0000000cffff:VideoROM 000f0000000fffff:SystemROM 001000003ffadfff:SystemRAM 001000000030afff:Kernelcode 0030b000003b4bff:Kerneldata 3ffae0003fffffff:reserved 40000000400003ff:0000:00:1f.1 4000100040001fff:0000:02:01.0 4000100040001fff:yenta_socket 4000200040002fff:0000:02:01.1 4000200040002fff:yenta_socket 40400000407fffff:PCICardBus#03 4080000040bfffff:PCICardBus#03 40c0000040ffffff:PCICardBus#07 41000000413fffff:PCICardBus#07 a0000000a0000fff:pcmcia_socket0 a0001000a0001fff:pcmcia_socket1 e0000000e7ffffff:0000:00:00.0 e8000000efffffff:PCIBus#01 e8000000efffffff:0000:01:00.0 ...
Equivalentfunctionswiththesameinterface
structresource*request_mem_region( unsignedlongstart, unsignedlonglen, char*name); voidrelease_mem_region( unsignedlongstart, unsignedlonglen);
193
ChoosingI/Oranges
I/Oportandmemoryrangescanbepassedasmodule parameters.Aneasywaytodefinethoseparametersisthrough /etc/modprobe.conf. Modulescanalsotrytofindfreerangesbythemselves (makingmultiplecallstorequest_regionor request_mem_region.
194
MappingI/Omemoryinvirtualmemory
ToaccessI/Omemory,driversneedtohaveavirtualaddress thattheprocessorcanhandle. Theioremapfunctionssatisfythisneed: #include<asm/io.h>; void*ioremap(unsignedlongphys_addr, unsignedlongsize); voidiounmap(void*address); Caution:checkthatioremapdoesn'treturnaNULLaddress!
195
Differenceswithstandardmemory
Readsandwritesonmemorycanbecached Thecompilermaychoosetowritethevalueinacpuregister, andmayneverwriteitinmainmemory. Thecompilermaydecidetooptimizeorreorderreadand writeinstructions.
196
AvoidingI/Oaccessissues
CachingonI/Oportsormemoryalreadydisabled,eitherby thehardwareorbyLinuxinitcode. Memorybarriersaresuppliedtoavoidreordering
Hardwareindependent
#include<asm/kernel.h> voidbarrier(void);
Hardwaredependent
197
AccessingI/Omemory
Directlyreadingfromorwritingtoaddressesreturnedbyioremap (pointerdereferencing)maynotworkonsomearchitectures. Usethebelowfunctionsinstead.Theyarealwaysportableandsafe:
unsignedintioread8(void*addr);(samefor16and32) voidiowrite8(u8value,void*addr);(samefor16and32)
Toreadorwriteaseriesofvalues:
voidioread8_rep(void*addr,void*buf,unsignedlongcount); voidiowrite8_rep(void*addr,constvoid*buf,unsignedlongcount);
Otherusefulfunctions:
voidmemset_io(void*addr,u8value,unsignedintcount); voidmemcpy_fromio(void*dest,void*source,unsignedintcount); voidmemcpy_toio(void*dest,void*source,unsignedintcount);
198
/dev/mem
Usedtoprovideuserspaceapplicationswithdirectaccessto physicaladdresses. ActuallyonlyworkswithaddressesthatarenonRAM(I/O memory)orwithaddressesthathavesomespecialflagsetin thekernel'sdatastructures.Fortunately,doesn'tprovide accesstoanyaddressinphysicalRAM! UsedbyapplicationssuchastheXservertowritedirectlyto devicememory.
199
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Characterdrivers
200
Usefulnessofcharacterdrivers
Exceptforstoragedevicedrivers,mostdriversfordeviceswith inputandoutputflowsareimplementedascharacterdrivers. So,mostdriversyouwillfacewillbecharacterdrivers Youwillregretifyousleepduringthispart!
201
Creatingacharacterdriver
Userspaceneeds Thenameofadevicefilein devtointeract / withthedevicedriverthroughregularfile operations(open,read,write,close...) Thekernelneeds
Copyfromuser Copytouser
Userspace
Read buffer read /dev/foo major/minor Write string write
Read handler
Write handler
Devicedriver Kernelspace
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
202
Declaringacharacterdriver
Devicenumberregistration Needtoregisteroneormoredevicenumbers(major/minorpairs), dependingonthenumberofdevicesmanagedbythedriver. Needtofindfreeones! Fileoperationsregistration Needtoregisterhandlerfunctionscalledwhenuserspaceprograms accessthedevicefiles:open,read,write,ioctl,close...
203
Informationonregistereddevices
Registereddevicesarevisiblein/proc/devices:
Characterdevices: Blockdevices: 1mem 1ramdisk 4/dev/vc/0 3ide0 4tty 8sd 4ttyS 9md 5/dev/tty 22ide1 5/dev/console 65sd 5/dev/ptmx 66sd 6lp 67sd 7vcs 68sd 10misc 69sd 13input 14sound ... Major Registered
number
name
204
dev_tdatatype
Kerneldatatypetorepresentamajor/minornumberpair Alsocalledadevicenumber. Definedin<linux/kdev_t.h> Linux2.6:32bitsize(major:12bits,minor:20bits) Macrotocreatethedevicenumber: MKDEV(intmajor,intminor); Macrotoextracttheminorandmajornumbers: MAJOR(dev_tdev); MINOR(dev_tdev);
205
Allocatingfixeddevicenumbers
#include<linux/fs.h> intregister_chrdev_region( dev_tfrom, /*Startingdevicenumber*/ unsignedcount, /*Numberofdevicenumbers*/ constchar*name); /*Registeredname*/ Returns0iftheallocationwassuccessful. Example
if(register_chrdev_region(MKDEV(202,128), acme_count,acme)){ printk(KERN_ERRFailedtoallocatedevicenumber\n); ...
206
Dynamicallocationofdevicenumbers
Safer:havethekernelallocatefreenumbersforyou! #include<linux/fs.h> intalloc_chrdev_region( dev_t*dev, /*Output:startingdevicenumber*/ unsignedbaseminor, /*Startingminornumber,usually0*/ unsignedcount, /*Numberofdevicenumbers*/ constchar*name); /*Registeredname*/ Returns0iftheallocationwassuccessful. Example
if(alloc_chrdev_region(&acme_dev,0,acme_count,acme)){ printk(KERN_ERRFailedtoallocatedevicenumber\n); ...
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
207
Creatingdevicefiles
Issue:youcannolongercreate/deventriesinadvance! Youhavetocreatethemontheflyafterloadingthedriveraccordingto theallocatedmajornumber. Trick:thescriptloadingthemodulecanthenuse/proc/devices:
module=foo;name=foo;device=foo rmf/dev/$device Caution:backquotes! insmod$module.ko major=`awk"\\$2==\"$name\"{print\\$1}"/proc/devices` mknod/dev/$devicec$major0
208
Fileoperations(1)
Beforeregisteringcharacterdevices,youhavetodefine file_operations(calledfops)forthedevicefiles. Herearethemainones: int(*open)( structinode*,/*Correspondstothedevicefile*/ structfile*);/*Correspondstotheopenfiledescriptor*/ Calledwhenuserspaceopensthedevicefile. int(*release)( structinode*, structfile*); Calledwhenuserspaceclosesthefile.
209
Thefilestructure
Iscreatedbythekernelduringtheopencall.Representsopenfiles. Pointerstothisstructureareusuallycalled"fips". mode_tf_mode; Thefileopeningmode(FMODE_READand/orFMODE_WRITE) loff_tf_pos; Currentoffsetinthefile. structfile_operations*f_op; Allowstochangefileoperationsfordifferentopenfiles! structdentry*f_dentry Usefultogetaccesstotheinode:filp>f_dentry>d_inode.
210
Fileoperations(2)
ssize_t(*read)( structfile*, /*Openfiledescriptor*/ char*, /*Userspacebuffertofillup*/ size_t, /*Sizeoftheuserspacebuffer*/ loff_t*); /*Offsetintheopenfile*/ Calledwhenuserspacereadsfromthedevicefile. ssize_t(*write)( structfile*, /*Openfiledescriptor*/ constchar*, /*Userspacebuffertowritetothedevice*/ size_t, /*Sizeoftheuserspacebuffer*/ loff_t*); /*Offsetintheopenfile*/ Calledwhenuserspacewritestothedevicefile.
211
Exchangingdatawithuserspace(1)
Indrivercode,youcan'tjustmemcpybetween anaddresssuppliedbyuserspaceand theaddressofabufferinkernelspace! Correspondtocompletelydifferent addressspaces(thankstovirtualmemory) Theuserspaceaddressmaybeswappedouttodisk Theuserspaceaddressmaybeinvalid (userspaceprocesstryingtoaccessunauthorizeddata)
212
Exchangingdatawithuserspace(2)
Youmustusededicatedfunctionssuchasthefollowingones inyourreadandwritefileoperationscode: include<asm/uaccess.h> unsignedlongcopy_to_user(void__user*to, constvoid*from, unsignedlongn); unsignedlongcopy_from_user(void*to, constvoid__user*from, unsignedlongn); Makesurethatthesefunctionsreturn0! Anotherreturnvaluewouldmeanthattheyfailed.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
213
Fileoperations(3)
int(*ioctl)(structinode*,structfile*, unsignedint,unsignedlong); Canbeusedtosendspecificcommandstothedevice,whichareneither readingnorwriting(e.g.formattingadisk,configurationchanges).
214
Fileoperationsspecifictoeachopenfile!
Usingthepossibilitytoredefinefileoperationsforeachopenfile.
getPAL video getNTSC video!
open /dev/video
215
Fileoperations(4)
int(*mmap)(structfile*, structvm_area_struct); Askingfordevicememorytobemappedintotheaddressspaceofauser process structmodule*owner; Usedbythekerneltokeeptrackofwho'susingthisstructureandcount thenumberofusersofthemodule.
216
readoperationexample
staticssize_t acme_read(structfile*file,char__user*buf,size_tcount,loff_t*ppos) { /*Theacme_bufaddresscorrespondstoadeviceI/Omemoryarea*/ /*ofsizeacme_bufsize,obtainedwithioremap()*/ intremaining_bytes; /*Numberofbyteslefttoreadintheopenfile*/ remaining_bytes=min(acme_bufsize(int)(*ppos),(int)count); if(remaining_bytes==0){ /*Allread,returning0(EndOfFile)*/ return0; } if(copy_to_user(buf/*to*/,*ppos+acme_buf/*from*/,remaining_bytes)){ returnEFAULT; }else{ /*Increasethepositionintheopenfile*/ *ppos+=remaining_bytes; returnremaining_bytes; } }
Readmethod
Pieceofcodeavailableon http://freeelectrons.com/doc/c/acme_read.c
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
217
writeoperationexample
staticssize_t acme_write(structfile*file,constchar__user*buf,size_tcount,loff_t*ppos) { intremaining_bytes; /*Numberofbytesnotwrittenyetinthedevice*/ remaining_bytes=acme_bufsize(*ppos); if(count>remaining_bytes){ /*Can'twritebeyondtheendofthedevice*/ returnEIO; } if(copy_from_user(*ppos+acme_buf/*to*/,buf/*from*/,count)){ returnEFAULT; }else{ /*Increasethepositionintheopenfile*/ *ppos+=count; returncount; } }
Writemethod
Pieceofcodeavailableon http://freeelectrons.com/doc/c/acme_write.c
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
218
fileoperationsdefinitionexample(3)
Definingafile_operationsstructure
#include<linux/fs.h> staticstructfile_operationsacme_fops= { .owner=THIS_MODULE, .read=acme_read, .write=acme_write, };
219
Characterdeviceregistration(1)
Thekernelrepresentscharacterdriverswithacdevstructure Declarethisstructureglobally(withinyourmodule): #include<linux/cdev.h> staticstructcdev*acme_cdev; Intheinitfunction,allocatethestructureandsetitsfileoperations: acme_cdev=cdev_alloc(); acme_cdev>ops=&acme_fops; acme_cdev>owner=THIS_MODULE;
220
Characterdeviceregistration(2)
Then,nowthatyourstructureisready,addittothesystem: intcdev_add( structcdev*p, /*Characterdevicestructure*/ dev_tdev, /*Startingdevicemajor/minornumber*/ unsignedcount); /*Numberofdevices*/
Example(continued):
if(cdev_add(acme_cdev,acme_dev,acme_count)){ printk(KERN_ERRChardriverregistrationfailed\n);
...
221
Characterdeviceunregistration
Firstdeleteyourcharacterdevice: voidcdev_del(structcdev*p); Then,andonlythen,freethedevicenumber: voidunregister_chrdev_region(dev_tfrom, unsignedcount); Example(continued): cdev_del(acme_cdev); unregister_chrdev_region(acme_dev,acme_count);
222
Linuxerrorcodes
Trytoreporterrorswitherrornumbersasaccurateaspossible! Fortunately,macronamesareexplicitandyoucanremember themquickly. Genericerrorcodes: include/asmgeneric/errnobase.h Platformspecificerrorcodes: include/asm/errno.h
223
Chardriverexamplesummary(1)
staticvoid*acme_buf; staticintacme_bufsize=8192; staticintacme_count=1; staticdev_tacme_dev; staticstructcdev*acme_cdev; staticssize_tacme_write(...){...} staticssize_tacme_read(...){...} staticstructfile_operationsacme_fops= { .owner=THIS_MODULE, .read=acme_read, .write=acme_write };
224
Chardriverexamplesummary(2)
Showshowtohandleerrorsanddeallocateresourcesintherightorder!
staticint__initacme_init(void) { interr; acme_buf=kmalloc(acme_bufsize, GFP_KERNEL); if(!acme_buf){ err=ENOMEM; gotoerr_exit; } if(alloc_chrdev_region(&acme_dev,0, acme_count,acme)){ err=ENODEV; gotoerr_free_buf; } acme_cdev=cdev_alloc(); if(!acme_cdev){ err=ENOMEM; gotoerr_dev_unregister; } acme_cdev>ops=&acme_fops; acme_cdev>owner=THIS_MODULE; if(cdev_add(acme_cdev,acme_dev, acme_count)){ err=ENODEV; gotoerr_free_cdev; } return0; err_free_cdev: kfree(acme_cdev); err_dev_unregister: unregister_chrdev_region( acme_dev,acme_count); err_free_buf: kfree(acme_buf); err_exit: returnerr; } staticvoid__exitacme_exit(void) { cdev_del(acme_cdev); unregister_chrdev_region(acme_dev, acme_count); kfree(acme_buf); }
Completeexamplecodeavailableonhttp://freeelectrons.com/doc/c/acme.c
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
225
Characterdriversummary
Definethefileoperationscallbacksforthedevicefile:read,write,ioctl... Inthemoduleinitfunction,getmajorandminornumberswithalloc_chrdev_region(), initacdevstructurewithyourfileoperationsandaddittothesystemwithcdev_add(). Inthemoduleexitfunction,callcdev_del()andunregister_chrdev_region()
Systemadministration
Systemuser Kernel
Openthedevicefile,read,write,orsendioctl'stoit. Executesthecorrespondingfileoperations
Kernel
Userspace
Kernel
Characterdriverwriter
226
PracticallabCharacterdrivers
TimetostartLab5! Writesimplefile_operations,fora characterdevice,includingioctl controls Getafreedevicenumber Registerthecharacterdevice Usethekmallocandkfreeutilities Exchangedatawithuserspace
227
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Debugging
228
Usefulnessofaserialport
Mostprocessorsfeatureaserialportinterface(usuallyvery wellsupportedbyLinux).Justneedthisinterfacetobe connectedtotheoutside. Easywayofgettingthefirstmessagesofanearlykernel version,evenbeforeitboots.Aminimumkernelwithonly serialportsupportisenough. Oncethekernelisfixedandhascompletedbooting,possible toaccessaserialconsoleandissuecommands. Theserialportcanalsobeusedtotransferfilestothetarget.
229
Whenyoudon'thaveaserialport
Onthehost Notanissue.YoucangetaUSBtoserialconverter.Usuallyvery wellsupportedonLinuxandroughlycosts$20.Thedeviceappears as/dev/ttyUSB0onthehost. Onthetarget CheckwhetheryouhaveanIrDAport.It'susuallyaserialporttoo. IfyouhaveanEthernetadapter,trywithit Youmayalsotrytomanuallyhookuptheprocessorserialinterface (checktheelectricalspecificationsfirst!)
230
Debuggingwithprintk
Universaldebuggingtechniqueusedsincethebeginningof programming(firstfoundincavemendrawings) Printedornotintheconsoleor/var/log/messages accordingtothepriority.Thisiscontrolledbytheloglevel kernelparameter,orthrough/proc/sys/kernel/printk (seeDocumentation/sysctl/kernel.txt) Availablepriorities(include/linux/kernel.h):
#defineKERN_EMERG"<0>"/*systemisunusable*/ #defineKERN_ALERT"<1>"/*actionmustbetakenimmediately*/ #defineKERN_CRIT"<2>"/*criticalconditions*/ #defineKERN_ERR"<3>"/*errorconditions*/ #defineKERN_WARNING"<4>"/*warningconditions*/ #defineKERN_NOTICE"<5>"/*normalbutsignificantcondition*/ #defineKERN_INFO"<6>"/*informational*/ #defineKERN_DEBUG"<7>"/*debuglevelmessages*/
231
Debuggingwith/procor/sys(1)
Insteadofdumpingmessagesinthekernellog,youcanhaveyour driversmakeinformationavailabletouserspace Throughafilein/procor/sys,whichcontentsarehandledby callbacksdefinedandregisteredbyyourdriver. Canbeusedtoshowanypieceofinformation aboutyourdeviceordriver. Canalsobeusedtosenddatatothedriverortocontrolit. Caution:anybodycanusethesefiles. Youshouldremoveyourdebugginginterfaceinproduction!
232
Debuggingwith/procor/sys(2)
Examples cat/proc/acme/stats(dummyexample) Displaysstatisticsaboutyouracmedriver. cat/proc/acme/globals(dummyexample) Displaysvaluesofglobalvariablesusedbyyourdriver.
echo600000>/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed
AdjuststhespeedoftheCPU(controlledbythecpufreqdriver).
233
Debuggingwithioctl
Canusetheioctl()systemcalltoqueryinformation aboutyourdriver(ordevice)orsendcommandstoit. Thiscallstheioctlfileoperationthatyoucanregisterin yourdriver. Advantage:yourdebugginginterfaceisnotpublic. Youcouldevenleaveitwhenyoursystem(oritsdriver)isin thehandsofitsusers.
234
Debuggingwithgdb
Ifyouexecutethekernelfromadebuggeronthesamemachine, thiswillinterferewiththekernelbehavior. However,youcanaccessthecurrentkernelstatewithgdb: gdb/usr/src/linux/vmlinux/proc/kcore uncompressedkernelkerneladdressspace Youcanaccesskernelstructures,followpointers...(readonly!) RequiresthekerneltobecompiledwithCONFIG_DEBUG_INFO (Kernelhackingsection)
235
kgdbkernelpatch
http://kgdb.linsyssoft.com/ Theexecutionofthepatchedkernelisfullycontrolledby gdbfromanothermachine,connectedthroughaserialline. Candoalmosteverything,includinginsertingbreakpointsin interrupthandlers. Supportedarchitectures:i386,x86_64,ppcands390.
236
Kernelcrashanalysiswithkexec
kexecsystemcall:makesitpossibleto callanewkernel,withoutrebootingand goingthroughtheBIOS/firmware. Idea:afterakernelpanic,makethe kernelautomaticallyexecuteanew, cleankernelfromareservedlocationin RAM,toperformpostmortemanalysis ofthememoryofthecrashedkernel. SeeDocumentation/kdump/kdump.txt inthekernelsourcesfordetails.
1.Copydebug kernelto reserved RAM 3.Analyze crashed kernelRAM Standardkernel 2.kernelpanic, kexecdebug kernel Debugkernel
RegularRAM
237
Decryptingoopsmessages
Youoftengetkerneloopsmessageswhen youdevelopdrivers(dereferencingnull pointers,illegalaccessestomemory...). Theygiverawinformationaboutthe functioncallstackandCPUregisters. Youcanmakethesemessagesmore explicitinyourdevelopmentkernel,for examplebyreplacingrawaddressesby symbolnames,bysetting: #GeneralSetup CONFIG_KALLSYMS=y Replacestheksymoopstoolwhich shouldn'tbeusedanymorewithLinux2.6
<1>Unable to handle kernel paging request at virtual address 4d 1b65e8 Unable to handle kernel paging request at virtual address 4d1b65 e8 <1>pgd = c0280000 pgd = c0280000 <1>[4d1b65e8] *pgd=00000000[4d1b65e8] *pgd=00000000 Internal error: Oops: f5 [#1] Internal error: Oops: f5 [#1] Modules linked in:Modules linked in: hx4700_udc hx4700_udc asic3_base asic3_base CPU: 0 CPU: 0 PC is at set_pxa_fb_info+0x2c/0x44 PC is at set_pxa_fb_info+0x2c/0x44 LR is at hx4700_udc_init+0x1c/0x38 [hx4700_udc] LR is at hx4700_udc_init+0x1c/0x38 [hx4700_udc] pc : [<c00116c8>] lr : [<bf00901c>] Not tainted sp : c076df78 ip : 60000093 fp : c076df84 pc : [<c00116c8>] lr : [<bf00901c>] Not tainted sp : c076df78 ip : 60000093 fp : c076df84 r10: 00000002 r9 : c076c000 r8 : c001c7e4 r10: 00000002 r9 : c076c000 r8 : c001c7e4 r7 : 00000000 r6 : c0176d40 r5 : bf007500 r4 : c0176d58 r7 : 00000000 r6 : c0176d40 r5 : bf007500 r4 : c0176d58 r3 : c0176828 r2 : 00000000 r1 : 00000f76 r0 : 80004440 r3 : c0176828 r2 : 00000000 r1 : 00000f76 r0 : 80004440 Flags: nZCvFlags: nZCv IRQs on FIQs on Mode SVC_32 Segme nt user
238
DebuggingwithKprobes
DescribedinDocumentation/kprobes.txtinkernelsources Fairlysimplewayofinsertingbreakpointsinkernelroutines. Nowavailableinstandardkernels. Unlikeprintkdebugging,youneitherhavetorecompilenorrebootyour kernel.Youonlyneedtocompileandloadadedicatedmoduletodeclarethe addressoftheroutineyouw anttoprobe. Nondisruptive,basedonthekernelinterrupthandler Kprobesevenletsyoumodifyregistersandglobalkernelinternals. Supportedarchitectures:i386,x86_64,ia64,ppc64andsparc64. armandmipspatchesavailable fromhttp://tree.celinuxforum.org/CelfPubW iki/PatchArchive
239
Kerneldebuggingtips
Ifyourkerneldoesn'tbootyetorhangswithoutanymessage,it canhelptoactivateLowLeveldebugging (KernelHackingsection,onlyavailableonarm): CONFIG_DEBUG_LL=y TechniquestolocatetheCinstructionwhichcausedanoops: http://kerneltrap.org/node/3648 Moreaboutkerneldebugginginthefree LinuxDeviceDriversbook(Referencessection)!
240
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Concurrentaccesstoresources
241
Sourcesofconcurrencyissues
Thesameresourcescanbeaccessedbyseveralkernelprocessesin parallel,causingpotentialconcurrencyissues Severaluserspaceprogramsaccessingthesamedevicedataor hardware.Severalkernelprocessescouldexecutethesamecodeon behalfofuserprocessesrunninginparallel. Multiprocessing:thesamedrivercodecanberunningonanother processor.ThiscanalsohappenwithsingleCPUswithhyperthreading. Kernelpreemption,interrupts:kernelcodecanbeinterruptedatany time(justafewexceptions),andthesamedatamaybeaccessbyanother processbeforetheexecutioncontinues.
242
Avoidingconcurrencyissues
Avoidusingglobalvariablesandshareddatawheneverpossible (cannotbedonewithhardwareresources) Don'tmakeresourcesavailabletootherkernelprocessesuntil theyarereadytobeused. Usetechniquestomanageconcurrentaccesstoresources. SeeRustyRussell'sUnreliableGuideToLocking Documentation/DocBook/kernellocking/ inthekernelsources.
243
Concurrencyprotectionwithlocks
Process1
Failed Acquirelock Success Criticalcodesection Tryagain Success
Waitlockrelease
Process2
Sharedresource
Releaselock
244
Linuxmutexes
ThemainlockingprimitivesinceLinux2.6.16. Betterthancountingsemaphoreswhenbinaryonesareenough. Mutexdefinition: #include<linux/mutex.h> Initializingamutexstatically: DEFINE_MUTEX(name); Initializingamutexdynamically: voidmutex_init(structmutex*lock);
245
lockingandunlockingmutexes
voidmutex_lock(structmutex*lock); Triestolockthemutex,sleepsotherwise. Caution:can'tbeinterrupted,resultinginprocessesyoucannotkill! intmutex_lock_interruptible(structmutex*lock); Same,butcanbeinterrupted.Ifinterrupted,returnsanonzerovalueand doesn'tholdthelock.Testthereturnvalue!!! intmutex_trylock(structmutex*lock); Neverwaits.Returnsanonzerovalueifthemutexisnotavailable. intmutex_is_locked(structmutex*lock); Justtellswhetherthemutexislockedornot. voidmutex_unlock(structmutex*lock); Releasesthelock.Makesureyoudoitasquicklyaspossible!
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
246
Reader/writersemaphores
Allowsharedaccessbyunlimitedreaders,orbyonly1w riter.Writersgetpriority. voidinit_rwsem(structrw_semaphore*sem); voiddown_read(structrw_semaphore*sem); intdown_read_trylock(structrw_semaphore*sem); intup_read(structrw_semaphore*sem); voiddown_write(structrw_semaphore*sem); intdown_write_trylock(structrw_semaphore*sem); intup_write(structrw_semaphore*sem); Wellsuitedforrarewrites,holdingthesemaphorebriefly.O therwise,readersget starved,waitingtoolongforthesemaphoretobereleased.
247
Whentousemutexesorsemaphores
Beforeandafteraccessingsharedresources Beforeandaftermakingotherresourcesavailabletoother partsofthekernelortouserspace(typicallyandmodule initialization). Insituationswhensleepingisallowed. Semaphoresandmutexesmustonlybeusedinprocess context(managedbythescheduler),andnotininterrupt context(managedbytheCPU,sleepingnotsupported).
248
Spinlocks
Lockstobeusedforcodethatcan'tsleep(criticalsections, interrupthandlers...Beverycarefulnottocallfunctionswhich cansleep! Intendedformultiprocessorsystems Spinlocksarenotinterruptible, don'tsleepandkeepspinninginaloop untilthelockisavailable.
Spinlock Stilllocked?
249
Initializingspinlocks
Static spinlock_tmy_lock=SPIN_LOCK_UNLOCKED; Dynamic voidspin_lock_init(spinlock_t*lock);
250
Usingspinlocks
voidspin_[un]lock(spinlock_t*lock); voidspin_[un]lock_irqsave(spinlock_t*lock, unsignedlongflags); DisablesIRQsonthelocalCPU voidspin_lock_irq(spinlock_t*lock); DisablesIRQswithoutsavingflags.Whenyou'resurethatnobody alreadydisabledinterrupts. voidspin_[un]lock_bh(spinlock_t*lock); Disablessoftwareinterrupts,butnothardwareones Notethatreader/writerspinlocksalsoexist.
251
Deadlocksituations
Theycanlockupyoursystem.Makesuretheyneverhappen!
Don'tcallafunctionthatcantry togetaccesstothesamelock Holdingmultiplelocksisrisky!
Getlock2
Dead Lock!
Getlock1
252
Kernellockvalidator
FromIngoMolnar http://people.redhat.com/mingo/lockdeppatches/ Addsinstrumentationtokernellockingcode Detectviolationsoflockingrulesduringsystemlife,suchas: Locksacquiredindifferentorder (keepstrackoflockingsequencesandcomparesthem). Spinlocksacquiredininterrupthandlersandalsoinprocess contextwheninterruptsareenabled. Notsuitableforproductionsystems butacceptableoverheadindevelopment. Overview:http://lwn.net/Articles/185078/
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
253
Alternativestolocking
Aswehavejustseen,lockingcanhaveastrongnegativeimpacton systemperformance.Insomesituations,youcoulddowithoutit. ByusinglockfreealgorithmslikeReadCopyUpdate(RCU). RCUAPIavailableinthekernel (Seehttp://en.wikipedia.org/wiki/RCU). Whenavailable,useatomicoperations.
254
Atomicvariables
Usefulwhenthesharedresourceisan integervalue Evenaninstructionliken++isnot guaranteedtobeatomiconallprocessors! Header #include<asm/atomic.h> Type atomic_t containsasignedinteger(atleast24bits)
Operationswithoutreturnvalue:
voidatomic_inc(atomic_t*v); voidatomic_dec(atomic_t*v); voidatomic_add(inti,atomic_t*v); voidatomic_sub(inti,atomic_t*v);
Simularfunctionstestingtheresult:
intatomic_inc_and_test(...); intatomic_dec_and_test(...); intatomic_sub_and_test(...);
Functionsreturningthenewvalue:
intatomic_inc_and_return(...); intatomic_dec_and_return(...); intatomic_add_and_return(...); intatomic_sub_and_return(...);
Atomicoperations(mainones) Setorreadthecounter:
atomic_set(atomic_t*v,inti); intatomic_read(atomic_t*v);
255
Atomicbitoperations
Supplyveryfast,atomicoperations Onmostplatforms,applytoanunsignedlongtype. Applytoavoidtypeonafewothers. Set,clear,toggleagivenbit: voidset_bit(intnr,unsignedlong*addr); voidclear_bit(intnr,unsignedlong*addr); voidchange_bit(intnr,unsignedlong*addr); Testbitvalue: inttest_bit(intnr,unsignedlong*addr); Testandmodify(returnthepreviousvalue): inttest_and_set_bit(...); inttest_and_clear_bit(...); inttest_and_change_bit(...);
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
256
EmbeddedLinuxDriverDevelopment
Driverdevelopment
Processesandscheduling
257
Processes
Aprocessisaninstanceofarunningprogram Multipleinstancesofthesameprogramcanberunning. Programcode(textsection)memoryisshared. Eachprocesshasitsowndatasection,addressspace, processorstate,openfilesandpendingsignals. Thekernelhasaseparatedatastructureforeachprocess.
258
Threads
InLinux,threadsarejustimplementedasprocesses! Newthreadsareimplementedasregularprocesses, withtheparticularitythattheyarecreatedwiththesame addressspace,filesystemresources,filedescriptorsand signalhandlersastheirparentprocess.
259
Aprocesslife
Parentprocess
Callsfork() andcreates anewprocess Theprocessiselected bythescheduler Taskterminatedbutits resourcesarenotfreedyet. Waitingforitsparent toacknowledgeitsdeath.
TASK_ZOMBIE
TASK_RUNNING
Readybut notrunning Theprocessispreempted bytoschedulertorun ahigherprioritytask
TASK_RUNNING
Actuallyrunning
TASK_INTERRUPTIBLE orTASK_UNINTERRUPTIBLE
Waiting
260
Processcontext
Userspaceprogramsandsystemcallsarescheduledtogether
Stillhasaccesstoprocess data(openfiles...)
261
Kernelthreads
Thekerneldoesnotonlyreactfromuserspace(systemcalls,exceptions)or hardwareevents(interrupts).Italsorunsitsow nprocesses. Kernelspacearestandardprocessesscheduledandpreemptedinthesame way(youcanviewthemwithtoporps!)Theyjusthavenospecialaddress spaceandusuallyrunforever. Kernelthreadexamples: pdflush:regularlyflushesdirtymemorypagestodisk(filechanges notcommittedtodiskyet). ksoftirqd:managessoftirqs.
262
Processpriorities
Regularprocesses Prioritiesfrom20(maximum)to19(minimum) Onlyrootcansetnegativepriorities (rootcangiveanegativeprioritytoaregularuserprocess) Usethenicecommandtorunajobwithagivenpriority: nicen<priority><command> Usetherenicecommandtochangeaprocesspriority: renice<priority>p<pid>
263
Realtimeprocesses
Realtimeprocessescanbestartedby ootusingthePOSIXAPI r Availablethrough<sched.h>(seemansched.hfordetails) 100realtimeprioritiesavailable SCHED_FIFOschedulingclass: TheprocessrunsuntilcompletionunlessitisblockedbyanI/O ,voluntarily relinquishestheCPU,orispreemptedbyahigherpriorityprocess. SCHED_RRschedulingclass: Difference:theprocessesarescheduledinaRoundRobinw ay. Eachprocessisrununtilitexhaustsamaxtimequantum.Thenother processeswiththesamepriorityarerun,andsoandso...
264
Timerfrequency
TimerinterruptsareraisedeveryHZthofsecond(=1jiffy) HZisnowconfigurable(inProcessortypeandfeatures): 100,250(i386default)or1000. Supportedoni386,ia64,ppc,ppc64,sparc64,x86_64 Seekernel/Kconfig.hz. Compromisebetweensystemresponsivenessandglobalthroughput. Caution:notanyvaluecanbeused.Constraintsapply! AnotherideaistocompletelyturnoffCPUtimerinterruptswhenthe systemisidle(dynamictick):seehttp://muru.com/linux/dyntick. Thissavespower.Supportsarmandi386sofar.
265
O(1)scheduler
Thekernelmaintains2priorityarrays: theactiveandtheexpiredarray. Eacharraycontains140entries(100realtimepriorities+40 regularones),1foreachpriority,eachcontainingalistof processeswiththesamepriority. Thearraysareimplementedinawaythatmakesitpossibleto pickaprocesswiththehighestpriorityinconstanttime (whateverthenumberofrunningprocesses).
266
Choosingandexpiringprocesses
Theschedulerfindsthehighestprocesspriority Itexecutesthefirstprocessinthepriorityqueueforthis priority. Oncetheprocesshasexhausteditstimeslice,itismovedto theexpiredarray. Theschedulergetsbacktoselectinganotherprocesswiththe highestpriorityavailable,andsoon... Oncetheactivearrayisempty,the2arraysareswapped! Again,everythingisdoneinconstanttime!
267
Whenisschedulingrun?
Eachprocesshasaneed_reschedflagwhichisset: Afteraprocessexhausteditstimeslice. Afteraprocesswithahigherpriorityisawakened. Thisflagischecked(possiblycausingtheexecutionofthescheduler) Whenreturningtouserspacefromasystemcall Whenreturningfromaninterrupthandler(includingthecputimer) Schedulingalsohappenswhenkernelcodeexplicitlyruns schedule()orexecutesanactionthatsleeps.
268
Timeslices
Thescheduleralsoprioritizeshighpriorityprocessesbygiving themabiggertimeslice. Initialprocesstimeslice:parent'stimeslicesplitin2 (otherwiseprocesswouldcheatbyforking). Minimumpriority:5msor1jiffy(whicheverislarger) Defaultpriorityinjiffies:100ms Maximumpriority:800ms Note:actuallydependsonHZ. Seekernel/sched.cfordetails.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
269
Dynamicpriorities
Onlyappliestoregularprocesses Forabetteruserexperience,theLinuxschedulerbootsthepriority ofinteractiveprocesses(processeswhichspendmostoftheirtime sleeping,andtaketimetoexhausttheirtimeslices).Such processesoftensleepbutneedtorespondquicklyafterwakingup (example:wordprocessorwaitingforkeypresses). Prioritybonus:upto5points. Conversely,theLinuxschedulerreducesthepriorityofcompute intensivetasks(whichquicklyexhausttheirtimeslices). Prioritypenalty:upto5points.
270
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Sleeping
271
Howtosleep(1)
Sleepingisneededwhenauserprocessiswaitingfordatawhich arenotreadyyet.Theprocessthenputsitselfinawaitingqueue. Staticqueuedeclaration DECLARE_WAIT_QUEUE_HEAD(module_queue); Dynamicqueuedeclaration wait_queue_head_tqueue; init_waitqueue_head(&queue);
272
Howtosleep(2)
Severalwaystomakeakernelprocesssleep
wait_event(queue,condition); SleepsuntilthegivenCexpressionistrue. Caution:can'tbeinterrupted(i.e.bykillingtheclientprocessinuserspace) wait_event_interruptible(queue,condition); Canbeinterrupted wait_event_timeout(queue,condition,timeout); Sleepsandautomaticallyw akesupafterthegiventimeout.
wait_event_interruptible_timeout(queue,condition,timeout);
Sameasabove,interruptible.
273
HowtosleepExample
Fromdrivers/ieee1394/video1394.c wait_event_interruptible( d>waitq, (d>buffer_status[v.buffer] ==VIDEO1394_BUFFER_READY) ); if(signal_pending(current)) returnEINTR;
274
Wakingup!
Typicallydonebyinterrupthandlerswhendatasleeping processesarewaitingforareavailable. wake_up(queue); Wakesupallthewaitingprocessesonthegivenqueue wake_up_interruptible(queue); Doesthesamejob.Usuallycalledwhenprocesseswaited usingwait_event_interruptible.
275
Sleepingandwakingupimplementation
Theschedulerdoesn'tkeepevaluatingthesleepingcondition! wait_event_interruptible(queue,condition); TheprocessisputintheTASK_INTERRUPTIBLEstate. wake_up_interruptible(queue); Forallprocesseswaitinginqueue,conditionisevaluated. Whenitevaluatestotrue,theprocessisputback totheTASK_RUNNINGstate.
276
EmbeddedLinuxdriverdevelopment
Driverdevelopment
Interruptmanagement
277
Needforinterrupts
Internalprocessorinterruptsusedbytheprocessor,for exampleformultitaskscheduling. Externalinterruptsneededbecausemostinternalandexternal devicesareslowerthantheprocessor.Betternotkeepthe processorwaitingforinputdatatobereadyordatatobe output.Whenthedeviceisreadyagain,itsendsaninterrupt togettheprocessorattentionagain.
278
Interrupthandlerconstraints
Notrunfromausercontext: Can'ttransferdatatoandfromuserspace (needtobedonebysystemcallhandlers) InterrupthandlerexecutionismanagedbytheCPU,notby thescheduler.Handlerscan'trunactionsthatmaysleep, becausethereisnothingtoresumetheirexecution. Inparticular,needtoallocatememorywithGFP_ATOMIC. Havetocompletetheirjobquicklyenough: theyshouldn'tblocktheirinterruptlinefortoolong.
279
Registeringaninterrupthandler(1)
Definedininclude/linux/interrupt.h intrequest_irq( Returns0ifsuccessful unsignedintirq, Requestedirqchannel irqreturn_thandler, Interrupthandler unsignedlongirq_flags, Optionmask(seenextpage) constchar*devname, Registeredname void*dev_id); Pointertosomehandlerdata CannotbeNULLandmustbeuniqueforsharedirqs! voidfree_irq(unsignedintirq,void*dev_id);
Whydoesdev_idhavetobeunique?
Answer...
280
Registeringaninterrupthandler(2)
irq_flagsbitvalues(canbecombined,noneisfinetoo) IRQF_DISABLED "Quick"interrupthandler.Runwithallinterruptsdisabledonthecurrentcpu(instead ofjustthecurrentline).Forlatencyreasons,shouldonlybeusedwhenneeded! IRQF_SHARED Runwithinterruptsdisabledonlyonthecurrentirqlineandonthelocalcpu. Theinterruptchannelcanbesharedbyseveraldevices. RequiresahardwarestatusregistertellingwhetheranIRQwasraisedornot. IRQF_SAMPLE_RANDOM Interruptscanbeusedtocontributetothesystementropypoolusedby /dev/randomand/dev/urandom.Usefultogenerategoodrandomnumbers. Don'tusethisiftheinterruptbehaviorofyourdeviceispredictable! IRQF_TIMER Onlyusedfortimerinterrupts.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
281
Whentoregisterthehandler
Eitheratdriverinitializationtime: consumeslotsofIRQchannels! Oratdeviceopentime(firstcalltotheopenfileoperation): betterforsavingfreeIRQchannels. Needtocountthenumberoftimesthedeviceisopened,to beabletofreetheIRQchannelwhenthedeviceisnolonger inuse.
282
Informationoninstalledhandlers
/proc/interrupts
CPU0 0:5616905XTPICtimer#Registeredname 1:9828XTPICi8042 2:0XTPICcascade 3:1014243XTPICorinoco_cs 7:184XTPICIntel82801DBICH4 8:1XTPICrtc 9:2XTPICacpi 11:566583XTPICehci_hcd,uhci_hcd, uhci_hcd,uhci_hcd,yenta,yenta,radeon@PCI:1:0:0 12:5466XTPICi8042 14:121043XTPICide0 15:200888XTPICide1 NMI:0#NonMaskableInterrupts ERR:0
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
283
Totalnumberofinterrupts
cat/proc/stat|grepintr intr819076760929671037701102775520196...
Totalnumber ofinterrupts IRQ1 total IRQ2 IRQ3 total ...
284
Interruptchanneldetection(1)
Usefulwhenadrivercanbeusedindifferentmachines/architectures SomedevicesannouncetheirIRQchannelinaregister Manualdetection
Registeryourinterrupthandlerforallpossiblechannels Askforaninterrupt LetthecalledinterrupthandlerstoretheIRQnumberinaglobalvariable. Tryagainifnointerruptwasreceived Unregisterunusedinterrupthandlers.
285
Interruptchanneldetection(2)
Kerneldetectionutilities mask=probe_irq_on(); Activateinterruptsonthedevice Deactivateinterruptsonthedevice irq=probe_irq_off(mask);
>0:uniqueIRQnumberfound =0:nointerrupt.Tryagain! <0:severalinterruptshappened.Tryagain!
286
Theinterrupthandler'sjob
Acknowledgetheinterrupttothedevice (otherwisenomoreinterruptswillbegenerated) Read/writedatafrom/tothedevice Wakeupanywaitingprocesswaitingforthecompletionof thisread/writeoperation: wake_up_interruptible(&module_queue);
287
Interrupthandlerprototype
irqreturn_t(*handler)( int, //irqnumberofthecurrentinterrupt void*dev_id, //Pointerusedtokeeptrack //ofthecorrespondingdevice. //Usefulwhenseveraldevices //aremanagedbythesamemodule ); Returnvalue: IRQ_HANDLED:recognizedandhandledinterrupt IRQ_NONE:notonadevicemanagedbythemodule.Usefultoshare interruptchannelsand/orreportspuriousinterruptstothekernel.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
288
Tophalfandbottomhalfprocessing(1)
Tophalf:theinterrupthandlermustcompleteasquicklyas possible.Onceitacknowledgedtheinterrupt,itjust schedulesthelengthyrestofthejobtakingcareofthedata, foralaterexecution. Bottomhalf:completingtherestoftheinterrupthandlerjob. Handlesdata,andthenwakesupanywaitinguserprocess. Bestimplementedbytasklets.
289
tophalfandbottomhalfprocessing(2)
Declarethetaskletinthemodulesourcefile: DECLARE_TASKLET(module_tasklet,/*name*/ module_do_tasklet,/*function*/ 0/*data*/ ); Schedulethetaskletinthetophalfpart(interrupthandler): tasklet_schedule(&module_do_tasklet);
290
Disablinginterrupts
Maybeusefulinregulardrivercode... Canbeusefultoensurethataninterrupthandlerwillnotpreemptyour code(includingkernelpreemption) DisablinginterruptsonthelocalCPU:
unsignedlongflags; local_irq_save(flags); //Interruptsdisabled ... local_irq_restore(flags);//Interruptsrestoredtotheirpreviousstate.
Note:mustberunfromwithinthesamefunction!
291
Maskingoutaninterruptline
Usefultodisableinterruptsonaparticularline voiddisable_irq(unsignedintirq); Disablestheirqlineforallprocessorsinthesystem. Waitsforallcurrentlyexecutinghandlerstocomplete. voiddisable_irq_nosync(unsignedintirq); Same,exceptitdoesn'twaitforhandlerstocomplete. voidenable_irq(unsignedintirq); Restoresinterruptsontheirqline. voidsynchronize_irq(unsignedintirq); Waitsforirqhandlerstocomplete(ifany).
292
Checkinginterruptstatus
Canbeusefulforcodewhichcanberunfrombothprocessor interruptcontext,toknowwhetheritisallowedornottocall codethatmaysleep. irqs_disabled() Testswhetherlocalinterruptdeliveryisdisabled. in_interrupt() Testswhethercodeisrunningininterruptcontext in_irq() Testswhethercodeisrunninginaninterrupthandler.
293
Interruptmanagementfun
Inatraininglab,somebodyforgottounregisterahandleron asharedinterruptlineinthemoduleexitfunction.
Whydidhiskernelcrashwithasegmentationfault atmoduleunload?
Answer...
294
Interruptmanagementsummary
Devicedriver Whenthedevicefileisfirstopen, registeraninterrupthandlerforthe device'sinterruptchannel. Interrupthandler Calledwhenaninterruptisraised. Acknowledgetheinterrupt Ifneeded,scheduleatasklettaking careofhandlingdata.Otherwise, wakeupprocesseswaitingforthe data. Tasklet Processthedata Wakeupprocesseswaitingfor thedata Devicedriver Whenthedeviceisnolonger openedbyanyprocess,unregister theinterrupthandler.
295
PracticallabInterrupts
TimetostartLab6! Implementasimpleinterrupthandler Registerthishandleronasharedinterrupt lineonyourGNU/LinuxPC. SeehowLinuxhandles sharedinterruptlines.
296
EmbeddedLinuxdriverdevelopment
Driverdevelopment
mmap
297
mmap(1)
Possibilitytohavepartsofthevirtualaddressspaceofaprogram mappedtothecontentsofafile!
>cat/proc/1/maps(initprocess) startend permoffsetmajor:minorinodemappedfilename 007710000077f000rxp0000000003:051165839/lib/libselinux.so.1 0077f00000781000rwp0000d00003:051165839/lib/libselinux.so.1 0097d00000992000rxp0000000003:051158767/lib/ld2.3.3.so 0099200000993000rp0001400003:051158767/lib/ld2.3.3.so 0099300000994000rwp0001500003:051158767/lib/ld2.3.3.so 0099600000aac000rxp0000000003:051158770/lib/tls/libc2.3.3.so 00aac00000aad000rp0011600003:051158770/lib/tls/libc2.3.3.so 00aad00000ab0000rwp0011700003:051158770/lib/tls/libc2.3.3.so 00ab000000ab2000rwp00ab000000:000 0804800008050000rxp0000000003:05571452/sbin/init(text) 0805000008051000rwp0000800003:05571452/sbin/init(data,stack) 08b4300008b64000rwp08b4300000:000 f6fdf000f6fe0000rwpf6fdf00000:000 fefd4000ff000000rwpfefd400000:000 ffffe000fffff000p0000000000:000
298
mmap(2)
Particularlyusefulwhenthefileisadevicefile! AllowstoaccessdeviceI/Omemoryandportswithouthavingtogo through(expensive)read,writeorioctlcalls! Xserverexample(mapsexcerpt)
startend permoffsetmajor:minorinodemappedfilename 08047000081be000rxp0000000003:05310295/usr/X11R6/bin/Xorg 081be000081f0000rwp0017600003:05310295/usr/X11R6/bin/Xorg ... f4e08000f4f09000rwse000000003:05655295/dev/dri/card0 f4f09000f4f0b000rws4281a00003:05655295/dev/dri/card0 f4f0b000f6f0b000rwse800000003:05652822/dev/mem f6f0b000f6f8b000rwsfcff000003:05652822/dev/mem
Amoreuserfriendlywaytogetsuchinformation:pmap<pid>
299
HowtoimplementmmapUserspace
Openthedevicefile Callthemmapsystemcall(seemanmmapfordetails): void*mmap( void*start, /*Often0,preferredstartingaddress*/ size_tlength, /*Lengthofthemappedarea*/ intprot, /*Permissions:read,write,execute*/ intflags, /*Options:sharedmapping,privatecopy...*/ intfd, /*Openfiledescriptor*/ off_toffset /*Offsetinthefile*/ ); Readfromthereturnvirtualaddressorwritetoit.
300
HowtoimplementmmapKernelspace
Characterdriver:implementammapfileoperation andaddittothedriverfileoperations:
int(*mmap)( structfile*, structvm_area_struct ); /*Openfilestructure*/ /*KernelVMAstructure*/
301
remap_pfn_range()
pfn:pageframenumber Themostsignificantbitsofthepageaddress (withoutthebitscorrespondingtothepagesize). #include<linux/mm.h> intremap_pfn_range( structvm_area_struct*, /*VMAstruct*/ unsignedlongvirt_addr, /*Startinguservirtualaddress*/ unsignedlongpfn, /*pfnofthestartingphysicaladdress*/ unsignedlongsize, /*Mappingsize*/ pgprot_t /*Pagepermissions*/ );
302
Simplemmapimplementation
staticintacme_mmap( structfile*file,structvm_area_struct*vma) { size=vma>vm_startvma>vm_end; if(size>ACME_SIZE) returnEINVAL; if(remap_pfn_range(vma, vma>vm_start, ACME_PHYS>>PAGE_SHIFT, size, vma>vm_page_prot)) returnEAGAIN; return0; }
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
303
devmem2
http://freeelectrons.com/pub/mirror/devmem2.c,byJanDerkBakker Veryusefultooltodirectlypeek(read)orpoke(write)I/Oaddresses mappedinphysicaladdressspacefromashellcommandline! Veryusefulforearlyinteractionexperimentswithadevice,without havingtocodeandcompileadriver. Usesmmapto/dev/mem. Needtorunrequest_mem_regionandsetup/dev/memfirst. Examples(b:byte,h:half,w:word) devmem20x000c0004h(reading) devmem20x000c0008w0xffffffff(writing)
304
EmbeddedLinuxdriverdevelopment
Driverdevelopment
DMA
305
DMAsituations
Synchronous
Auserprocesscallstheread methodofadriver.Thedriver allocatesaDMAbufferandasks thehardwaretocopyitsdata.The processisputinsleepmode. Thehardwarecopiesitsdataand raisesaninterruptattheend. Theinterrupthandlergetsthe datafromthebufferandwakesup thewaitingprocess.
Asynchronous
Thehardwaresendsaninterruptto announcenewdata. Theinterrupthandlerallocatesa DMAbufferandtellsthehardware wheretotransferdata. Thehardwarewritesthedataand raisesanewinterrupt. Thehandlerreleasesthenew data, andwakesuptheneededprocesses.
306
Memoryconstraints
Needtousecontiguousmemoryinphysicalspace Canuseanymemoryallocatedbykmalloc(upto128KB) or__get_free_pages(upto8MB) CanuseblockI/Oandnetworkingbuffers, designedtosupportDMA. Cannotusevmallocmemory (wouldhavetosetupDMAoneachindividualpage)
307
ReservingmemoryforDMA
Tomakesureyou'vegotenoughRAMforbigDMAtransfers... Exampleassumingyouhave32MBofRAM,andneed2MBforDMA: Bootyourkernelwithmem=30 Thekernelwilljustusethefirst30MBofRAM. Drivercodecannowreclaimthe2MBleft: dmabuf=ioremap( 0x1e00000, /*Start:30MB*/ 0x200000 /*Size:2MB*/ );
308
Memorysynchronizationissues
MemorycachingcouldinterferewithDMA BeforeDMAtodevice: NeedtomakesurethatallwritestoDMAbufferarecommitted. AfterDMAfromdevice: BeforedriversreadfromDMAbuffer,needtomakesurethatmemory cachesareflushed. BidirectionalDMA NeedtoflushcachesbeforeandaftertheDMAtransfer.
309
LinuxDMAAPI
ThekernelDMAutilitiescantakecareof: Eitherallocatingabufferinacachecoherentarea, Ormakesurecachesareflushedwhenrequired, ManagingtheDMAmappingsandIOMMU(ifany) SeeDocumentation/DMAAPI.txt fordetailsabouttheLinuxDMAgenericAPI. Mostsubsystems(suchasPCIorUSB)supplytheirownDMAAPI, derivedfromthegenericone.Maybesufficientformostneeds.
310
LimitedDMAaddressrange?
Bydefault,thekernelassumesthatyourdevicecanDMAtoany 32bitaddress.Nottrueforalldevices! Totellthekernelthatitcanonlyhandle24bitaddresses: if(dma_set_mask(dev, /*devicestructure*/ 0xffffff /*24bits*/ )) use_dma=1; /*AbletouseDMA*/ else use_dma=0; /*WillhavetodowithoutDMA*/
311
CoherentorstreamingDMAmappings
Coherentmappings CansimultaneouslybeaccessedbytheCPUanddevice. So,havetobeinacachecoherentmemoryarea. Usuallyallocatedforthewholetimethemoduleisloaded. Canbeexpensivetosetupanduse. Streamingmappings(recommended) Setupforeachtransfer. KeepDMAregistersfreeonthephysicalhardwareregisters. Someoptimizationsalsoavailable.
312
Allocatingcoherentmappings
Thekerneltakescareofboththebufferallocationandmapping: include<asm/dmamapping.h> void* /*Output:bufferaddress*/ dma_alloc_coherent( structdevice*dev, /*devicestructure*/ size_tsize, /*Neededbuffersizeinbytes*/ dma_addr_t*handle,/*Output:DMAbusaddress*/ gfp_tgfp /*StandardGFPflags*/ ); voiddma_free_coherent(structdevice*dev, size_tsize,void*cpu_addr,dma_addr_thandle);
313
DMApools(1)
dma_alloc_coherentusuallyallocatesbuffersw ith __get_free_pages(minimum:1page). YoucanuseDMApoolstoallocatesmallercoherentmappings: <includelinux/dmapool.h> Createadmapool: structdma_pool* dma_pool_create( constchar*name, structdevice*dev, size_tsize, size_talign, size_tallocation );
314
DMApools(2)
Allocatefrompool void*dma_pool_alloc( structdma_pool*pool, gfp_tmem_flags, dma_addr_t*handle ); Freebufferfrompool voiddma_pool_free( structdma_pool*pool, void*vaddr, dma_addr_tdma); Destroythepool(freeallbuffersfirst!) voiddma_pool_destroy(structdma_pool*pool);
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
315
Settingupstreamingmappings
Worksonbuffersalreadyallocatedbythedriver
<includelinux/dmapool.h> dma_addr_tdma_map_single( structdevice*, /*devicestructure*/ void*, /*input:buffertouse*/ size_t, /*buffersize*/ enumdma_data_direction /*EitherDMA_BIDIRECTIONAL, DMA_TO_DEVICEorDMA_FROM_DEVICE*/ ); voiddma_unmap_single(structdevice*dev,dma_addr_t handle,size_tsize,enumdma_data_directiondir);
316
DMAstreamingmappingnotes
Whenthemappingisactive:onlythedeviceshouldaccessthebuffer (potentialcacheissuesotherw ise). TheCPUcanaccessthebufferonlyafterunmapping! Anotherreason:ifrequired,thisA PIcancreateanintermediate ounce b buffer(usedifthegivenbufferisnotusableforD MA). PossiblefortheCPUtoaccessthebufferwithoutunmappingit,usingthe dma_sync_single_for_cpu()(ownershiptocpu)and dma_sync_single_for_device()functions(ownershipbackto device). TheLinuxAPIalsosupportscatter/gatherD MAstreamingmappings.
317
EmbeddedLinuxdriverdevelopment
Driverdevelopment
NewDeviceModel
318
DeviceModelfeatures(1)
Originallycreatedtomakepowermanagementsimpler Nowgoesmuchbeyond. Usedtorepresentthearchitectureandstateofthesystem Hasarepresentationinuserspace:sysfs Nowthepreferredinterfacewithuserspace(insteadof/proc) Easytoimplementthankstothedeviceinterface: include/linux/device.h
319
Devicemodelfeatures(2)
Allowstoviewthesystemforseveralpointsofview: Fromdevicesexistinginthesystem:theirpow erstate,thebustheyareattached to,andthedriverresponsibleforthem. Fromthesystembusstructure:w hichbusisconnectedtowhichbus(e.g.USB buscontrolleronthePCIbus),existingdevicesanddevicespotentially accepted(withtheirdrivers) Fromavailabledevicedrivers:w hichdevicestheycansupport,andw hichbus typetheyknowabout. Fromthevariouskinds("classes") fdevices:input,net,sound...Existing o devicesforeachclass.Convenienttofindalltheinputdevicesw ithoutactually knowinghowtheyarephysicallyconnected.
320
sysfs
UserspacerepresentationoftheDeviceModel. Configureitwith CONFIG_SYSFS=y(Filesystems>Pseudofilesystems) Mountitwith mounttsysfsnone/sys Spendtimeexploring/sysonyourworkstation!
321
sysfstools
http://linuxdiag.sourceforge.net/Sysfsutils.html libsysfsThelibrary'spurposeistoprovideaconsistentand stableinterfaceforqueryingsystemdeviceinformationexposed throughsysfs.Usedbyudev(seelater). systoolAutilitybuiltuponlibsysfsthatlistsdevicesby bus,class,andtopology.
322
Thedevicestructure
Declaration Thebasedatastructureisstructdevice,definedin include/linux/device.h Inreallife,youwillratheruseastructurecorrespondingto thebusyourdeviceisattachedto:structpci_dev, structusb_device... Registration Stilldependingonthedevicetype,specificregisterand unregisterfunctionsareprovided
323
Deviceattributes
Definingdeviceattributestoberead/writtenfrom/byuserspace
structdevice_attribute{ structattributeattr; ssize_t(*show)(structdevice*dev,char*buf,size_tcount,loff_toff); ssize_t(*store)(structdevice*dev,constchar*buf,size_tcount,loff_toff); }; #defineDEVICE_ATTR(name,mode,show,store)
Adding/removingfromthedevicedirectory
intdevice_create_file(structdevice*dev,structdevice_attribute*entry); voiddevice_remove_file(structdevice*dev,structdevice_attribute*attr);
Example
/*Createsafilenamed"power"witha0644(rwrr)mode*/ DEVICE_ATTR(power,0644,show_power,store_power); device_create_file(dev,&dev_attr_power); device_remove_file(dev,&dev_attr_power);
324
Thedevicedriverstructure
Declaration
structdevice_driver{ /*Omittedafewinternals*/ char *name; structbus_type *bus; int(*probe) (structdevice*dev); int(*remove) (structdevice*dev); void(*shutdown)(structdevice*dev); int(*suspend)(structdevice*dev,u32state,u32level); int(*resume) (structdevice*dev,u32level); };
Registration
externintdriver_register(structdevice_driver*drv); externvoiddriver_unregister(structdevice_driver*drv);
Attributes
Availableinasimilarway
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
325
DeviceModelreferences
Veryusefulandcleardocumentationinthekernelsources! Documentation/drivermodel/ Documentation/filesystems/sysfs.txt
326
EmbeddedLinuxdriverdevelopment
Driverdevelopment
udevandhotplug
327
/devissuesandlimitations
OnRedHat9,18000entriesin/dev! Allentriesforallpossibledevices hadtobecreatedatsysteminstallation. Neededanauthoritytoassignmajornumbers http://lanana.org/:LinuxAssignedNamesandNumbersAuthority Notenoughnumbersin2.4,limitsextendedin2.6. Userspaceneitherknewwhatdeviceswerepresentinthesystem, norwhichrealdevicecorrespondedtoeach/deventry.
328
devfssolutionandlimitations
devfs:afirstsolutionimplementedinLinux2.3. Onlyshowedpresentdevices Butuseddifferentnamesasin/dev,causingissuesinscripts. Butnoflexibilityindevicenames,unlikewith/dev/,e.g.the1st IDEdiskdevicehadtobecalledeither/dev/hdaor /dev/ide/hd/c0b0t0u0. Butdidn'tallowdynamicmajorandminornumberallocation. Butrequiredtostorethedevicenamingpolicyinkernelmemory. KeptforeverinkernelRAMevenwhennolongerneeded. devfswascompletelyremovedinLinux2.6.18.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
329
Theudevsolution
TakesadvantageofsysfsintroducedbyLinux2.6. CreatedbyGregKroahHartman,ahugecontributor. Otherkeycontributors:KaySievers,DanStekloff. Entirelyinuserspace. Automaticallycreates/removesdeviceentries in/dev/accordingtoinserted/removeddevices. Majorandminordevicetransmittedbythekernel. Requiresnochangetodrivercode. Fast:writteninC Smallsize(udevd:54KBinUbuntu6.10).
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
330
hotplughistory
udevwasfirstimplementedthroughthehotpluginfrastructure: IntroducedinLinux2.4.PioneeredbyUSB. Wheneveradevicewasinsertedorremoved,thekernelwasexecuting the/sbin/hotplugprogramtonotifyuserspaceprograms. Foreachsubsystem(USB,PCI...),/sbin/hotplugwasthenrunning scripts(agents)takingcareofidentifyingthehardwareand inserting/removingtherightdrivermodules. Linux2.6:mucheasierdeviceidentificationthankstosysfs. udevwasoneoftheagentsrunby/sbin/hotplug.
331
udevissueswithhotplug
sysfstimingissues. Outoforderexecutionofhotplugprocesses. Outofmemoryissueswhentoomanyprocesses areruninaveryshorttime. Eventually,udevtookoverseveralpartsofthehotpluginfrastructureand completelyreplacedit.
332
Startingudev(1)
Attheverybeginningofuserspacestartup,the dev/directoryis / mountedasatmpfsfilesystem. /dev/ispopulatedwithstaticdevicesavailablein /lib/udev/devices/:
Ubuntu6.10example:
crw1rootroot5,12007013104:18console lrwxrwxrwx1rootroot112007013104:18core>/proc/kcore lrwxrwxrwx1rootroot132007013104:18fd>/proc/self/fd crwr1rootkmem1,22007013104:18kmem brw1rootroot7,02007013104:18loop0 lrwxrwxrwx1rootroot132007013104:18MAKEDEV>/sbin/MAKEDEV drwxrxrx2rootroot40962007013104:18net crw1rootroot1,32007013104:18null crw1rootroot108,02007013104:18ppp drwxrxrx2rootroot40962006101614:39pts drwxrxrx2rootroot40962006101614:39shm lrwxrwxrwx1rootroot242007013104:18sndstat>/proc/asound/oss/sndstat lrwxrwxrwx1rootroot152007013104:18stderr>/proc/self/fd/2 lrwxrwxrwx1rootroot152007013104:18stdin>/proc/self/fd/0 lrwxrwxrwx1rootroot152007013104:18stdout>/proc/self/fd/1
333
Startingudev(2)
Theudevddaemonisstarted. Itlistenstoueventsfromthedrivercore, whicharesentwheneverdevicesareinsertedorremoved. Theudevddaemonreadsandparsesalltherulesfoundin/etc/udev/rules.d/ andkeepstheminmemory. Wheneverrulesareadded,removedormodified, udevdreceivesaninotifyeventandupdatesits rulesetinmemory. Whenaneventisreceived,udevdstartsaprocessto: trytomatchtheeventagainstudevrules, create/removedevicefiles, andrunprograms(toload/removeadriver, tonotifyuserspace...)
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
334
Eventqueuemanagement
udevdtakescareofprocessingeventsintherightorder. Thisisusefultoprocesseventsaftertheonesthendependon (example:partitioneventsneedtheparentblockdeviceeventprocessingtobe complete,toaccessitsinformationintheudevdatabase). udevdalsolimitsthenumberofprocessesitstarts.W henthelimitis exceeded,onlyeventscarryingthe IMEOUTkeyareimmediatelyprocessed. T The/etc/.udev/queue/directoryrepresentscurrentlyrunningorqueued events.Itcontainssymboliclinkstothecorrespondingsysfsdevices.The directoryisremovedafterremovingthelastlink. Eventprocesseswhichfailedarerepresentedby etc/.udev/failed/. / Symboliclinksinthisdirectoryareremovedw henaneventforthesame deviceissuccessfullyprocessed.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
335
netlinksockets
Kernelnetlinksocketsareusedtocarryuevents.Advantages: Theyareasynchronous.Messagesarequeued.Thereceivercan choosetoprocessmessagesatitsbestconvenience. Otheruserspacekernelspacecommunicationmeansare synchronous:systemcalls,ioctls,/proc/and/sys. Systemcallshavetobecompiledstaticallyintothekernel. Theycannotbeaddedbymodulebaseddevicedrivers. Multicastingisavailable.Severalapplicationscanbenotified. Seehttp://www.linuxjournal.com/article/7356 foraverynicedescriptionofnetlinksockets.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
336
ueventmessageexample
ExampleinsertingaUSBmouse
recv(4, //socketid "add@/class/input/input9/mouse2\0 //message ACTION=add\0 //actiontype DEVPATH=/class/input/input9/mouse2\0 //pathin/sys SUBSYSTEM=input\0 //subsystem(class) SEQNUM=1064\0 //sequencenumber PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/22/22:1.0\0 //devicepathin/sys PHYSDEVBUS=usb\0 //bus PHYSDEVDRIVER=usbhid\0 //driver MAJOR=13\0 //majornumber MINOR=34\0", //minornumber 2048, //messagebuffersize 0) //flags =221 //actualmessagesize
337
udevrules
Whenaudevrulematchingeventinformationisfound,itcanbeused: Todefinethenameandpathofadevicefile. Todefinethegroupandpermissionsofadevicefile. Toexecuteaspecifiedprogram. Rulefilesareprocessedinlexicalorder.
338
udevnamingcapabilities
Devicenamescanbedefined fromalabelorserialnumber, fromabusdevicenumber, fromalocationonthebustopology, fromakernelname, fromtheoutputofaprogram. Seehttp://www.reactivated.net/writing_udev_rules.html foraverycompletedescription.
339
udevnamingruleexamples
#Inputdevices,groupunder/dev/input BUS="scsi",PROGRAM="/sbin/scsi_id",RESULT="OEM0815",NAME="disk1" #USBprintertobecalledlp_color BUS="usb",SYSFS{serial}="W09090207101241330",NAME="lp_color" #SCSIdiskwithaspecificvendorandmodelnumberwillbecalledboot BUS="scsi",SYSFS{vendor}="IBM",SYSFS{model}="ST336",NAME="boot%n" #soundcardwithPCIbusid00:0b.0tobecalleddsp BUS="pci",ID="00:0b.0",NAME="dsp" #USBmouseatthirdportofthesecondhubtobecalledmouse1 BUS="usb",PLACE="2.3",NAME="mouse1" #ttyUSB1shouldalwaysbecalledpdawithtwoadditionalsymlinks KERNEL="ttyUSB1",NAME="pda",SYMLINK="palmtophandheld" #multipleUSBwebcamswithsymlinkstobecalledwebcam0,webcam1,... BUS="usb",SYSFS{model}="XV3",NAME="video%n",SYMLINK="webcam%n"
340
udevpermissionruleexamples
Excerptsfrom/etc/udev/rules.d/40permissions.rules
#Blockdevices SUBSYSTEM!="block",GOTO="block_end" SYSFS{removable}!="1",GROUP="disk" SYSFS{removable}=="1",GROUP="floppy" BUS=="usb",GROUP="plugdev" BUS=="ieee1394",GROUP="plugdev" LABEL="block_end" #Otherdevices,byname KERNEL=="null",MODE="0666" KERNEL=="zero",MODE="0666" KERNEL=="full",MODE="0666"
341
Identifyingdevicedrivermodules
Eachdriverannounceswhichdeviceandvendor idsitsupports.Informationstoredinmodulefiles. Thedepmodacommandprocesses modulefilesandgenerates /lib/modules/<version>/modules.alias Thedrivercore(usb,pci...)readsthedeviceid, vendoridandotherdeviceattributes.
Thekernelsendsaneventtoudevd,settingthe MODALIASenvironmentvariable,encodingthesedata.
Audeveventprocessruns modprobe$MODALIAS
modprobefindsthemoduletoload inthemodules.aliasfile.
Kernel/modulecompiling
Systemeverydaylife
342
Modulealiases
MODALIASenvironmentvariableexample(U SBmouse): MODALIAS=usb:v046DpC03Ed2000dc00dsc00dp00ic03isc01ip02 Matchinglinein/lib/modules/<version>/modules.alias: aliasusb:v*p*d*dc*dsc*dp*ic03isc01ip02*usbmouse
343
udevmodproberuleexamples
Evenmoduleloadingisdonew ithudev! Excerptsfrom/etc/udev/rules.d/90modprobe.rules
ACTION!="add",GOTO="modprobe_end" SUBSYSTEM!="ide",GOTO="ide_end" IMPORT{program}="ide_mediaexport$devpath" ENV{IDE_MEDIA}=="cdrom", RUN+="/sbin/modprobeQbaidecd" ENV{IDE_MEDIA}=="disk", RUN+="/sbin/modprobeQbaidedisk" ENV{IDE_MEDIA}=="floppy",RUN+="/sbin/modprobeQbaidefloppy" ENV{IDE_MEDIA}=="tape",RUN+="/sbin/modprobeQbaidetape" LABEL="ide_end" SUBSYSTEM=="input",PROGRAM="/sbin/grepmapudev",\ RUN+="/sbin/modprobeQba$result" #Loaddriversthatmatchkernelsuppliedalias ENV{MODALIAS}=="?*",RUN+="/sbin/modprobeQ$env{MODALIAS}"
344
Coldplugging
Issue:loosingalldeviceeventshappeningduringkernel initialization,becauseudevisnotreadyyet. Solution:afterstartingudevd,havethekernelemituevents foralldevicespresentin/sys. Thiscanbedonebytheudevtriggerutility. Strongbenefit:completelytransparentforuserspace. Legacyandremovabledeviceshandledandnamedinexactly thesameway.
345
Debuggingeventsudevmonitor(1)
udevmonitorvisualizesthedrivercoreeventsandthe deveventprocesses. u ExampleeventsequenceconnectingaU SBmouse:
UEVENT[1170452995.094476]add@/devices/pci0000:00/0000:00:1d.7/usb4/43/43.2 UEVENT[1170452995.094569]add@/devices/pci0000:00/0000:00:1d.7/usb4/43/43.2/43.2:1.0 UEVENT[1170452995.098337]add@/class/input/input28 UEVENT[1170452995.098618]add@/class/input/input28/mouse2 UEVENT[1170452995.098868]add@/class/input/input28/event4 UEVENT[1170452995.099110]add@/class/input/input28/ts2 UEVENT[1170452995.099353]add@/class/usb_device/usbdev4.30 UDEV[1170452995.165185]add@/devices/pci0000:00/0000:00:1d.7/usb4/43/43.2 UDEV[1170452995.274128]add@/devices/pci0000:00/0000:00:1d.7/usb4/43/43.2/43.2:1.0 UDEV[1170452995.375726]add@/class/usb_device/usbdev4.30 UDEV[1170452995.415638]add@/class/input/input28 UDEV[1170452995.504164]add@/class/input/input28/mouse2 UDEV[1170452995.525087]add@/class/input/input28/event4 UDEV[1170452995.568758]add@/class/input/input28/ts2
346
Debuggingeventsudevmonitor(2)
udevmonitorenvshowsthecompleteeventenvironmentforeachline.
UDEV[1170453642.595297]add@/devices/pci0000:00/0000:00:1d.7/usb4/43/43.2/43.2:1.0 UDEV_LOG=3 ACTION=add DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb4/43/43.2/43.2:1.0 SUBSYSTEM=usb SEQNUM=3417 PHYSDEVBUS=usb DEVICE=/proc/bus/usb/004/031 PRODUCT=46d/c03d/2000 TYPE=0/0/0 INTERFACE=3/1/2 MODALIAS=usb:v046DpC03Dd2000dc00dsc00dp00ic03isc01ip02 UDEVD_EVENT=1
347
Miscudevutilities
udevinfo Letsusersquerytheudevdatabase. udevtest<sysfs_device_path> Simulatesaudevruntotesttheconfiguredrules.
348
Firmwarehotplugging
Alsoimplementedwithudev! Firmwaredataarekeptoutsidedevicedrivers Maynotbelegalorfreeenoughtodistribute Firmwareinkernelcodewouldoccupymemorypermanently, evenifjustusedonce. Kernelconfiguration:needstobesetinCONFIG_FW_LOADER (DeviceDrivers>GenericDriverOptions>hotplugfirmware loadingsupport)
349
Firmwarehotpluggingimplementation
Kernelspace
Driver
callsrequest_firmware() Sleeps
Userspace
/sys/class/firmware/xxx/{loading,data} appear
/lib/udev/firmware_helper
echo1>/sys/class/firmware/xxx/loading catfw_image>/sys/class/firmware/xxx/data echo0>/sys/class/firmware/xxx/loading
Driver
wakesupafterrequest_firmware() Copiesthebuffertothehardware Callsrelease_firmware()
SeeDocumentation/firmware_class/foraniceoverview
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
350
udevfiles
/etc/udev/udev.conf udevconfigurationfile. Mainlyusedtoconfiguresyslogreportingpriorities. Examplesetting:udev_log="err" /etc/udev/rules.d/* udeveventmatchingrules. /lib/udev/devices/* static/devcontent(suchas/dev/console,/dev/null...). /lib/udev/* helperprogramscalledfromudevrules. /dev/* Createddevicefiles.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
351
Kernelconfigurationforudev
Createdfor2.6.19 Caution:nodocumentationfound,andnottestedyetonaminimalisticsystem. Somesettingsmaystillbemissing. Subsystemsanddevicedrivers(USB,PCI,PCMCIA...)shouldbeaddedtoo! #Generalsetup CONFIG_HOTPLUG=y #Networking,networkingoptions CONFIG_NET=y CONFIG_UNIX=y CONFIG_NETFILTER_NETLINK=y CONFIG_NETFILTER_NETLINK_QUEUE=y #Pseudofilesystems CONFIG_PROC_FS=y CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_RAMFS=y
Unixdomainsockets
Neededtomanage/dev
352
udevsummarytypicaloperation
Kerneldrivercore (usb,pci...) uevent
udevd
udeveventprocess
Matches event to rules Creates / removes device files
/lib/udev/programsorothers
Load the right module Notify userspace programs (GUI...)
353
udevresources
Homepage http://kernel.org/pub/linux/utils/kernel/hotplug/udev.html Sources http://kernel.org/pub/linux/utils/kernel/hotplug/ Recentstateofudev,byKaySievers(verygoodarticle): http://vrfy.org/log/recentstateofudev.html
354
EmbeddedLinuxdriverdevelopment
Adviceandresources
355
Systemsecurity
Inproduction:disableloadablekernelmodulesifyoucan. Carefullycheckdatafrominputdevices(ifinterpretedbythe driver)andfromuserprograms(bufferoverflows) Checkkernelsourcessignature. Bewareofuninitializedmemory. Compilemodulesbyyourself(bewareofbinarymodules)
356
EmbeddedLinuxdriverdevelopment
Adviceandresources
Choosingfilesystems
357
BlockdeviceorMTDfilesystems
Blockdevices Floppyorharddisks (SCSI,IDE) CompactFlash(seenasa regularIDEdrive) RAMdisks Loopbackdevices MemoryTechnologyDevices(MTD) Flash,ROMorRAMchips MTDemulationonblockdevices
FilesystemsareeithermadeforblockorMTDstoragedevices. SeeDocumentation/filesystems/fordetails.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
358
Traditionalblockfilesystems
Traditionalfilesystems Hardtorecoverfromcrashes.Canbeleftinacorrupted(half finished)stateafterasystemcrashorsuddenpoweroff. ext2:traditionalLinuxfilesystem (repairitwithfsck.ext2) vfat:traditionalWindowsfilesystem (repairitwithfsck.vfatonGNU/LinuxorScandiskon Windows)
359
Journaledfilesystems
Designedtostayina correctstateevenafter systemcrashesora suddenpoweroff Allwritesarefirst describedinthejournal beforebeingcommitted tofiles
Application
Userspace Kernelspace (filesystem) Writetofile
360
Filesystemrecoveryaftercrashes
Reboot
Journal empty?
361
Journaledblockfilesystems
Journaledfilesystems ext3:ext2withjournalextension reiserFS:mostinnovative(fastandextensible) Caution:needsatleast32MB! reiser4:thelatestversion. Availablethroughpatches(notinmainstreamyet). Others:JFS(IBM),XFS(SGI) NTFS:wellsupportedbyLinuxinreadmode.
362
Compressedblockfilesystems(1)
Cramfs Simple,small,readonlycompressedfilesystem designedforembeddedsystems. Maximumfilesystemsize:256MB Maximumfilesize:16MB SeeDocumentation/filesystems/cramfs.txt inkernelsources.
363
Compressedblockfilesystems(2)
Squashfs:http://squashfs.sourceforge.net AmustusereplacementforCramfs!Alsoreadonly. Maximumfilesystemandfilesize:264bytes! Achievesbettercompressionandmuchbetterperformance. Itsupportsblocksizesupto64K(insteadof4K)forgreater compression,andevendetectsduplicatefiles! Fullystablebutreleasedasaseparatepatchsofar (waitingforLinux2.7tostart). Successfullytestedoni386,ppc,armandsparc. Benchmarks:(roughly3timessmallerthanext3,and24timesfaster) http://tree.celinuxforum.org/CelfPubWiki/SquashFsComparisons
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
364
ramfilesystems
Usefultostoretemporarydatanotkeptafterpowerofforreboot:system logfiles,connectiondata,temporaryfiles... Traditionalblockfilesystems:journalingnotneeded. Manydrawbacks:fixedinsize.RemainingspacenotusableasRAM. FilesduplicatedinRAM(intheblockdeviceandfilecache)! tmpfs(Config:Filesystems>Pseudofilesystems) Doesn'twasteRAM:growsandshrinkstoaccommodatestoredfiles SavesRAM:noduplication;canswapoutpagestodiskwhenneeded. SeeDocumentation/filesystems/tmpfs.txtinkernelsources.
365
Mixingreadonlyandreadwritefilesystems
Goodideatosplityourblockstorageinto Acompressedreadonlypartition(Squashfs) Typicallyusedfortherootfilesystem(binaries,kernel...). Compressionsavesspace.Readonlyaccessprotectsyour systemfrommistakesanddatacorruption. Areadwritepartitionwithajournaledfilesystem(likeext3) Usedtostoreuserorconfigurationdata. Guaranteesfilesystemintegrityafterpowerofforcrashes. Ramstoragefortemporaryfiles(tmpfs) Squashfs BlockStorage RAM
readonly compressed root filesystem
ext3
readwrite volatiledata
tmpfs
366
TheMTDsubsystem
Linuxfilesysteminterface MTDUsermodules
jffs2 yaffs2 Chardevice Readonlyblockdevice Blockdevice
MTDChipdrivers
CFIflash NANDflash DiskOnChipflash
Memorydeviceshardware
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
367
MTDfilesystemsjffs2
jffs2:JournalingFlashFileSystemv2 Designedtowriteflashsectorsinanhomogeneousway. Flashbitscanonlyberewrittenarelativelysmallnumberoftimes (often<100000). Compressedtofitasmanydataaspossibleonflashchips.Also compensatesforsloweraccesstimetothosechips. Powerdownreliable:canrestartwithoutanyintervention Shortcomings:lowspeed,bigRAMconsumption(4MBfor128 MBofstorage).
368
Mountingajffs2image
Usefultocreateoreditjffs2imagesonyourGNU/LinuxPC! MountinganMTDdeviceasaloopdeviceisabitcomplextask.Here'san exampleforjffs2:
modprobeloop modprobemtdblock losetup/dev/loop0<file>.jffs2 modprobeblkmtderasesz=256device=/dev/loop0 mknod/dev/mtdblock0b310 (ifnotdoneyet) mkdir/mnt/jffs2 (examplemountpoint,ifnotdoneyet) mounttjffs2/dev/mtdblock0/mnt/jffs2/
369
MTDfilesystemsyaffs2
yaffs2:YetAnotherFlashFilingSystem,version2 yaffs2home:http://www.aleph1.co.uk/yaffsoverview Features:NANDflashonly.Nocompression.Severaltimes fasterthanjffs2(mainlysignificantinboottime).Consumes muchlessRAM.AlsoincludesECCandispowerdownreliable. License:GPLorproprietary ShipsoutsidetheLinuxkernel.GetitfromCVS: http://aleph1.co.uk/cgibin/viewcvs.cgi/yaffs2/
370
Filesystemchoicesforblockflashdevices
TypicallyforCompactFlashstorage Can'tusejffs2oryaffs2onCFstorage(blockdevice).MTDBlock deviceemulationcouldbeused,butjffs2/yaffs2writingschemes couldinterferewithonchipflashmanagement(manufacturerdependent). Neveruseblockdevicejournaledfilesystemsonunprotectedflashchips! Keepingthejournalwouldwritethesamesectors overandoveragainandquicklydamagethem. Canuseext2orvfat,withthebelowmountoptions: noatime:doesn'twriteaccesstimeinformationinfileinodes sync:toperformwritesimmediately(reducepowerdownfailurerisks)
371
Filesystemchoicesummary
Block No No No
Storage type?
Readonly files?
Contains flash?
Volatile data?
Chooseext3,reiser4, XFSorJFS
chooseSquashfs
readonly
Choosetmpfs
372
EmbeddedLinuxdriverdevelopment
Adviceandresources
Gettinghelpandcontributions
373
Solvingissues
Ifyoufaceanissue,anditdoesn'tlookspecifictoyourworkbut rathertothetoolsyouareusing,itisverylikelythatsomeoneelse alreadyfacedit. SearchtheInternetforsimilarerrorreports Onwebsitesormailinglistarchives (usingagoodsearchengine) Onnewsgroups:http://groups.google.com/ Youhavegreatchancesoffindingasolutionorworkaround,orat leastanexplanationforyourissue. Otherwise,reportingtheissueisuptoyou!
374
Gettinghelp
Ifyouhaveasupportcontract,askyourvendor Otherwise,don'thesitatetoshareyourquestionsandissues onmailinglists
EithercontacttheLinuxmailinglistforyourarchitecture(likelinux armkernelorlinuxshdev...) Orcontactthemailinglistforthesubsystemyou' redealingwith (linuxusbdevel,linuxmtd...).D on'taskthemaintainerdirectly! MostmailinglistscomewithaFAQpage.Makesureyoureadit beforecontactingthemailinglist RefrainfromcontactingtheLinuxK ernelmailinglist,unlessyou're anexperienceddeveloperandneedadvice
375
Gettingcontributions
Appliesifyourprojectcaninterestotherpeople: developingadriverorfilesystem,portingLinuxonanew processor,boardordeviceavailableonthemarket... Externalcontributorscanhelpyoualotby Testing Writingdocumentation Makingsuggestions Evenwritingcode
376
Encouragingcontributions
Openyourdevelopmentprocess:mailinglist,Wiki,publicCVS readaccess Leteveryonecontributeaccordingtotheirskillsandinterests. Releaseearly,releaseoften Takefeedbackandsuggestionsintoaccount Recognizecontributions Makesurestatusanddocumentationareuptodate Publicizeyourworkandprogresstobroaderaudiences
377
EmbeddedLinuxdriverdevelopment
Adviceandresources
Bugreportandpatchsubmission
378
ReportingLinuxbugs
Firstmakesureyou'reusingthelatestversion Makesureyouinvestigatetheissueasmuchasyoucan: seeDocumentation/BUGHUNTING Makesurethebughasnotbeenreportedyet.Abugtrackingsystem (http://bugzilla.kernel.org/)existsbutveryfewkerneldevelopersuseit. Besttousewebsearchengines(accessingpublicmailinglistarchives) Ifthesubsystemyoureportabugonhasamailinglist,useit. Otherwise,contacttheofficialmaintainer(seetheMAINTAINERSfile). Alwaysgiveasmanyusefuldetailsaspossible.
379
Howtosubmitpatchesordrivers
Don'tmergepatchesaddressingdifferentissues Youshouldidentifyandcontacttheofficialmaintainer forthefilestopatch. SeeDocumentation/SubmittingPatchesfordetails.For trivialpatches,youcancopytheTrivialPatchMonkey. Seealsohttp://kernelnewbies.org/UpstreamMergeforveryhelpful advicetohaveyourcodemergedupstream(byRikvanRiel). Specialsubsystems: ARMplatform:it'sbesttosubmityourARMpatchestoRussell King'spatchsystem: http://www.arm.linux.org.uk/developer/patches/
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
380
Howtobecomeakerneldeveloper?
GregKroahHartmangatheredusefulreferencesandadvicefor peopleinterestedincontributingtokerneldevelopment: Documentation/HOWTO Donotmissthisveryusefuldocument!
381
EmbeddedLinuxdriverdevelopment
Adviceandresources
References
382
Specifictrainingmaterials
FreeElectronsisworkingondedicatedtrainingmaterialsfor specificdevice/drivertypes: LinuxUSBdrivers http://freeelectrons.com/articles/linuxusb Morewillbeavailableinthenextmonths:block,network, input,audio,graphics... Don'thesitatetoaskustocreatetheonesyouneedfora trainingsession!
383
Informationsites(1)
LinuxWeeklyNews http://lwn.net/ TheweeklydigestoffallLinuxandfreesoftware informationsources Indepthtechnicaldiscussionsaboutthekernel Subscribetofinancetheeditors($5/month) Articlesavailablefornonsubscribers after1week.
384
Informationsites(2)
KernelTrap http://kerneltrap.org/ Forumwebsiteforkerneldevelopers News,articles,whitepapers,discussions,polls,interviews Perfectifadigestisnotenough!
385
Usefulreading(1)
LinuxDeviceDrivers,3rdedition,Feb2005 ByJonathanCorbet,AlessandroRubini, GregKroahHartman,O'Reilly http://www.oreilly.com/catalog/linuxdrive3/ Freelyavailableonline! Greatcompaniontotheprintedbook foreasyelectronicsearches! http://lwn.net/Kernel/LDD3/(1PDFfileperchapter) http://freeelectrons.com/community/kernel/ldd3/(singlePDFfile) AmusthavebookforLinuxdevicedriverwriters!
386
Usefulreading(2)
LinuxKernelDevelopment,2ndEdition,Jan2005 RobertLove,NovellPress http://rlove.org/kernel_book/ Averysyntheticandpleasantwaytolearnaboutkernel subsystems(beyondtheneedsofdevicedriverwriters) UnderstandingtheLinuxKernel,3rdedition,Nov2005 DanielP.Bovet,MarcoCesati,O'Reilly http://oreilly.com/catalog/understandlk/ AnextensivereviewofLinuxkernelinternals, coveringLinux2.6atlast. Unfortunately,onlycoversthePCarchitecture.
387
Usefulonlineresources
LinuxkernelmailinglistFAQ http://www.tux.org/lkml/ CompleteLinuxkernelFAQ Readthisbeforeaskingaquestiontothemailinglist KernelNewbies http://kernelnewbies.org/ Glossary,articles,presentations,HOWTOs, recommendedreading,usefultoolsforpeople gettingfamiliarwithLinuxkernelordriver development. Kernelglossary: http://kernelnewbies.org/KernelGlossary
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
388
CELinuxForumresources
CELinuxForum'sWiki isfullofusefulresourcesforembeddedsystemsdevelopers: Kernelpatchesnotavailableinmainstreamyet Manyhowtodocumentsofallkinds Detailsaboutongoingprojects,suchasreducingkernelsize, boottime,orpowerconsumption. Contributionsarewelcome! http://tree.celinuxforum.org/CelfPubWiki
389
ARMresources
ARMLinuxproject:http://www.arm.linux.org.uk/ Developerdocumentation:http://www.arm.linux.org.uk/developer/ armlinuxkernelmailinglist: http://lists.arm.linux.org.uk/mailman/listinfo/linuxarmkernel FAQ:http://www.arm.linux.org.uk/armlinux/mlfaq.php Howtopostkernelfixes: http://www.arm.uk.linux.org/developer/patches/ ARMLinux@Simtec:http://armlinux.simtec.co.uk/ Afewusefulresources:FAQ,documentationandWho'swho! ARMLimited:http://www.linuxarm.com/ Wikiwithlinkstousefuldeveloperresources
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
390
Internationalconferences(1)
UsefulconferencesfeaturingLinuxkernelpresentations OttawaLinuxSymposium(July):http://linuxsymposium.org/ Rightafterthe(private)kernelsummit. Lotsofkerneltopics.Manycorekernelhackersstillpresent. Fosdem:http://fosdem.org(Brussels,February) Fordevelopers.Kernelpresentationsfromwellknownkernelhackers. CELinuxForum:http://celinuxforum.org/ Organizesseveralinternationaltechnicalconferences,inparticularin California(SanJose)andinJapan.NowopentononCELFmembers! Veryinterestingkerneltopicsforembeddedsystemsdevelopers.
391
Internationalconferences(2)
linux.conf.au:http://conf.linux.org.au/(Australia/NewZealand) Featuresafewpresentationsbykeykernelhackers. Don'tmissourfreeconferencevideoson http://freeelectrons.com/community/videos/conferences/!
392
EmbeddedLinuxdriverdevelopment
Adviceandresources
Lastadvice
393
UsetheSource,Luke!
ManyresourcesandtricksontheInternetfindyouwill,but solutionstoalltechnicalissuesonlyintheSourcelie.
ThankstoLucasArts
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
394
EmbeddedLinuxdriverdevelopment
Annexes
Quizanswers
395
Quizanswers
request_irq,free_irq Q:Whydoesdev_idhavetobeuniqueforsharedIRQs? A:Otherwise,thekernelwouldhavenowayofknowingwhichhandlerto release.Alsoneededformultipledevices(disks,serialports...)managedby thesamedriver,whichrelyonthesameinterrupthandlercode. Interrupthandling Q:Whydidthekernelsegfaultatmoduleunload(forgettingtounregistera handlerinasharedinterruptline)? A:Kernelmemoryisallocatedatmoduleloadtime,tohostmodulecode. Thismemoryisfreedatmoduleunloadtime.Ifyouforgettounregistera handlerandaninterruptcomes,thecpuw illtrytojumptotheaddressofthe handler,whichisinafreedmemoryarea.Crash!
396
EmbeddedLinuxdriverdevelopment
Annexes
Ubootdetails
397
PostprocessingkernelimageforUboot
TheUbootbootloaderneedsextrainformationtobeaddedto thekernelandinitrdimagefiles. mkimagepostprocessingutilityprovidedinUbootsources Kernelimagepostprocessing: makeuImage
398
PostprocessinginitrdimageforUboot
mkimage ninitrd\ Aarm\ Olinux\ Tramdisk\ Cgzip\ drdext2.gz\ uInitrd Name Architecture OperatingSystem Type Compression Inputfile Outputfile
399
CompilingDasUboot
GettheUbootsourcesfromhttp://uboot.sourceforge.net/ IntheUbootsourcedirectory: Findthenameoftheconfigfileforyourboardin include/configs(forexample:omap1710h3.h) ConfigureUboot: makeomap1710h3_config(.hreplacedby_config) Ifneeded,changethecrosscompilerprefixinMakefile: ifeq($(ARCH),arm) CROSS_COMPILE=armlinux endif Compile: make
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
400
CompilingUbootmkimage
IfyoujustneedmkimageandUbootisalreadyinstalledonyourboard: GettheUbootsourcesfrom http://uboot.sourceforge.net/ ConfigureUbootforanyboardonyourplatform(seepreviousslide) Compile: make(ormakekifyouhaveminorfailures) Installmkimage: cptools/mkimage/usr/local/bin/
401
Configuringtftp(1)
Oftenindevelopment:downloadingakernelimagefromthenetwork. Instructionsforxinetdbasedsystems(FedoraCore,RedHat...) Installthetftpserverpackageifneeded Removedisable=yesin/etc/xinetd.d/tftp Copyyourimagefilestothe/tftpboot/directory(ortothe locationspecifiedin/etc/xinetd.d/tftp) YoumayhavetodisableSELinuxin/etc/selinux/config Restartxinetd: /etc/init.d/xinetdrestart
402
Configuringtftp(2)
OnGNU/LinuxsystemsbasedonDebian:Ubuntu,Knoppix,KernelKit... Installthetftpdhpapackageifneeded SetRUN_DAEMON="yes" in/etc/default/tftpdhpa Copyyourimagesto/var/lib/tftpboot /etc/hosts.allow: ReplaceALL:ALL@ALL:DENYbyALL:ALL@ALL:ALLOW /etc/hosts.deny: CommentoutALL:PARANOID Restarttheserver: /etc/init.d/tftpdhparestart
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
403
Ubootprompt
ConnectthetargettoyourPCthroughaserialconsole Poweruptheboard. Ontheserialconsole,youwillseesomethinglike: UBoot1.1.2(Aug3200417:31:20) RAMConfiguration: Bank#0:000000008MB Flash:2MB In:serial Out:serial Err:serial uboot#
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
404
Boardinformation
uboot#bdinfo DRAMbank=0x00000000 >start=0x00000000 >size=0x00800000 ethaddr=00:40:95:36:35:33 ip_addr=10.0.0.11 baudrate=19200bps
405
Environmentvariables(1)
uboot#printenv baudrate=19200 ethaddr=00:40:95:36:35:33 netmask=255.255.255.0 ipaddr=10.0.0.11 serverip=10.0.0.1 stdin=serial stdout=serial stderr=serial uboot#printenvserverip serverip=10.0.0.2
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
uboot#setenvserverip10.0.0.2
406
Environmentvariables(2)
Environmentvariablechangescanbestored toflashusingthesaveenvcommand. Youcanevencreatesmallshellscripts storedinenvironmentvariables: setenvmyscripttftp0x21400000uImage;bootm 0x21400000 Youcanthenexecutethescript: runmyscript
407
Networkcommands
uboot#tftp8000uboot.bin Fromserver10.0.0.1;ourIPaddressis 10.0.0.11 Filename'uboot.bin'. Loadaddress:0x8000 Loading:################### done Bytestransferred=95032(17338hex) Thesizeandlocationofthedownloadedfilearestoredinthe fileaddrandfilesizeenvironmentvariables.
408
Flashcommands(1)
uboot#flinfo Bank#1:AMDAm29LV160DB16KB,2x8KB,32KB,31x64KB Size:2048KBin35Sectors SectorStartAddresses: S00@0x01000000!S01@0x01004000! S02@0x01006000!S03@0x01008000! S04@0x01010000!S05@0x01020000! S06@0x01030000S07@0x01040000 Protectedsectors ... S32@0x011D0000S33@0x011E0000 S34@0x011F0000
409
Flashcommands(2)
uboot#protectoff1:04 UnProtectFlashSectors04inBank#1 uboot#erase1:04 EraseFlashSectors04inBank#1 ErasingSector0@0x01000000...done ErasingSector1@0x01004000...done ErasingSector2@0x01006000...done ErasingSector3@0x01008000...done ErasingSector4@0x01010000...done
410
Flashcommands(3)
Storingafileinflash Downloadingfromthenetwork: uboot#tftp8000uboot.bin Copytoflash(0x01000000:firstsector) uboot#cp.b${fileaddr}1000000 ${filesize} CopytoFlash...................done Removetheprotectionofflashsectors uboot#protecton1:04 ProtectFlashSectors05inBank#1
411
bootcommands
Specifykernelbootparameters: uboot#setenvbootargsmem=64M console=ttyS0,115200init=/sbin/init root=/dev/mtdblock0 Executethekernelfromagivenphysicaladdress(RAMorflash) bootm0x01030000
412
Usefullinks
VeryniceoverviewaboutUboot (whichhelpedtocreatethissection): http://linuxdevices.com/articles/AT5085702347.html TheUbootmanual: http://www.denx.de/wiki/view/DULG/UBoot Backtothebootloaderssection.
413
EmbeddedLinuxdriverdevelopment
Annexes
Grubdetails
414
Grubfeatures(1)
Manyfeaturesandalotofflexibility! Supportsbootingmanyoperatingsystems: Linux,Hurd,*BSD,Windows,DOS,OS/2... Supportfordifferentbootdevices:harddisk(ofcourse),cdrom (ElTorito),network(tftp) Supportformanyfilesystems(unlikeLILO,itdoesn'tneedto storethephysicallocationofeachkernel): ext2/3,xfs,jfs,reiserfs,dos,fat16,fat32... Configurationfile:unlikeLILO,noneedtoupdatetheMBRafter makingchangestotheconfigurationfile.
415
Grubfeatures(2)
Supportformanynetworkcards (reusingdriversfromtheEtherbootbootloader). Menuinterfaceforregularusers. Advancedcommandlineinterfaceforadvancedusers. Remotecontrolfromaserialconsole. Supportsmultipleexecutableformats: ELFbyalsoa.outvariants. Canuncompresscompressedfiles Small:possibletoremovefeaturesanddrivers whicharenotused(./configurehelp). Withoutrecompiling:removeunusedfilesystemstages.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
416
Grubsize
Examplefromgrub0.971ubuntu9(UbuntuDapper): Stage1: /lib/grub/i386pc/stage1:512bytes Stage1.5: /lib/grub/i386pc/e2fs_stage1_5:7508bytes Stage2: /lib/grub/i386pc/stage2:105428bytes Total:only113448bytes!
417
Installinggrub(1)
InstallGrubonanembeddedtargetwithablankdisk. DoitfromaGNU/LinuxPCwithGrubinstalled. Accessthediskfortheembeddedtargetasexternalstorage:
CompactFlashdisk:useaUSBCFcardreader. Harddiskdrive:useaUSBharddiskdriverenclosure.
418
Installinggrub(2)
InstallGrub: grubinstallrootdirectory=/mnt/sda1/dev/sda /dev/sda:thephysicaldisk.GrubisinstalledonitsMasterBoot Record. /mnt/sda1:thedirectoryunderwhichgrubinstallcreatesa boot/directorycontainingtheupperstageandconfigurationfile. Ofcourse,youcouldhaveusedanotherpartition. Grubnowneedsakerneltoboot.Copyakernelimageto /mnt/sda1/boot/(forexample)anddescribethiskernelin /mnt/sda1/boot/grub/menu.lst. Onceyoualsocopiedrootfilesystemfiles,youcanputyourstoragedevice backtotheembeddedtargetandbootfromit.
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
419
Namingfiles
Grubnamespartitionsasfollows:(hdn,p) n:nthdiskonthesystem p:pthpartitiononthisdisk Filesaredescribedwiththepartitiontheybelongto. Example:(hd0,2)/boot/vmlinuz2.6.18 Youcanspecifyadefaultpartitionwiththerootcommand: Example: root(hd0,0) /boot/vmlinuz2.6.18
420
Sampleconfigurationfile
/boot/grub/menu.lst
default0 timeout10 title Ubuntu,kernel2.6.1527386 root (hd0,2) kernel /boot/vmlinuz2.6.1527386root=/dev/hda3roquiet splash initrd /boot/initrd.img2.6.1527386 savedefault boot title root kernel initrd boot Ubuntu,kernel2.6.1527386(recoverymode) (hd0,2) /boot/vmlinuz2.6.1527386root=/dev/hda3rosingle /boot/initrd.img2.6.1527386
421
Networksupport
Grubcanusethenetworkinseveralways Grubrunningfromdisk(floppy,harddrive,cdrom),and downloadingkernelimagesfromatftpserveronthenetwork. Disklesssystem: Afirststagebootloader(typicallyEtherboot) isbootedfromROM. ItthendownloadsasecondstagefromGrub: pxegrubforaPXEROM,ornbgrubforaNBIloader). Grubcanthengetkernelimagesfromthenetwork.
422
Grubsecurity(1)
Caution:theGrubshellcanbeusedtodisplayanyofyourfiles! Example: Bootyoursystem Typetheccommandtoentercommandlinemode. find/etc/passwd Grubdisplaysallpartitionscontainingsuchafile. cat(hd0,2)/etc/passwd Youcanseethenamesofusersonthesystem! Ofcourse,youcanaccessanyfile.Permissionsareignored.
423
Grubsecurity(2)
Interactivecommandscanbeprotectedwithapassword. Otherwise,peoplewouldevenbeabletoviewthecontentsof filesfromtheGrubshell! Youcanalsoprotectmenuentrieswithapassword. Usefultorestrictfailsafemodestoadminusers.
424
Grubresources
Grubhomepage: http://www.gnu.org/software/grub/manual/ Grubmanual: http://www.gnu.org/software/grub/manual/
Backtothebootloaderssection.
425
EmbeddedLinuxdriverdevelopment
Annexes
UsingEthernetoverUSB
426
EthernetoverUSB(1)
Ifyourdevicedoesn'thaveEthernetconnectivity,buthasa USBdevicecontroller YoucanuseEthernetoverUSBthroughtheg_etherUSB device(gadget)driver(CONFIG_USB_GADGET) Ofcourse,youneedaworkingUSBdevicedriver.Generally availableasmoreandmoreembeddedprocessors(well supportedbyLinux)haveabuiltinUSBdevicecontroller PluginbothendsoftheUSBcable
427
EthernetoverUSB(2)
OnthePChost,youneedtohavetheusbnetmodule (CONFIG_USB_USBNET) PluginbothendsoftheUSBcable.Configurebothendsas regularnetworkingdevices.Example:
Onthetargetdevice modprobeg_ether ifconfigusb0192.168.0.202 routeadd192.168.0.200devusb0 OnthePC modprobeusbnet ifconfigusb0192.168.0.200 routeadd192.168.0.202devusb0
WorksgreatoniPAQPDAs!
EmbeddedLinuxkernelanddriverdevelopment Copyright20042007,FreeElectrons CreativeCommonsAttributionShareAlike2.5license http://freeelectrons.com Feb3,2007
428
EmbeddedLinuxdriverdevelopment
Annexes
Initrunlevels
429
SystemVinitrunlevels(1)
IntroducedbySystemVUnix MuchmoreflexiblethaninBSD Makeitpossibletostartorstop differentservicesforeach runlevel Correspondtotheargumentgiven to/sbin/init. Runlevelsdefinedin /etc/inittab.
/etc/initabexcerpt:
id:5:initdefault: #Systeminitialization. si::sysinit:/etc/rc.d/rc.sysinit l0:0:wait:/etc/rc.d/rc0 l1:1:wait:/etc/rc.d/rc1 l2:2:wait:/etc/rc.d/rc2 l3:3:wait:/etc/rc.d/rc3 l4:4:wait:/etc/rc.d/rc4 l5:5:wait:/etc/rc.d/rc5 l6:6:wait:/etc/rc.d/rc6
430
SystemVinitrunlevels(2)
Standardlevels init0 Haltthesystem init1 Singleusermodeformaintenance init6 Rebootthesystem initS Singleusermodeformaintenance. Mountingonly/.Oftenidenticalto1 Customizablelevels:2,3,4,5 init3 Oftenmultiusermode,withonly commandlinelogin init5 Oftenmultiusermode,with graphicallogin
431
initscripts
Accordingto/etc/inittabsettings,init<n>runs: First/etc/rc.d/rc.sysinitforallrunlevels Thenscriptsin/etc/rc<n>.d/ Startingservices(1,3,5,S): runsS*scriptswiththestartoption Killingservices(0,6): runsK*scriptswiththestopoption Scriptsareruninfilenamelexicalorder Justuselsltofindouttheorder!
432
/etc/init.d
Repositoryforallavailableinitscripts /etc/rc<n>.d/onlycontainslinkstothe/etc/init.d/ scriptsneededforrunleveln /etc/rc1.d/example(fromFedoraCore3)
K01yum>../init.d/yum K02cupsconfigdaemon>../init.d/cups configdaemon K02haldaemon>../init.d/haldaemon K02NetworkManager> ../init.d/NetworkManager K03messagebus>../init.d/messagebus K03rhnsd>../init.d/rhnsd K05anacron>../init.d/anacron K05atd>../init.d/atd S00single>../init.d/single S01sysstat>../init.d/sysstat S06cpuspeed>../init.d/cpuspeed
433
Handlinginitscriptsbyhand
Simplycallthe/etc/init.dscripts! /etc/init.d/sshdstart Startingsshd:[OK] /etc/init.d/nfsstop ShuttingdownNFSmountd:[FAILED] ShuttingdownNFSdaemon:[FAILED]Shutting downNFSquotas:[FAILED] ShuttingdownNFSservices:[OK] /etc/init.d/pcmciastatus cardmgr(pid3721)isrunning... /etc/init.d/httpdrestart Stoppinghttpd:[OK] Startinghttpd:[OK]
434
InitrunlevelsUsefullinks
Backtotheslideabouttheinitprogram.
435
Traininglabs
Traininglabsarealsoavailablefromthesamelocation: http://freeelectrons.com/training/drivers Theyareausefulcomplementtoconsolidatewhatyoulearned fromthistraining.Theydon'ttellhowtodotheexercises. However,theyonlyrelyonnotionsandtoolsintroducedbythe lectures. Ifyouhappentobestuckwithanexercise,thisprovesthatyou missedsomethinginthelecturesandhavetogobacktothe slidestofindwhatyou'relookingfor.
436
Relateddocuments
AllthetechnicalpresentationsandtrainingmaterialscreatedandusedbyFreeElectrons, availableunderafreedocumentationlicense(morethan1500pages!). http://freeelectrons.com/training
IntroductiontoUnixandGNU/Linux EmbeddedLinuxkernelanddriverdevelopment FreeSoftwaretoolsforembeddedLinuxsystems AudioinembeddedLinuxsystems MultimediainembeddedLinuxsystems LinuxUSBdrivers RealtimeinembeddedLinuxsystems IntroductiontouClinux LinuxonTIOMAPprocessors FreeSoftwaredevelopmenttools JavainembeddedLinuxsystems IntroductiontoGNU/LinuxandFreeSoftware Linuxandecology What'snewinLinux2.6? HowtoportLinuxonanewPDA
http://freeelectrons.com/articles
AdvantagesofFreeSoftwareinembeddedsystems EmbeddedLinuxoptimizations EmbeddedLinuxfromScratch...in40min!
437
Howtohelp
Ifyousupportthiswork,youcanhelp... Bysendingcorrections,suggestions,contributionsandtranslations Byaskingyourorganizationtoordertrainingsessionsperformedby theauthorofthesedocuments(seehttp://freeelectrons.com/training) Byspeakingaboutittoyourfriends,colleagues andlocalFreeSoftwarecommunity. Byaddinglinkstoouronlinematerialsonyourwebsite, toincreasetheirvisibilityinsearchengineresults.
438
Thanks
TotheOpenOffice.orgproject,fortheirpresentationand wordprocessortoolswhichsatisfiedallmyneeds Tohttp://openclipart.orgprojectcontributorsfortheirnice publicdomainclipart TotheHandhelds.orgcommunity,forgivingmesomuch helpandsomanyopportunitiestohelp. TothemembersofthewholeFreeSoftwareandOpen Sourcecommunity,forsharingthebestofthemselves:their work,theirknowledge,theirfriendship. ToBillGates,forleavinguswithsomuchroomfor innovation! Topeoplewhohelped, sentcorrectionsor suggestions:
VanessaConchodon, StphaneRubino,Samuli Jarvinen,PhilBlundell, JefferyHuang,Mohit Mehta,MattiAaltonen.
439
EmbeddedLinuxTraining UnixandGNU/Linuxbasics Linuxkernelanddriversdevelopment RealtimeLinux uClinux Developmentandprofilingtools Lightweighttoolsforembeddedsystems Rootfilesystemcreation Audioandmultimedia Systemoptimization
FreeElectronsservices
CustomDevelopment Systemintegration EmbeddedLinuxdemosandprototypes Systemoptimization Linuxkerneldrivers Applicationandinterfacedevelopment
http://freeelectrons.com