Sunteți pe pagina 1din 6

3/12/14

Understanding GRUB Source Code | Ahmed S. Ghonim

Ahmed S. Ghonim
SoftwareEngineer&SystemsAdministrator Home AboutMe

Understanding GRUB Source Code


asghonim/November3,2013

IhavebeentryingtounderstandtheLinuxbootprocessforquitesometimes.However, alltheresourcesIfoundonlineexplainthisprocessfromsomekindofabirdseye view.Theygooverthestepsabstractlywithoutactuallyexplainingthedirtydetails. So,IgaveupontheInternet,andIstartedtostudythebootprocessfirsthand.I startedwiththeGRUBlegacycode(v.97).Inthisarticle,IwillexplaintheGRUB sourcecode,andwhatexactlyhappensduringthebootprocessfromthemomentthat BIOSloadsGRUBtothepointthattheGRUBshellisupandrunning.Iwillbe explainingtheexecutionflowoftheprocess,thesourcecodeandfileswherethatflow iswritten,aswellasthebuildandconfigurationfilesthatmakesurethiscodecompiles andlinksthewayitissupposedto.Ifyouaretryingtobuildyourownamatureboot loader,orifyouaretryingtomodifyGRUB,Ihopethisarticlehelps.Beforeweget started,makesuretogetyourhandsontheGRUB0.97sourcecode.Hereisalinkto getyoustartedftp://alpha.gnu.org/gnu/grub.Fromnowon,Iwillrefertotheroot directoryofyourgrubsourcetreeassimplygrub/. ThekeytounderstandingtheGRUBsourcecodeistoknowthatthecodeis complicatedbecausetherequirementschangedafterthedevelopersrealizedtheneed tomakeGRUBfilesystemaware.Atthebeginning,GRUBwascopiedentirelyintothe firstfewsectorsofthebootdevice.Thefirstsectoristhefamousbootsectorcalled stage1inGRUB,followedbyabinaryimagecalledstage2spanningthefollowingfew sectors.Afterawhile,designerswantedtointroducestage1.5thatallowsstage2and theconfigurationfilestobestoredonanormalfilesystemonthedrive.Toexplainthe sourcecode,IwillfirstconsiderthecasewhereGRUBiscomposedoftwostages stage1andstage2.Thenweconsidertheintroductionofstage1.5andhowthat affectedthesourcecode. Firstofall,letsconsiderhowyouinstallGRUBwithonlytwostagesonaharddiskora floppy.YouaccomplishthisbyobtainingtheGRUBsourcecode,buildingitusing ./configureandmake,thencopytheoutputfiles(inbinarymode)stage1andstage2 tothefirstsectorandthefollowingsectorsofyourbootdevicerespectively. Follow
asghonim.wordpress.com/2013/11/03/understanding-grub-source-code/ 1/6

3/12/14

Understanding GRUB Source Code | Ahmed S. Ghonim

d di f = s t a g e 1o f = / d e v / f l o p p y 0b s = 5 1 2c o u n t = 1 d di f = s t a g e 2o f = / d e v / f l o p p y 0b s = 5 1 2s e e k = 1

FollowAhmedS. Ghonim
Geteverynewpostdelivered

Now,wehavestage1atsector1andstage2startingfromsector2towhateversize toyourInbox. itneeds.WhenyoustartyourPC,theBIOSloadsasinglesectorfromthestartofyour

Enteryouremailaddress deviceintoabsoluteaddress0x7C00.Itthensetstheblregistertoacertainvalue
indicatingthedevicewhichwasusedtoloadthatsector(000=FirstFloppy,080=

Signmeup FirstHDD,etc).Thenitjumpsto0x7C00wherestage1ofGRUBwasloaded.

PoweredbyWordPress.com Thesourcecodeofthefirstsectoriswritteningrub/stage1/stage1.s.Thefirst

