You are on page 1of 28

AdvancedOperatingSystems

EmbeddedfromScratch:
Systembootandhardwareaccess

FedericoTerraneo
federico.terraneo@polimi.it
Outline 2/ 28

Baremetalprogramming

HWarchitectureoverview
Linkerscript

Bootprocess
Highlevelprogramminglanguagesrequirements
Assemblerstartupscript
Hardwareaccess

Memorymappedperipheralregisters

Datasheets

Bitmanipulation
Example

BlinkingLED

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 3/ 28

HWarchitectureoverview
Systemmemory

Processesrunningontopofan
operatingsystemsliveina
virtualaddressspace

PointershandledinCprogram
canonlyaccessaddressesin
thevirtualspace

Aprocessiscompletelyisolated
fromthephysicaladdressspace

Loadingaprogramintomemory
isresponsibilityoftheoperating
system

Processescan'taccessHW
peripherals,butonlymake
syscallstotheOS
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 4/ 28

HWarchitectureoverview

ThisclassshowshowprogrammingisdonewithoutanOS
abstraction

Tolearnhowtoprograminabaremetalenvironment

ToseehowprogrammingisdoneinsideanOS

Tothesakeofsimplicitythetargetwillbeamicrocontroller
AcomputingdevicethatevennowadaysisoftenprogrammedwithoutanOS
Microcontrollerarchitecture

AsinglechipincludingCPUcore,memoryandperipherals
Acomputeronachip

WewillbeusingtheSTM32F407microcontroller

32bitsCPU,popularARM(CortexM4)architecture

Onchip192KBRAMand1MBofFlashmemory

Widerangeofonchipperipherals(USB,Ethernet,
ADC/DAC,Serialport,GPIO,etc...)
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 5/ 28

STM32F407HWarchitectureoverview

Nosupportforvirtualmemory Simplified
STM32F407Memorymap
C/C++programsarewritteninterms
ofphysicaladdresses 0xFFFFFFFF


ProgramcodeislocatedintheFlash,
Flashismemorymappedfromaddress0x0 Peripherals
DirectcodeexecutionfromFlashispossible
0x40000000

Stack,heapandglobalvariablesare
placedinRAM 0x2001FFFF

RAMismemorymappedat0x20000000 RAM
0x20000000

Addressesstartingfrom0x40000000
arereservedtohardwareperipherals 0xFFFFF

Issparselyused,mostlyunmapped
Flash
0x0

Partoftheaddressspaceisunmapped
Accessingunmappedareascausesafaultinterrupttobegenerated
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 6/ 28

Linkerscript

Thecompilationstagedoesnotdiffer Simplified
STM32F407Memorymap
fromOSbasedenvironments

Atthelinkingstage,whengenerating 0xFFFFFFFF

thebaremetalprogramthelinkerneeds
Peripherals
toknowwheretoplace
Code(.textsection)Flashmemory 0x40000000
Data(.data/.bss)RAM
0x2001FFFF
StackandHeaparealsoallocatedinRAM,but
atruntime RAM
0x20000000

Thisisthepurposeofthelinkerscript
Anadditionalfilepassedtothelinkerto 0xFFFFF

describethememoryregionsofthearchitecture Flash
0x0

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 7/ 28

LinkerscriptforaCprogramonSTM32F407(1/2)
ENTRYtellsthelinkerthefirst ENTRY(Reset_Handler)
functionthatwillbecalledatboot MEMORY
{
MEMORYsectionspecifiesthe flash(rx):ORIGIN=0x00000000,LENGTH=1M
hardwarememorylayout ram(wx):ORIGIN=0x20000000,LENGTH=128K
}
_stack_topisavariabledefining
thestartaddressoftheStack _stack_top=0x20000000+128*1024;

SECTIONSblocktellsthelinker SECTIONS
{
howtomaptheprogramsections .=0;
intomemoryregions
.text:
.isaspecialvariablecalled {
locationcounterthatis /*Startupcodemustgoataddress0*/
KEEP(*(.isr_vector))
incremented,aftereachsection *(.text)
mapping,bythesectionsize .=ALIGN(4);
*(.rodata)
}>flash
Thisblockmapsthe.isr_vector,
.textand.rodatasectionstothe .=ALIGN(8);
_etext=.;
Flash

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 8/ 28

LinkerscriptforaCprogramonSTM32F407(2/2)

Thisblockmapsthe.datasectiontoRAM,
.data:
butplacesalsoacopyofitintheFlash {
(toinitializeitatboot) _data=.;
*(.data)
.=ALIGN(8);
Thisblockmapsthe.bss,sectionto _edata=.;
}>ramAT>flash
RAM,

_bss_start=.;
.bss:
{
Thelinkerscriptdefinesmanyvariablesthat *(.bss)
willbeusedforinitializingsectionsat .=ALIGN(8);
runtimeandALIGNcommandstosatisfy }>ram
thealignmentrequirementsoftheprocess _bss_end=.;

ABI(ApplicationBinaryInterface) _end=.;
}

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 9/ 28

