Académique Documents
Professionnel Documents
Culture Documents
BootingARMLinux
BootingARMLinux
VincentSanders
<vince@arm.linux.org.uk>
Reviewandadvice,largechunksoftheARMLinuxkernel,allaroundgoodguy:RussellKing
Review,adviceandnumerousclarifications.:NicolasPitre
Reviewandadvice:ErikMouw,ZwaneMwaikambo,JeffSutherland,RalphSiemsen,DanielSilverstone,Martin
Michlmayr,MichaelStevens,LesleyMitchell,MatthewRichardson
Reviewandreferencedinformation(seebibliography):Wookey
Copyright2004VincentSanders
ThisdocumentisreleasedunderaGPLlicence.
Alltrademarksareacknowledged.
Whileeveryprecautionhasbeentakeninthepreparationofthisarticle,thepublisherassumesnoresponsibilityfor
errorsoromissions,orfordamagesresultingfromtheuseoftheinformationcontainedherein.
20040604
RevisionHistory
Revision1.00
InitialRelease.
10thMay2004
VRS
Revision1.10
4thJune2004
VRS
Updateexamplecodetobemorecomplete.
Improvewordinginplaces,changessuggestedbyNicolasPitre.
UpdateSection2,Otherbootloaders.
Updateacknowledgements.
TableofContents
1.Aboutthisdocument
2.Otherbootloaders
3.Overview
4.Configuringthesystem'smemory
5.Loadingthekernelimage
6.LoadinganinitialRAMdisk
7.Initialisingaconsole
8.Kernelparameters
9.ObtainingtheARMLinuxmachinetype
10.Startingthekernel
A.TagReference
B.Completeexample
Bibliography
Abstract
Thisdocumentdefinesinclearconciseterms,withimplementationguidanceandexamples,therequirementsand
proceduresforabootloadertostartanARMLinuxkernel.
1.Aboutthisdocument
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
1/15
01/02/2016
BootingARMLinux
Thisdocumentdescribesthe"new"bootingprocedurewhichallversion2.4.18andlaterkernelsuse.Thelegacy
"struct"methodmustnotbeused.
Thisdocumentcontainsinformationfromawidevarietyofsources(seetheBibliography)andauthors,youare
encouragedtoconsultthesesourcesformoreinformationbeforeaskingquestionsoftheMaintainers,oronthe
ARMLinuxmailinglists.Mostoftheseareashavebeencoveredrepeatedlyinthepastandyouarelikelytobe
ignoredifyouhaven'tdoneatleastbasicresearch.
Additionallyitshouldbenotedthatprovidedtheguidanceinthisdocumentisfollowed,thereshouldbenoneedfor
animplementortounderstandeverynuanceoftheassemblerthatstartsthekernel.Experiencehasshownon
numerousoccasionsthatmostbootingproblemsareunlikelytoberelatedtothiscode,saidcodeisalsoquitetricky
andunlikelytogiveanyinsightintotheproblem.
2.Otherbootloaders
Beforeembarkingonwritinganewbootloaderadevelopershouldconsiderifoneoftheexistingloadersis
appropriate.Thereareexamplesofloadersinmostareas,fromsimpleGPLloaderstofullblowncommercial
offerings.AshortlistisprovidedherebutthedocumentsintheBibliographyoffermoresolutions.
Table1.Bootloaders
Name
URL
Description
Blob
Bootldr
Redboot
UBoot
ABLE
Blobbootloader
Bootldr
Redboot
UBoot
ABLEbootloader
GPLbootloaderforSA11x0(StrongARM)platforms.
BothGPLandnonGPLversionsavailable,mainlyusedforhandhelddevices.
RedhatloaderreleasedundertheireCoslicence.
GPLuniversalbootloader,providessupportforseveralCPUs.
Commercialbootloaderwithcomprehensivefeatureset
3.Overview
ARMLinuxcannotbestartedonamachinewithoutasmallamountofmachinespecificcodetoinitialisethe
system.ARMLinuxrequiresthebootloadercodetodoverylittle,althoughseveralbootloadersdoprovide
extensiveadditionalfunctionality.Theminimalrequirementsare:
Configurethememorysystem.
Loadthekernelimageatthecorrectmemoryaddress.
OptionallyloadaninitialRAMdiskatthecorrectmemoryaddress.
Initialisethebootparameterstopasstothekernel.
ObtaintheARMLinuxmachinetype
Enterthekernelwiththeappropriateregistervalues.
Itisusuallyexpectedthatthebootloaderwillinitialiseaserialorvideoconsoleforthekernelinadditiontothese
basictasks.Indeedaserialportisalmostconsideredmandatoryinmostsystemconfigurations.
Eachofthesestepswillbeexaminedinthefollowingsections.
4.Configuringthesystem'smemory
ThebootloaderisexpectedtofindandinitialiseallRAMthatthekernelwilluseforvolatiledatastorageinthe
system.Itperformsthisinamachinedependentmanner.Itmayuseinternalalgorithmstoautomaticallylocateand
sizeallRAM,oritmayuseknowledgeoftheRAMinthemachine,oranyothermethodthebootloaderdesigner
seesfit.
Inallcasesitshouldbenotedthatallsetupisperformedbythebootloader.Thekernelshouldhavenoknowledgeof
thesetuporconfigurationoftheRAMwithinasystemotherthanthatprovidedbythebootloader.Theuseof
machine_fixup()withinthekernelismostdefinitelynotthecorrectplaceforthis.Thereisacleardistinction
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
2/15
01/02/2016
BootingARMLinux
betweenthebootloadersresponsibilityandthekernelinthisarea.
ThephysicalmemorylayoutispassedtothekernelusingtheATAG_MEMparameter.Memorydoesnot
necessarilyhavetobecompletelycontiguous,althoughtheminimumnumberoffragmentsispreferred.Multiple
ATAG_MEMblocksallowforseveralmemoryregions.Thekernelwillcoalesceblockspassedtoitiftheyare
contiguousphysicalregions.
Thebootloadermayalsomanipulatethememorywiththekernelscommandline,usingthe'mem='parameter,the
optionsforthisparameterarefullydocumentedinlinux/Documentation/kernelparameters.txt
Thekernelcommandline'mem='hasthesyntaxmem=<size>[KM][,@<phys_offset>]whichallowsthesizeand
physicalmemorylocationforamemoryareatobedefined.Thisallowsforspecifyingmultiplediscontigous
memoryblocksatdifferingoffsetsbyprovidingthemem=parametermultipletimes.
5.Loadingthekernelimage
Kernelimagesgeneratedbythekernelbuildprocessareeitheruncompressed"Image"filesorcompressedzImage
files.
TheuncompressedImagefilesaregenerallynotused,astheydonotcontainareadilyidentifiablemagicnumber.
ThecompressedzImageformatisalmostuniversallyusedinpreference.
ThezImagehasseveralbenefitsinadditiontothemagicnumber.Typically,thedecompressionoftheimageis
fasterthanreadingfromsomeexternalmedia.Theintegrityoftheimagecanbeassured,asanyerrorswillresultin
afaileddecompress.Thekernelhasknowledgeofitsinternalstructureandstate,whichallowsforbetterresultsthan
agenericexternalcompressionmethod.
ThezImagehasamagicnumberandsomeusefulinformationnearitsbeginning.
Table2.UsefulfieldsinzImageheadcode
OffsetintozImage
Value
Description
0x24
0x016F2818 MagicnumberusedtoidentifythisisanARMLinuxzImage
0x28
startaddress TheaddressthezImagestartsat
0x2C
endaddress TheaddressthezImageendsat
Thestartandendoffsetscanbeusedtodeterminethelengthofthecompressedimage(size=endstart).Thisis
usedbyseveralbootloaderstodetermineifanydataisappendedtothekernelimage.Thisdataistypicallyusedfor
aninitialRAMdisk(initrd).Thestartaddressisusually0asthezImagecodeispositionindependent.
ThezImagecodeisPositionIndependentCode(PIC)somaybeloadedanywherewithintheavailableaddress
space.Themaximumkernelsizeafterdecompressionis4Megabytes.Thisisahardlimitandwouldincludethe
initrdifabootpImagetargetwasused.
Note
AlthoughthezImagemaybelocatedanywhere,careshouldbetaken.Startingacompressedkernel
requiresadditionalmemoryfortheimagetobeuncompressedinto.Thisspacehascertainconstraints.
ThezImagedecompressioncodewillensureitisnotgoingtooverwritethecompresseddata.Ifthe
kerneldetectssuchaconflictitwilluncompresstheimageimmediatelyafterthecompressedzImage
dataandrelocatethekernelafterdecompression.Thisobviouslyhastheimpactthatthememory
regionthezImageisloadedintomusthaveupto4Megabytesofspaceafterit(themaximum
uncompressedkernelsize),i.e.placingthezImageinthesame4MegabytebankasitsZRELADDR
wouldprobablynotworkasexpected.
DespitetheabilitytoplacezImageanywherewithinmemory,conventionhasitthatitisloadedatthebaseof
physicalRAMplusanoffsetof0x8000(32K).Thisleavesspacefortheparameterblockusuallyplacedatoffset
0x100,zeropageexceptionvectorsandpagetables.Thisconventionisverycommon.
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
3/15
01/02/2016
BootingARMLinux
6.LoadinganinitialRAMdisk
AninitialRAMdiskisacommonrequirementonmanysystems.Itprovidesawaytohavearootfilesystem
availablewithoutaccesstootherdriversorconfigurations.Fulldetailscanbeobtainedfrom
linux/Documentation/initrd.txt
TherearetwomethodsavailableonARMLinuxtoobtainaninitialRAMdisk.Thefirstisaspecialbuildtarget
bootpImagewhichtakesaninitialRAMdiskatbuildtimeandappendsittoazImage.Thismethodhasthebenefit
thatitneedsnobootloaderintervention,butrequiresthekernelbuildprocesstohaveknowledgeofthephysical
addresstoplacetheramdisk(usingtheINITRD_PHYSdefinition).Thehardsizelimitfortheuncompressedkernel
andinitrdof4Megabytesapplies.Becauseoftheselimitationsthistargetisrarelyusedinpractice.
Thesecondandmuchmorewidelyusedmethodisforthebootloadertoplaceagiveninitialramdiskimage,
obtainedfromwhatevermedia,intomemoryatasetlocation.Thislocationispassedtothekernelusing
ATAG_INITRD2andATAG_RAMDISK.
Conventionallytheinitrdisplaced8Megabytesfromthebaseofphysicalmemory.Whereveritisplacedtheremust
besufficientmemoryafterboottodecompresstheinitialramdiskintoarealramdiski.e.enoughmemoryforzImage
+decompressedzImage+initrd+uncompressedramdisk.Thecompressedinitialramdiskmemorywillbefreed
afterthedecompressionhashappened.Limitationstothepositionoftheramdiskare:
Itmustliecompletelywithinasinglememoryregion(mustnotcrossbetweenareasdefinedbydifferent
ATAG_MEMparameters)
Itmustbealignedtoapageboundary(typically4k)
ItmustnotconflictwiththememorythezImageheadcodeusestodecompressthekerneloritwillbeoverwritten
asnocheckingisperformed.
7.Initialisingaconsole
Aconsoleishighlyrecommendedasamethodtoseewhatactionsthekernelisperformingwheninitialisinga
system.Thiscanbeanyinputoutputdevicewithasuitabledriver,themostcommoncasesareavideoframebuffer
driveroraserialdriver.SystemsthatARMLinuxrunsontendtoalmostalwaysprovideaserialconsoleport.
Thebootloadershouldinitialiseandenableoneserialportonthetarget.Thisincludesenablinganyhardwarepower
managementetc.,tousetheport.Thisallowsthekernelserialdrivertoautomaticallydetectwhichserialportit
shoulduseforthekernelconsole(generallyusedfordebuggingpurposes,orcommunicationwiththetarget.)
Asanalternative,thebootloadercanpasstherelevant'console='optiontothekernel,viathecommandline
parameterspecifyingtheport,andserialformatoptionsasdescribedinlinux/Documentation/kernel
parameters.txt
8.Kernelparameters
Thebootloadermustpassparameterstothekerneltodescribethesetupithasperformed,thesizeandshapeof
memoryinthesystemand,optionally,numerousothervalues.
Thetaggedlistshouldconformtothefollowingconstraints
ThelistmustbestoredinRAMandplacedinaregionofmemorywhereneitherthekerneldecompressernorinitrd
manipulationwilloverwriteit.Therecommendedplacementisinthefirst16KiBofRAM,usuallythestartof
physicalRAMplus0x100(whichavoidszeropageexceptionvectors).
ThephysicaladdressofthetaggedlistmustbeplacedinR2onentrytothekernel,howeverhistoricallythishasnot
beenmandatoryandthekernelhasusedthefixedvalueofthestartofphysicalRAMplus0x100.Thismustnotbe
relieduponinthefuture.
Thelistmustnotextendpastthe0x4000boundarywherethekernel'sinitialtranslationpagetableiscreated.The
kernelperformsnoboundscheckingandwilloverwritetheparameterlistifitdoesso.
Thelistmustbealignedtoaword(32bit,4byte)boundary(ifnotusingtherecommendedlocation)
ThelistmustbeginwithanATAG_COREandendwithATAG_NONE
ThelistmustcontainatleastoneATAG_MEM
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
4/15
01/02/2016
BootingARMLinux
Eachtaginthelistconsistsofaheadercontainingtwounsigned32bitvalues,thesizeofthetag(in32bit,4byte
words)andthetagvalue
structatag_header{
u32size;/*legthoftaginwordsincludingthisheader*/
u32tag;/*tagvalue*/
};
Eachtagheaderisfollowedbydataassociatedwiththattag,exceptingATAG_NONEwhichhasnodataand
ATAG_COREwherethedataisoptional.Thesizeofthedataisdeterminedbythesizefieldinheader,the
minimumsizeis2astheheaderssizeisincludedinthisvalue.TheATAG_NONEisuniqueinthatitssizefieldis
settozero.
Atagmaycontainadditionaldataafterthemandatedstructuresprovidedthesizeisadjustedtocovertheextra
information,thisallowsforfutureexpansionandforabootloadertoextendthedataprovidedtothekernel.For
exampleabootloadermayprovideadditionalserialnumberinformationinanATAG_SERIALwhichcouldthembe
interpretedbyamodifiedkernel.
Theorderofthetagsintheparameterlistisunimportant,theymayappearasmanytimesasrequiredalthough
interpretationofduplicatetagsistagdependant.
ThedataforeachindividualtagisdescribedintheAppendixA,TagReferencesection.
Table3.Listofusabletags
Tagname
ATAG_NONE
Value
0x00000000 2
Size
ATAG_CORE
0x54410001 5(2ifempty)
Description
Emptytagusedtoendlist
Firsttagusedtostartlist
ATAG_MEM
0x54410002 4
ATAG_VIDEOTEXT 0x54410003 5
Describesaphysicalareaofmemory
DescribesaVGAtextdisplay
ATAG_RAMDISK
0x54410004 5
ATAG_INITRD2
0x54420005 4
Describeshowtheramdiskwillbeusedinkernel
Describeswherethecompressedramdiskimageis
placedinmemory
ATAG_SERIAL
ATAG_REVISION
0x54410006 4
0x54410007 3
ATAG_VIDEOLFB
0x54410008 8
Initialvaluesforvesafbtypeframebuffers
2+((length_of_cmdline
0x54410009
Commandlinetopasstokernel
+3)/4)
ATAG_CMDLINE
64bitboardserialnumber
32bitboardrevisionnumber
Forimplementationpurposesastructurecanbedefinedforatag
structatag{
structatag_headerhdr;
union{
structatag_corecore;
structatag_memmem;
structatag_videotextvideotext;
structatag_ramdiskramdisk;
structatag_initrd2initrd2;
structatag_serialnrserialnr;
structatag_revisionrevision;
structatag_videolfbvideolfb;
structatag_cmdlinecmdline;
}u;
};
Oncethesestructureshavebeendefinedanimplementationneedstocreatethelistthiscanbeimplementedwith
codesimilarto
#definetag_next(t)((structtag*)((u32*)(t)+(t)>hdr.size))
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
5/15
01/02/2016
BootingARMLinux
#definetag_size(type)((sizeof(structtag_header)+sizeof(structtype))>>2)
staticstructatag*params;/*usedtopointatthecurrenttag*/
staticvoid
setup_core_tag(void*address,longpagesize)
{
params=(structtag*)address;/*Initialiseparameterstostartatgivenaddress*/
params>hdr.tag=ATAG_CORE;/*startwiththecoretag*/
params>hdr.size=tag_size(atag_core);/*sizethetag*/
params>u.core.flags=1;/*ensurereadonly*/
params>u.core.pagesize=pagesize;/*systemspagesize(4k)*/
params>u.core.rootdev=0;/*zerorootdevice(typicalyoveriddenfromcommandline)*/
params=tag_next(params);/*movepointertonexttag*/
}
staticvoid
setup_mem_tag(u32_tstart,u32_tlen)
{
params>hdr.tag=ATAG_MEM;/*Memorytag*/
params>hdr.size=tag_size(atag_mem);/*sizetag*/
params>u.mem.start=start;/*Startofmemoryarea(physicaladdress)*/
params>u.mem.size=len;/*Lengthofarea*/
params=tag_next(params);/*movepointertonexttag*/
}
staticvoid
setup_end_tag(void)
{
params>hdr.tag=ATAG_NONE;/*Emptytagendslist*/
params>hdr.size=0;/*zerolength*/
}
staticvoid
setup_tags(void)
{
setup_core_tag(0x100,4096);/*standardcoretag4kpagesize*/
setup_mem_tag(0x10000000,0x400000);/*64Mbat0x10000000*/
setup_mem_tag(0x18000000,0x400000);/*64Mbat0x18000000*/
setup_end_tag(void);/*endoftags*/
}
Whilethiscodefragmentiscompleteitillustratestheabsoluteminimalrequirementsforaparametersetandis
intendedtodemonstratetheconceptsexpressedearlierinthissection.Arealbootloaderwouldprobablypass
additionalvaluesandwouldprobablyprobeforthememoryactuallyinasystemratherthanusingfixedvalues.A
morecompleteexamplecanbefoundinAppendixB,Completeexample
9.ObtainingtheARMLinuxmachinetype
Theonlyadditionalinformationthebootloaderneedstoprovideisthemachinetype,thisisasimplenumberunique
foreachARMsystemoftenreferredtoasaMACH_TYPE.
ThemachinetypenumberisobtainedviatheARMLinuxwebsiteMachineRegistry.Amachinetypeshouldbe
obtainedasearlyinaprojectslifeaspossible,ithasanumberoframificationsforthekernelportitself(machine
definitionsetc.)andchangingdefinitionsafterwardsmayleadtoanumberofundesirableissues.Thesevaluesare
representedbyalistofdefineswithinthekernelsource(linux/arch/arm/tools/machtypes)
Thebootloadermustobtainthemachinetypevaluebysomemethod.Whetherthisisahardcodedvalueoran
algorithmthatlooksattheconnectedhardware.Implementationiscompletelysystemspecificandisbeyondthe
scopeofthisdocument.
10.Startingthekernel
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
6/15
01/02/2016
BootingARMLinux
Oncethebootloaderhasperformedalltheotherstepsitmuststartexecutionofthekernelwiththecorrectvaluesin
theCPUregisters.
Theentryrequirementsare:
TheCPUmustbeinSVC(supervisor)modewithbothIRQandFIQinterruptsdisabled.
TheMMUmustbeoff,i.e.coderunningfromphysicalRAMwithnotranslatedaddressing.
Datacachemustbeoff
Instructioncachemaybeeitheronoroff
CPUregister0mustbe0
CPUregister1mustbetheARMLinuxmachinetype
CPUregister2mustbethephysicaladdressoftheparameterlist
Thebootloaderisexpectedtocallthekernelimagebyjumpingdirectlytothefirstinstructionofthekernelimage.
A.TagReference
ATAG_CORE
ATAG_COREStarttagusedtobeginlist
Value
0x54410001
Size
5(2ifnodata)
Structuremembers
structatag_core{
u32flags;/*bit0=readonly*/
u32pagesize;/*systemspagesize(usually4k)*/
u32rootdev;/*rootdevicenumber*/
};
Description
Thistagmustbeusedtostartthelist,itcontainsthebasicinformationanybootloadermustpass,ataglengthof2
indicatesthetaghasnostructureattached.
ATAG_NONE
ATAG_NONEEmptytagusedtoendlist
Value
0x00000000
Size
2
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
7/15
01/02/2016
BootingARMLinux
Structuremembers
None
Description
Thistagisusedtoindicatethelistend.Itisuniqueinthatitssizefieldintheheadershouldbesetto0(not2).
ATAG_MEM
ATAG_MEMTagusedtodescribeaphysicalareaofmemory.
Value
0x54410002
Size
4
Structuremembers
structatag_mem{
u32size;/*sizeofthearea*/
u32start;/*physicalstartaddress*/
};
Description
Describesanareaofphysicalmemorythekernelistouse.
ATAG_VIDEOTEXT
ATAG_VIDEOTEXTTagusedtodescribeVGAtexttypedisplays
Value
0x54410003
Size
5
Structuremembers
structatag_videotext{
u8x;/*widthofdisplay*/
u8y;/*heightofdisplay*/
u16video_page;
u8video_mode;
u8video_cols;
u16video_ega_bx;
u8video_lines;
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
8/15
01/02/2016
BootingARMLinux
u8video_isvga;
u16video_points;
};
Description
ATAG_RAMDISK
ATAG_RAMDISKTagdescribinghowtheramdiskwillbeusedbythekernel
Value
0x54410004
Size
5
Structuremembers
structatag_ramdisk{
u32flags;/*bit0=load,bit1=prompt*/
u32size;/*decompressedramdisksizein_kilo_bytes*/
u32start;/*startingblockoffloppybasedRAMdiskimage*/
};
Description
Describeshowthe(initial)ramdiskwillbeconfiguredbythekernel,specificallythisallowsforthebootloaderto
ensuretheramdiskwillbelargeenoughtotakethedecompressedinitialramdiskimagethebootloaderispassing
usingATAG_INITRD2.
ATAG_INITRD2
ATAG_INITRD2Tagdescribingthephysicallocationofthecompressedramdiskimage
Value
0x54420005
Size
4
Structuremembers
structatag_initrd2{
u32start;/*physicalstartaddress*/
u32size;/*sizeofcompressedramdiskimageinbytes*/
};
Description
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
9/15
01/02/2016
BootingARMLinux
Locationofacompressedramdiskimage,usuallycombinedwithanATAG_RAMDISK.Canbeusedasaninitial
rootfilesystemwiththeadditionofacommandlineparameterof'root=/dev/ram'.Thistagsupersedestheoriginal
ATAG_INITRDwhichusedvirtualaddressing,thiswasamistakeandproducedissuesonsomesystems.Allnew
bootloadersshouldusethistaginpreference.
ATAG_SERIAL
ATAG_SERIALTagwith64bitserialnumberoftheboard
Value
0x54410006
Size
4
Structuremembers
structatag_serialnr{
u32low;
u32high;
};
Description
ATAG_REVISION
ATAG_REVISIONTagfortheboardrevision
Value
0x54410007
Size
3
Structuremembers
structatag_revision{
u32rev;
};
Description
ATAG_VIDEOLFB
ATAG_VIDEOLFBTagdescribingparametersforaframebuffertypedisplay
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
10/15
01/02/2016
BootingARMLinux
Value
0x54410008
Size
8
Structuremembers
structatag_videolfb{
u16lfb_width;
u16lfb_height;
u16lfb_depth;
u16lfb_linelength;
u32lfb_base;
u32lfb_size;
u8red_size;
u8red_pos;
u8green_size;
u8green_pos;
u8blue_size;
u8blue_pos;
u8rsvd_size;
u8rsvd_pos;
};
Description
ATAG_CMDLINE
ATAG_CMDLINETagusedtopassthecommandlinetothekernel
Value
0x54410009
Size
2+((length_of_cmdline+3)/4)
Structuremembers
structatag_cmdline{
charcmdline[1];/*thisistheminimumsize*/
};
Description
Usedtopasscommandlineparameterstothekernel.ThecommandlinemustbeNULLterminated.The
length_of_cmdlinevariableshouldincludetheterminator.
B.Completeexample
Thisisaworkedexampleofasimplebootloaderandshowsalltheinformationexplainedthroughoutthisdocument.
Morecodewouldberequiredforarealbootloaderthisexampleispurelyillustrative.
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
11/15
01/02/2016
BootingARMLinux
ThecodeinthisexampleisdistributedunderaBSDlicence,itmaybefreelycopiedandusedifnecessary.
/*example.c
*exampleARMLinuxbootloadercode
*thisexampleisdistributedundertheBSDlicence
*/
/*listofpossibletags*/
#defineATAG_NONE0x00000000
#defineATAG_CORE0x54410001
#defineATAG_MEM0x54410002
#defineATAG_VIDEOTEXT0x54410003
#defineATAG_RAMDISK0x54410004
#defineATAG_INITRD20x54420005
#defineATAG_SERIAL0x54410006
#defineATAG_REVISION0x54410007
#defineATAG_VIDEOLFB0x54410008
#defineATAG_CMDLINE0x54410009
/*structuresforeachatag*/
structatag_header{
u32size;/*lengthoftaginwordsincludingthisheader*/
u32tag;/*tagtype*/
};
structatag_core{
u32flags;
u32pagesize;
u32rootdev;
};
structatag_mem{
u32size;
u32start;
};
structatag_videotext{
u8x;
u8y;
u16video_page;
u8video_mode;
u8video_cols;
u16video_ega_bx;
u8video_lines;
u8video_isvga;
u16video_points;
};
structatag_ramdisk{
u32flags;
u32size;
u32start;
};
structatag_initrd2{
u32start;
u32size;
};
structatag_serialnr{
u32low;
u32high;
};
structatag_revision{
u32rev;
};
structatag_videolfb{
u16lfb_width;
u16lfb_height;
u16lfb_depth;
u16lfb_linelength;
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
12/15
01/02/2016
BootingARMLinux
u32lfb_base;
u32lfb_size;
u8red_size;
u8red_pos;
u8green_size;
u8green_pos;
u8blue_size;
u8blue_pos;
u8rsvd_size;
u8rsvd_pos;
};
structatag_cmdline{
charcmdline[1];
};
structatag{
structatag_headerhdr;
union{
structatag_corecore;
structatag_memmem;
structatag_videotextvideotext;
structatag_ramdiskramdisk;
structatag_initrd2initrd2;
structatag_serialnrserialnr;
structatag_revisionrevision;
structatag_videolfbvideolfb;
structatag_cmdlinecmdline;
}u;
};
#definetag_next(t)((structtag*)((u32*)(t)+(t)>hdr.size))
#definetag_size(type)((sizeof(structtag_header)+sizeof(structtype))>>2)
staticstructatag*params;/*usedtopointatthecurrenttag*/
staticvoid
setup_core_tag(void*address,longpagesize)
{
params=(structtag*)address;/*Initialiseparameterstostartatgivenaddress*/
params>hdr.tag=ATAG_CORE;/*startwiththecoretag*/
params>hdr.size=tag_size(atag_core);/*sizethetag*/
params>u.core.flags=1;/*ensurereadonly*/
params>u.core.pagesize=pagesize;/*systemspagesize(4k)*/
params>u.core.rootdev=0;/*zerorootdevice(typicalyoveriddenfromcommandline)*/
params=tag_next(params);/*movepointertonexttag*/
}
staticvoid
setup_ramdisk_tag(u32_tsize)
{
params>hdr.tag=ATAG_RAMDISK;/*Ramdisktag*/
params>hdr.size=tag_size(atag_ramdisk);/*sizetag*/
params>u.ramdisk.flags=0;/*Loadtheramdisk*/
params>u.ramdisk.size=size;/*Decompressedramdisksize*/
params>u.ramdisk.start=0;/*Unused*/
params=tag_next(params);/*movepointertonexttag*/
}
staticvoid
setup_initrd2_tag(u32_tstart,u32_tsize)
{
params>hdr.tag=ATAG_INITRD2;/*Initrd2tag*/
params>hdr.size=tag_size(atag_initrd2);/*sizetag*/
params>u.initrd2.start=start;/*physicalstart*/
params>u.initrd2.size=size;/*compressedramdisksize*/
params=tag_next(params);/*movepointertonexttag*/
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
13/15
01/02/2016
BootingARMLinux
}
staticvoid
setup_mem_tag(u32_tstart,u32_tlen)
{
params>hdr.tag=ATAG_MEM;/*Memorytag*/
params>hdr.size=tag_size(atag_mem);/*sizetag*/
params>u.mem.start=start;/*Startofmemoryarea(physicaladdress)*/
params>u.mem.size=len;/*Lengthofarea*/
params=tag_next(params);/*movepointertonexttag*/
}
staticvoid
setup_cmdline_tag(constchar*line)
{
intlinelen=strlen(line);
if(!linelen)
return;/*donotinsertatagforanemptycommandline*/
params>hdr.tag=ATAG_CMDLINE;/*Commandlinetag*/
params>hdr.size=(sizeof(structatag_header)+linelen+1+4)>>2;
strcpy(params>u.cmdline.cmdline,line);/*placecommandlineintotag*/
params=tag_next(params);/*movepointertonexttag*/
}
staticvoid
setup_end_tag(void)
{
params>hdr.tag=ATAG_NONE;/*Emptytagendslist*/
params>hdr.size=0;/*zerolength*/
}
#defineDRAM_BASE0x10000000
#defineZIMAGE_LOAD_ADDRESSDRAM_BASE+0x8000
#defineINITRD_LOAD_ADDRESSDRAM_BASE+0x800000
staticvoid
setup_tags(parameters)
{
setup_core_tag(parameters,4096);/*standardcoretag4kpagesize*/
setup_mem_tag(DRAM_BASE,0x4000000);/*64Mbat0x10000000*/
setup_mem_tag(DRAM_BASE+0x8000000,0x4000000);/*64Mbat0x18000000*/
setup_ramdisk_tag(4096);/*create4Mbramdisk*/
setup_initrd2_tag(INITRD_LOAD_ADDRESS,0x100000);/*1Mbofcompresseddataplaced8Mbintomemory*/
setup_cmdline_tag("root=/dev/ram0");/*commandlinesettingrootdevice*/
setup_end_tag(void);/*endoftags*/
}
int
start_linux(char*name,char*rdname)
{
void(*theKernel)(intzero,intarch,u32params);
u32exec_at=(u32)1;
u32parm_at=(u32)1;
u32machine_type;
exec_at=ZIMAGE_LOAD_ADDRESS;
parm_at=DRAM_BASE+0x100
load_image(name,exec_at);/*copyimageintoRAM*/
load_image(rdname,INITRD_LOAD_ADDRESS);/*copyinitialramdiskimageintoRAM*/
setup_tags(parm_at);/*setsupparameters*/
machine_type=get_mach_type();/*getmachinetype*/
irq_shutdown();/*stopirq*/
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
14/15
01/02/2016
BootingARMLinux
cpu_op(CPUOP_MMUCHANGE,NULL);/*turnMMUoff*/
theKernel=(void(*)(int,int,u32))exec_at;/*setthekerneladdress*/
theKernel(0,machine_type,parm_at);/*jumptokernelwithregisterset*/
return0;
}
Bibliography
ARMLinuxwebsiteDocumentation.RussellMKing.
LinuxKernelDocumentation/arm/booting.txt.RussellMKing.
SettingR2correctlyforbootingthekernel(explanationofbootingrequirements).RussellMKing.
Wookey'spostsummarisingbooting.Wookey.
Makefiledefinesandsymbols.RussellMKing.
Bootloaderguide.Wookey.
Kernelbootorder.RussellMKing.
Adviceforhead.SDebugging.RussellMKing.
Linuxkernel2.4startup.BillGatliff.
Blobbootloader.ErikMouw.
Blobbootloaderonlart.ErikMouw.
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html#d0e416
15/15