Carregador (informàtica)
En els sistemes informàtics, un carregador és la part d'un sistema operatiu que s'encarrega de carregar programes i biblioteques. És una de les etapes essencials en el procés d'inici d'un programa, ja que col·loca els programes a la memòria i els prepara per a l'execució. La càrrega d'un programa implica el mapeig de memòria o copiar el contingut del fitxer executable que conté les instruccions del programa a la memòria i, a continuació, dur a terme altres tasques preparatòries necessàries per preparar l'executable per a l'execució. Un cop finalitzada la càrrega, el sistema operatiu inicia el programa passant el control al codi del programa carregat.[1]
Tots els sistemes operatius que admeten la càrrega de programes disposen de carregadors, a part dels sistemes informàtics altament especialitzats que només tenen un conjunt fix de programes especialitzats. Els sistemes incrustats normalment no tenen carregadors i, en canvi, el codi s'executa directament des de la ROM o similar. Per carregar el propi sistema operatiu, com a part de l'arrencada, s'utilitza un carregador d'arrencada especialitzat. En molts sistemes operatius, el carregador resideix permanentment a la memòria, tot i que alguns sistemes operatius que admeten memòria virtual poden permetre que el carregador estigui situat en una regió de memòria que és paginable.[2]
En el cas dels sistemes operatius que admeten memòria virtual, és possible que el carregador no copie realment el contingut dels fitxers executables a la memòria, sinó que simplement pot declarar al subsistema de memòria virtual que hi ha un mapeig entre una regió de memòria assignada per contenir l'execució. codi del programa i el contingut del fitxer executable associat. Aleshores, el subsistema de memòria virtual s'informa que les pàgines amb aquesta regió de memòria s'han d'omplir a demanda si i quan l'execució del programa arriba a aquestes àrees de memòria sense omplir. Això pot significar que parts del codi d'un programa no es copien a la memòria fins que s'utilitzen realment, i és possible que el codi no utilitzat mai es carregui a la memòria.[3]
Responsabilitats
[modifica]A Unix, el carregador és el gestor de la crida al sistema execve()
.[4] Les tasques del carregador Unix inclouen:
- validació (permisos, requisits de memòria, etc.);
- mapeig de memòria de l'objecte executable des del disc a la memòria principal;
- copiant els arguments de la línia d'ordres a la memòria virtual;
- inicialització de registres (per exemple, el punter de pila);
- saltant al punt d'entrada del programa (
_start
).
A Microsoft Windows 7 i posteriors, el carregador és la funció LdrInitializeThunk
continguda a ntdll.dll, que fa el següent:
- inicialització d'estructures a la pròpia DLL (és a dir, seccions crítiques, llistes de mòduls);
- validació de l'executable per carregar;
- creació d'un munt (mitjançant la funció
RtlCreateHeap
); - assignació del bloc de variables d'entorn i del bloc PATH;
- addició d'executable i NTDLL a la llista de mòduls (una llista doblement enllaçada);
- càrrega de KERNEL32. DLL per obtenir diverses funcions importants, per exemple
BaseThreadInitThunk
; - càrrega de les importacions d'executables (és a dir, biblioteques d'enllaços dinàmics) de forma recursiva (comproveu les importacions de les importacions, les seves importacions, etc.);
- en mode de depuració, augmentant el punt d'interrupció del sistema;
- inicialització de DLL;
- recollida d'escombraries;
- cridant
NtContinue
al paràmetre de context donat a la funció de càrrega (és a dir, saltar aRtlUserThreadStart
, que iniciarà l'executable)
Reubicació de carregadors
[modifica]Alguns sistemes operatius necessiten reubicar carregadors, que ajusten les adreces (punters) a l'executable per compensar les variacions en l'adreça en què comença la càrrega. Els sistemes operatius que necessiten desplaçar carregadors són aquells en què un programa no sempre es carrega a la mateixa ubicació de l'espai d'adreces (virtual) i en els quals els punters són adreces absolutes en lloc de desplaçaments de l'adreça base del programa. Alguns exemples coneguts són l'OS/360 d'IBM per als seus mainframes System/360 i els seus descendents, inclòs z/OS per als mainframes z/Architecture.
Enllaçadors dinàmics
Els carregadors d'enllaç dinàmic són un altre tipus de carregador que carreguen i enllacen biblioteques compartides (com ara fitxers.so, fitxers.dll o fitxers.dylib) a programes en execució ja carregats.
Quan aquestes biblioteques compartides es poden compartir per diversos processos, amb una única còpia del codi compartit possiblement apareixent en una adreça (virtual) diferent a l'espai d'adreces de cada procés, cal que el codi de la biblioteca compartida sigui reubicable, és a dir, la biblioteca. només ha d'utilitzar adreces internes relatives a si mateixes o de segment de codi base-relatives a tot arreu. Alguns processadors tenen instruccions que poden utilitzar referències de codi auto-relatius per tal de facilitar-ho.
Referències
[modifica]- ↑ Chatterjee, Puja. «What is Loader? Types, Functions, Pros, Cons & More» (en anglès americà), 13-02-2023. [Consulta: 9 desembre 2023].
- ↑ «Loader in Compiler Design» (en anglès americà), 26-01-2023. [Consulta: 9 desembre 2023].
- ↑ «Loader (computing) explained» (en anglès). [Consulta: 9 desembre 2023].
- ↑ «exec» (en anglès). The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition. The Open Group. [Consulta: 23 juny 2008].