instructionismarkedbythe_startsymbolwhichtellsthelinkertoputthissequenceof instructionatthebeginningoftheoutputimage.Ingrub/stage1/makefile.am,thereisa linethatstartswithLDFLAGS.Thislinespecifiestheoptionsgiventothelinkerwhen buildingthestage1imagefile.NoticetheTtext7C00optionthattellsthelinkerthat thiscodeissupposedtobeloadedandrunatabsoluteaddress0x7C00wherethe BIOSisconfiguredtoloadandrunthefirstsector.Stage1doesntdomuch.First,it skipsoversomeareasforcompatibilityreasonslikeBPB(BIOSParameterBlock)and partitiontable.Thenitreadsthedevicecodefrombltoknowwheretherestofthe GRUBcodeistobeloadedfrom)sameplacefirstsectorwasloadedfrom).Itloadsa singlesector(sector2)intoabsoluteaddress08000andjumpsthere.Themethodit usestoloadthissectoriseitherLBAiftheBIOSsupportsit,orafallbackmethod usingCHS(CylinderHeadSector)modeifLBAfails.BothmethodsusetheBIOS INT013serviceroutines.Thevalue08000,whichrepresentsthedestinationaddress usedtoloadthesecondsector,ishardcodedintothestage1code.However,the addresswherethisvalueisstoredisdefinedinthetwomacros STAGE1_STAGE2_ADDRESSandSTAGE1_STAGE2_SEGMENTdefinedin grub/stage2/<shared.h>.Payattentiontothesemacrosbecausetheywillexplainsome trickerylater. Thecodethatisloadedataddress08000bystage1isthestartcode.Itisasingle sectorthatissupposedtoloadtherestofthegrubsourcecode.Thesourcecodefor thestartsectorisingrub/stage2/start.s.Thestartsectorisalittleconfusingbecause itisincludedinthebeginningofbothstage2andstage1.5images.Itdependsona compiletimeparameter(STAGE1_5)totellitwhichimageitisbeingincludedinto.The sameparameter(STAGE1_5)definesthedestinationaddresswherestartisgoingto loadtherestoftheimage.Ifloadingastage2image(STAGE1_5isnotdefined),start willloadtheimageatabsoluteaddress08200.Ifitisastage1.5image,startwillload theimageatabsoluteaddress02200.Thenitwilljumptothataddress.Again_start definesthebeginningofthecode.YoushouldnoticeacoupleofIfdefSTAGE1_5 wherestarttakesactionaccordingtothetypeofimageitisincludedinto.Forthisfirst partofthearticle,wewilljustignoretheSTAGE1_5macrobecauseitwasntaddedto thecodeuntilrecently(aftertheadditionofstage1.5).Themakefiledoesnotdefinethis macrowhenitisbuildingastage2image.Ingrub/stage2/makefile.am,youcanfind start.sgeneratedintwoways.Thefirstwayisbyincludingitinthesourcefileslist whengeneratinganystage1.5image.Forexample,thelinestartingwith fat_stage1_5_exec_SOURCES=start.Sasm.Scommon.ctellsmakethatinorder tobuildthefat_stage1.5.execimage,itneedstoincludethesourcefilesstart.s,
asghonim.wordpress.com/2013/11/03/understanding-grub-source-code/ 2/6

3/12/14

Understanding GRUB Source Code | Ahmed S. Ghonim

asm.s,andcommon.camongothers.Whenbuildingthisimage(anystage1.5 image),theSTAGE1_5_COMPILEdefinestheoptionsgiventothecompiler.Notice theDSTAGE1_5=1optionmentionedabove.Wewillnotlookcloselyintostage1.5 justyet.Thesecondplacewherestart.sisbuiltisaspartofthestage2image.Inthis case,start.siscompiledandlinkedaloneintoastart.execimage.Thisimageisthen concatenatedtothebeginningofthestage2codethatiscalledpre_stage2inthe makefile.Seethestart_exec_SOURCES,stage2,andpre_stage2targetsin grub/stage2/makefile.am.AlsonoticethatSTAGE2_COMPILEdefinesthecompiler optionsusedwhencompilingthiscode.Inthiscase,noDSTAGE1_5optionisgivento thecompiler. asm.sisthestartingpointofbothstage1.5andstage2code.Itisthecodethatrunes afterthestartsector.asm.sisalsoincludedinbothstage1.5andstage2.Itiseither loaded(bystart.s)atabsoluteaddress08200(ifitispartofstage2)or02200(ifitis partofstage1.5).Itsetsupsegments,enablesprotectedmode,thencallstheC functioninit_bios_info().Init_bios_info()willdoitsbusinessandthencallcmain(). Cmain()thengoesontoprintthingsonthescreen,initializethecommandline,give youthegrubshell,andsoon.cmain()isdefinedingrub/stage2/stage2.c.In grub/stage2/makefile.am,lookforpre_stage2_exec_SOURCEStoseealistofthefiles includedinthestage2code.Also,seethestage2targettoseehowthispre_stage2 imageisconvertedtothefinalstage2imagebycombiningitwiththestartsector.

Nowletssumupwhathappenswhenyoubootfromthefloppythatwejustmade above.Thefirstsectorisloadedat0x7C00.Thisisthebootsector.Thissectorloads thesecondsectorat08000.Thisisthestartsector.Thestartsectorloadstherestof thefloppyataddress08200.Thecodethatalignswith08200istheasm.scode startingwiththe_startsymbol.

asghonim.wordpress.com/2013/11/03/understanding-grub-source-code/

3/6

3/12/14

Understanding GRUB Source Code | Ahmed S. Ghonim

