top of page

Calea catre main() - intro



In liceu am invatat ca un program incepe de la main(), acest lucru fiind valabil in mai multe limbaje de uz intens.


De ce main()?

Ce-i drept, aceasta este o regula nescrisa in lumea programarii asupra entry-pointului (punctul de pornire al unui program). In loc de acest main() putem avea chiar si ProgramulMeuIncepeAici().

Cati dintre voi s-au intrebat ce se intampla pana a se atinge acest entry-point in programul construit?

Procesul este interesant si in esenta este comun.


Start at hardware

Daca pornim de la hardware, fie ca avem un procesor Intel/ AMD/ MIPS etc., fie ca avem un microcontroller de la Freescale/ Renesas/ Infineon etc., toate vor avea anumite “pretentii” cu privire la metoda de pronire a softwareului. De regula, pe langa aplicatia pe care am construit-o, va exista o bucata de software preprogramata de catre furnizorul de solutii (microcontroler, placa de baza). La sistemele de calcul cu procesor, BIOSul este cel care defineste ce se intampla in hardware. De asemenea sursa softwareului este aleasa tot de BIOS.

Unitatile de calcul vor citi de cele mai multe ori o bucata de memorie non volatila, fie ea interna (ROM/ OTP) fie ea externa (ROM/ OTP/ HDD/ SSD). La acea adresa, se afla o serie de bytes specifici. Acesti bytes sunt fie cititi de un soft preprogramat (inca din productie), fie sunt “legati” (hardwired) catre anumiti tranzistori care activeaza anumite functii.


Start-up flow:

Concret, pe un sistem PowerPC, tranzitia de la nivel hardware catre software se face astfel:

  • o bucata de SW este programata intr-o memorie ce “nu poate” fi stearsa

  • acea bucata de SW va cauta in mai multe sectoare de memorie (sector = mai multe pagini unde, pagina = unitatea minim programabila) un anumit pattern de date

  • odata identificat acest pattern, in acelasi sector (la o alta adresa) se va afla adresa de inceput a programului de start-up.

Din acest punct, suntem responsabili sa definim toti pasii necesari pentru a asigura un mediu stabil si initializat corespunzator pentru aplicatia noastra.

Exemplul prezentat anterior defineste o pornire avand ca sursa, memoria interna unde noi am programat o anumita secventa.

Pornirea se poate face prin intermediul altor surse externe.

In lumea Automotive, avem numeroase protocoale de comunicatie si din acest motiv, furnizorii s-au gandit si la solutii alternative. Un microcontroller poate fi setat sa astepte anumite secvente prin intermediul unui protocol de comunicare. Aceste secvente ii vor permite sa scrie anumite informatii intr-un mediu de stocare volatil/ nevolatil. Ulterior, informatia poate fi citita de unitatea de procesare si sa ajunga la secventa de start-up.


Toate drumurile duc catre... start-up code:

Scopul principal al secventei de start-up este de a asigura o initializare minimala a hardware-ului pana la entry-pointul main().

De regula, urmatorul set minimalist de proceduri este incorporat in secventa initializare:

  • configurarea hardwareului incat sa nu genereze vreun reset nedorit (eg. watchdog deactivation, stabilizare de oscilatoare etc.)

  • setarea tuturor registrilor procesorului (program counter, GPRs, link registers, stack pointer, heap pointer etc.)

  • activarea exceptiilor de procesor (interuperi cu prioritate foarte mare generate ca urmare a unei operatii neobisnuite - e.g. eroare pe bus)

  • initializarea RAMului: setarea pe 0 a segmentelor de .data, .sdata, .zdata, .bss, .sbss etc.

  • activarea nucleelor procesorului daca acesta are capacitati multicore

  • setarea cacheului daca se lucreaza in mod direct cu acest tip de memorie

  • copierea initializatorilor (e.g. variable1 = 25) din segmentul de memorie aferent imaginii de ROM, in segmentul .data, .sdata.

  • saltul catre main() efectuat printr-o instructiune de jump ce ia ca si offset, diferenta de adresa pana la simbolul main()

In incheiere...

Cum spuneam intial, acest main() poate fi inlocuit cu orice symbol care respecta sintaxa definita de limbajul de programare. De regula insa, prin constrangeri de coding style sau prin constrangeri de biblioteci, numele rutinei va fi de cele mai multe ori main().

Intr-un articol ulterior, voi prezenta mai detaliat ce implica fiecare din pasii de initializare si ce probleme ar putea fi intalnite.

Cu speranta ca a mai disparut din ideea ca “magic happens” pana ce codul ajunge in main(), astept completarile/ reactiile voastre in sectiunea de comenturi.

29 afișări0 comentarii

Postări recente

Afișează-le pe toate

Comments


bottom of page