Bootprocess

ACPUcanbeseenasacomplexstatemachineexecutingthe
instructionpointedbytheProgramCounter(orInstructionPointer)
register,andincrementingittoexecutethenextinstruction


Question:Wheredoestheprocessorstartexecutingcodefrom,
whenthesystemispoweredon?

Theanswerisarchitecturedependent,buttherearetwocommon
solutions
1)SettheProgramCountertoapredefinedaddress(e.g.,0x0)toidentifythe
firstinstructiontoexecute
2)Readapredefinedmemorylocationcontainingtheaddressofthefirst
instruction,andusethatvaluetoinitializetheProgramCounter(ARMCortex
processorsapproach)

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 10/ 28

Bootprocess

IntheSTM32F407theaddressofthefirstinstructionmustbe
placedat0x00000004


Question:Isitenoughtoputtheretheaddressofthemain()
functionofaCprogram?

Answer:NOHighlevelprogramminglanguagesmakeassumption
aboutthestateoftheirexecutionenvironment
BeittheabstractionofaprocessinaOSorabaremetalmachine


Asmallpartoftheprogramneedstobewritteninassembler
Thepartexecutedatbootaimsatsatisfyingtheassumptionsabove


WearegoingtoseeassumptionsmadeforCandC++programs

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 11/ 28

Cprogramminglanguagerequirements

Thestackpointerregistermustpointtothetopofasuitablememoryarea
Thecompilerimplicitlyusesthestacktoallocatelocalvariableswithinfunctions
Untilthestackpointerisinitializedonlyassemblercodecanbeexecuted

Globalandstaticinitializedvariablesmustsettotheirinitialvalue
SincetheyareplacedinRAM,andafterthepoweronthecontentofRAMisrandom,
theymustbeexplicitlyinitialized

Globalandstaticuninitializedvariablesmustbesetto0


Iftheprogramusestheheap,additionalsupportisrequired
Forbaremetalembeddedsystemstheenvironmentmaychoosetonotprovideanheap
inthememory

IftheprogramusestheCstandardlibrary,certainsyscallsneedtobe
providedtoperformtherequestedhighleveloperations
Forexamplewrite()iscalledbyprintf,open()whenopeningafile
Forbaremetalembeddedsystemstheenvironmentmaychoosetonotprovidean
implementationofthesesyscalls
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 12/ 28

Cprogramminglanguagestartupscript(1/2)
AssemblerfileidentificationforARM .syntaxunified
.cpucortexm4
CortexM4processors .thumb

Sectioncontainingatableofpointers .section.isr_vector
.global__Vectors
0x00000000=stackpointerinit __Vectors:
definedinthe
0x00000004=programcounterinit .word_stack_top
linkerscript
.wordReset_Handler

