Sunteți pe pagina 1din 15

01/02/2016

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

S-ar putea să vă placă și