Now,theguyswritingtheGRUBcodewantedtointroducetheconceptofafilesystem friendlybootloader.Whatthismeansisthattheywantedtoallowsuserstochangethe GRUBconfigurationandeventhegrubcodesimplybymodifyingfilesontheirownfile systemsratherthanhackingandslashingthroughsectorsandaddresses.Thesolution wasstage1.5.Theideaissimpleinsteadofloadingstage2bystage1,weloadanother image(alsofromthesecondsector).Thisimageisthenresponsibleforloadingthe stage2codefromafilesystem.Inordertodothiswithminimalchangestothecode thatisalreadyworking,theymadesuretomakestage1.5verysimilartostage2. Stage1.5alsobeginswiththestartsector,followedbytheasm.sandtherestofthe stage1.5Ccode.However,thestartsectorinstage1.5willnotbeloadedwherethe startsectorofstage2wasusedtobeloaded(address08000).Instead,thedesigners chosetoloaditstartingat02000to02200.Forthisreason,stage1.5cannotbe simplyconcatenatedtostage1onafloppydiskandworkseamlessly.Insteadyou mustusetheinstallorsetupcommandfromagrubshellorcommandline(loaded usingtheoldstylefloppy)toinstallthestage1.5.Thisisrequiredbecausetheinstall commandwillactuallygoinsidethestage1imageandchangethe08000valuethat wediscussedaboveinto02000beforeitcopiestheimagetothefloppyorharddisk whenitisinstallinggrubwithastage1.5step.Itdoesthisusingthemacros STAGE1_STAGE2_ADDRESSandSTAGE1_STAGE2_SEGMENTthatwementioned above.Seegrub/stage2/builins.cinthefunctioninstall_func,andlookfortheusageof thevariableinstalladdr.Thiswillmakesurethatthebootsectorloadsthestart.scode ataddress02000insteadof08000ifthatstartispartofastage1.5imageinsteadof astage2image.Startnowwilldoexactlyasitdidwiththeoldstage2image,copythe restrightafteritself.However,thistime,thedestinationis02200insteadofox8200. ThisisconstrolledbytheSTAGE1_5compileroptionsmentionedabove.Then,it
asghonim.wordpress.com/2013/11/03/understanding-grub-source-code/ 4/6

3/12/14

Understanding GRUB Source Code | Ahmed S. Ghonim

jumpstoasm.s,whichalsoneedstoknowthatitispartofstage1.5byusingthe STAGE1_5compileroption.Nowwhenasmcallsthecmain()function,thecmain()in thestage1.5.ciscalledbecauseitisactuallytheonlycmain()linkedthistime,notthe cmain()instage2.c Nowletsseewhathappensifyouusetheinstallcommandtosetupgrubonahard disk.First,youbuildthestage1andstage2imagesexactlyasbefore.Youalsobuild thestage1.5thatcanreadthefilesystemwereyouwillstorestage2.Then,youstart theGRUBshellandpointittothedirectorywhereyoukeepthoseimagesandthe devicewhereyouwanttoinstallGRUB.Theinstallcommandwilllookinsidethe stage1.5andstage2imagestolookforafieldcalledID.ThisIDtellsitwitheritis stage1.5orstage2.Incaseitisastage1.5,itwillmodifythestage1codetochange the08000valueintoa02200value.Thenitwillcopystage1,concatenatedby stage1.5,andfollowwiththerestofsetup.Whenyoubootfromthatdisknow,the stage1willbeloadedat0x7C00.Thisisthemodifiedstage1.stage1willnowloadthe firstsectorafteritself,thestartsector,toaddress02000,whichinturnwillloadthe restofthesectorsafteritself,stage1.5,startingat02200.Thenitwilljumpto02200 wheretheasm.sfilestartsexecution.Asm.sfinallycallsinit_bios_info()whichinturn callscmain()thatisfoundingrub/stage2/stage1.5.c Whencmain()isdone,youeitherhaveacommandlineorarunningkernelcode dependingonyourconfigurationfiles.

Twitter

Facebook

Like
Bethefirsttolikethis.

November3,2013inUncategorized.

Related posts
TheCaseoftheShrinkingDiskSpaceonWindows

TheCaseoftheShrinkingDiskSpace onWindows

One thought on Understanding GRUB Source Code

Yahia January3,2014at7:38AM
asghonim.wordpress.com/2013/11/03/understanding-grub-source-code/ 5/6

3/12/14

Understanding GRUB Source Code | Ahmed S. Ghonim

NiceTutorialAhmed,itssomethingusefulwhenyouwanttoknowhow yourOSboots(Veryusefultuto).Thankyou). Reply

Leave a Reply
Enteryourcommenthere...

BlogatWordPress.com.TheExpoundTheme.

asghonim.wordpress.com/2013/11/03/understanding-grub-source-code/

6/6

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