.section.text
Reset_Handlerfunctiondeclaration .globalReset_Handler
.typeReset_Handler,%function
Reset_Handler:
/*Copy.datafromFLASHtoRAM*/
ldrr0,=_data
ldrr1,=_edata definedinthe
ldrr2,=_etext linkerscript
cmpr0,r1
Thisblockcopies.datasection beqnodata
fromFlashtoRAM(asshownin subsr2,r2,#4
dataloop:
thelinkerscript) ldrr3,[r2,#4]!
strr3,[r0],#4
cmpr1,r0
bnedataloop
nodata:

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 13/ 28

Cprogramminglanguagestartupscript(2/2)

/*Zero.bss*/
ldrr0,=_bss_start
definedinthe
ldrr1,=_bss_end
linkerscript
cmpr0,r1
beqnobss
Thisblocksettozero.bsssection movsr3,#0
bssloop:
strr3,[r0],#4
cmpr1,r0
bnebssloop
nobss:
/*Jumptomain()*/
blisthefunctioncallinstruction blmain
/*Ifmain()returns,endlessloop*/
inARMassembly loop:
bloop
.size Reset_Handler,.Reset_Handler

WewillNOTseehowtoprovideaheapnorhowto
implementsyscallsinabaremetalenvironment
FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 14/ 28

C++programminglanguagerequirements

AlltherequirementsfortheCprogramminglanguage
AswithC,theheapandsyscallsmaybeomittedifnotused


Constructorsofglobalobjectsneedtobecalledbeforemain

C++classescanhaveconstructors

C++objectscanbedeclaredasglobalvariable

Theirconstructorsneedtobecalled!


Iftheprogramusesexceptions,additionalsectionsaregeneratedby
thecompilerthatneedtobehandledinthelinkerscript
Forbaremetalembeddedsystemstheenvironmentmaychoosetonotprovide
C++exceptionsupport

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 15/ 28

LinkerscriptforaC++programonSTM32F407
Nodifferencewithrespectto ENTRY(Reset_Handler)
Cprogramcase
SECTIONS
{
.=0;

.text:
{
/*Startupcodemustgoataddress0*/
.init_arraysectioncontainsa KEEP(*(.isr_vector))
table(builtbythecompiler) *(.text)
offunctionpointerstothe .=ALIGN(4);
*(.rodata)
constructorsofglobalobjects
/*Tableofglobalconstructors,forC++*/
.=ALIGN(4);
__init_array_start=.;
KEEP(*(.init_array))
__init_array_end=.;

Nomoredifferenceswithrespect }>flash
toCprogramcase

FedericoTerraneo AdvancedOperatingSystems
Baremetalprogramming 16/ 28

C++programminglanguagestartupscript
Nodifferencewithrespectto
.globalReset_Handler
Cprogramcase .typeReset_Handler,%function
Reset_Handler:
Reset_Handlerfunctionfirst
initializes.dataand.bss,asglobal nobss:
/*CallglobalcontructorsforC++
constructorsmayreferenceother Can'tuser0r3asthecallee
globalvariables doesn'tpreservethem*/
ldrr4,=__init_array_start
ldrr5,=__init_array_end
cmpr4,r5
beqnoctor
ctorloop:
Thisloopcallsthefunction ldrr3,[r4],#4
blxr3
pointersonebyone cmpr5,r4
bnectorloop
Nomoredifferenceswithrespect noctor:
/*Jumptomain()*/
toCprogramcase blmain
/*Ifmain()returns,endlessloop*/
loop:
bloop
.size Reset_Handler,.Reset_Handler

FedericoTerraneo AdvancedOperatingSystems
Outline 17/ 28

Baremetalprogramming

HWarchitectureoverview
Linkerscript

Bootprocess
Highlevelprogramminglanguagesrequirements
Assemblerstartupscript
Hardwareaccess

Memorymappedperipheralregisters

Datasheets

Bitmanipulation
Example

BlinkingLED

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 18/ 28

HW/SWinterfacing

Question:howcansoftwareinteractwithhardware?

Peripheralregisters

Mostcommonwayusedbyhardwareperipheralstoexposetheir
functionalitytothesoftware

Memorylocationsmappedtospecificaddressesintheprocessor
addressspace

MustnotbeconfusedwithCPUregisters!

Mappedatphysicaladdresses(notvirtualones)
Inoperatingsystemswithmemoryprotection(Linux,Mac,Windows)are
accessibleonlyfromwithintheOSkernel
Inamicrocontrollerenvironmenttheyarefreelyaccessible

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 19/ 28

Memorymappedperipheralregisters:

Similaritieswithprogramminglanguagesvariables

Accessibleinthesameway
Forexample,throughload/storeassemblerinstructionsinRISCprocessors

Inmanycasestheycanbereadandwritteninsoftware
Evenifsomeregistersmaybereadonly

8,16or32bitwide,justlikeunsignedchar,unsignedshortand
unsignedintdatatypesinC/C++

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 20/ 28

Memorymappedperipheralregisters:

Differenceswithprogramminglanguagesvariables

Whatgetswritteninthoseregisterscausesactionsintherealworld
SuchasaLEDturningon,anADCinitiatingaconversion,acharacterbeingsent
throughaserialport,etc...

Theyareatwellspecifiedmemoryaddresses
WhenavariableisallocatedinRAM,whetheronthestackortheheap,tothe
programmeritdoesntmattertheaddresswhereitisallocated
Whileifaperipheralregisterismappedattheaddress0x101e5018the
programmerneedstobesurethatiswritingatthataddress

Peripheralregistersarenotatexclusiveusetotheprogrammer,
theyaresharedbetweenthehardwareandsoftware
Thehardwarecandecidetochangethecontentofaregistertosignaleventsor
statusflags,whilevariablessimplykeepthevaluestoredinthembythe
programmer
FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 21/ 28

Memorymappedperipheralregisters

Question:Howcanaprogrammerknowtheperipheralsavailablein
agivenarchitecture?

Foramicrocontroller,availableperipheralsaredetailedina
document,usuallycalleddatasheetorreferencemanual
Datasheetsareusuallyavailableatthemanufacturerswebsite


Question:Assumingthereisa32bitregistercalledIODIR0,at
address0xe0028008,howtoaccessfromaC/C++program,
writing0toit?

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 22/ 28

Memorymappedperipheralregisters(accessmethod1)
voidclearReg()
{
(*((volatileunsignedint*)0xe0028008))=0;
}


WeuseaCcastoperatortocastthe0xe0028008numbertoapointerto
anunsignedintdatatype.
Thechoiceofanunsignedintisduetothatfactthattheregisterisa32bitregisterand
unsignedintisa32bitdatatype(ona32bitprocessor)

The'*'attheleftdereferencesthepointer,thusgivingaccesstothe
memorylocationpointedtobythepointer

Zeroiswrittenintothataddress

volatilekeywordisnecessarytodisablecompileroptimizations
Suchasinstructionreorderingandredundantwriteeliminationthatcauseproblemsas
thecompilerisnotawarethatatthatmemorylocationthereisaperipheralregister

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 23/ 28

Memorymappedperipheralregisters(accessmethod1)
#defineIODIR0(*((volatileunsignedint*)0xe0028008))

voidclearReg()
{
IODIR0=0;
}


Morereadablecode
Makeswritingtoaperipheralregistermoresimilarinsyntaxtowritingtoa
variable
UseofthesymbolicnameIODIR0canbeeasilylookedupinthedatasheet

Commonpractice:togroupmacrosdefiningallregistersofan
architectureinanheaderfile
Mostmicrocontrollermanufacturersalreadyprovidethatheaderfile

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 24/ 28

Memorymappedperipheralregisters(accessmethod2)

Rarelyaperipheralhasonlyoneregister
Usuallyaperipheraliscontrolledthroughasetofregisters,thatareoften
mappedatcontiguousorclosebyaddresses

Thisallowsgroupingallperipheralregistersinadatastructure,like
this
structGpioPeripheral
{
volatileunsignedintCRL;
volatileunsignedintCRH;
volatileunsignedintBSRR;
volatileunsignedintBRR;
};

#defineGPIO((structGpioPeripheral*)0xfeeeaba0)

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 25/ 28

Memorymappedperipheralregisters(accessmethod2)

Usingthismethod,thecodetoclearregisterCRLintheGPIO
peripheralis:
voidclearReg()
{
GPIO>CRL=0;
};


Therearenodifferences,noteveninperformancebetweenthetwo
methods

Somemanufacturershoweverusethefirstmethod,somethesecond
one,soitisnecessarytoknowboth

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 26/ 28

Datasheets

Thefigurebelowshowsatypicalperipheralregisterasdocumented
inadatasheet

Informationprovidedforeachregister

Name(e.g.,REGEXAMPLE)

Addressinmemory(0xE0000004)

Meaningandaccesspermissionsofallthebits
Whethertheyarereadable(r)and/orwritable(w)
Somebitsmaybeunused

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 27/ 28

Bitmanipulation

Giventhefollowingregisterrepresentationincode:
#defineREGEXAMPLE(*((volatileunsignedchar*)0xe0000004))

Questions
1)HowtosetbitENto1leavingtheotherbitsunaffected?
2)HowtoclearbitCNF2to0leavingtheotherbitsunaffected?
3)HowtotestifbitFLAGAissetto1?

Answers
1)REGEXAMPLE|=(1<<0);
2)REGEXAMPLE&=~(1<<2);
3)if(REGEXAMPLE&(1<<4)){}

FedericoTerraneo AdvancedOperatingSystems
Hardwareaccess 28/ 28

Bitmanipulation

FedericoTerraneo AdvancedOperatingSystems

You might also like