En informática , un cargador es la parte del sistema operativo responsable de cargar programas y bibliotecas . Es una de las etapas esenciales en el proceso de inicio de un programa, ya que lo coloca en la memoria y lo prepara para su ejecución. La carga de un programa implica mapear o copiar el contenido del archivo ejecutable que contiene las instrucciones del programa en la memoria, y luego realizar otras tareas preparatorias necesarias para que el ejecutable esté listo para su ejecución. Una vez completada la carga, el sistema operativo inicia el programa transfiriendo el control al código cargado.
Todos los sistemas operativos que admiten la carga de programas tienen cargadores, a excepción de los sistemas informáticos altamente especializados que solo tienen un conjunto fijo de programas especializados. Los sistemas embebidos normalmente no tienen cargadores y, en su lugar, el código se ejecuta directamente desde la ROM o similar. Para cargar el propio sistema operativo, como parte del arranque , se utiliza un cargador de arranque especializado . En muchos sistemas operativos, el cargador reside permanentemente en la memoria, aunque algunos sistemas operativos que admiten memoria virtual pueden permitir que el cargador se ubique en una región de memoria paginable .
En el caso de los sistemas operativos que admiten memoria virtual, el cargador puede no copiar realmente el contenido de los archivos ejecutables en la memoria, sino que simplemente puede indicar al subsistema de memoria virtual que existe una asignación entre una región de memoria asignada para contener el código del programa en ejecución y el contenido del archivo ejecutable asociado. (Véase archivo asignado a memoria ). El subsistema de memoria virtual es informado entonces de que las páginas con esa región de memoria deben llenarse bajo demanda si la ejecución del programa accede a esas áreas de memoria no llenas. Esto puede significar que partes del código de un programa no se copian realmente en la memoria hasta que se utilizan, y que el código no utilizado puede que nunca se cargue en la memoria.
Responsabilidades
En los sistemas Unix y similares a Unix , el cargador es el manejador de la llamada al sistemaexecve() . [ 1 ] Las tareas del cargador Unix incluyen:
- validación (permisos, requisitos de memoria, etc.);
- mapeo de memoria del objeto ejecutable desde el disco a la memoria principal ;
- copiando los argumentos de la línea de comandos en la memoria virtual;
- inicializar registros (por ejemplo, el puntero de pila);
- Saltando al punto de entrada del programa (
_start).
En Microsoft Windows 7 y versiones posteriores, el cargador es la LdrInitializeThunkfunción contenida en ntdll.dll , que realiza lo siguiente:
- inicialización de estructuras en la propia DLL (es decir, secciones críticas , listas de módulos);
- Validación del ejecutable a cargar;
- creación de un montón (a través de la función
RtlCreateHeap); - asignación del bloque de variables ambientales y del bloque PATH;
- adición del ejecutable y NTDLL a la lista de módulos (una lista doblemente enlazada );
- Carga de KERNEL32.DLL para obtener varias funciones importantes, por ejemplo
BaseThreadInitThunk; - carga recursiva de las importaciones del ejecutable (es decir, bibliotecas de enlace dinámico ) (verificar las importaciones de las importaciones, sus importaciones, etc.);
- en modo de depuración, elevación del punto de interrupción del sistema;
- inicialización de DLL;
- recolección de basura;
- llamar
NtContinueal parámetro de contexto dado a la función del cargador (es decir, saltar aRtlUserThreadStart, que iniciará el ejecutable)
Reubicación de cargadoras
Algunos sistemas operativos necesitan cargadores de reubicación , que ajustan las direcciones (punteros) del ejecutable para compensar las variaciones en la dirección de inicio de la carga. Los sistemas operativos que requieren cargadores de reubicación son aquellos en los que un programa no siempre se carga en la misma ubicación del espacio de direcciones (virtual) y en los que los punteros son direcciones absolutas en lugar de desplazamientos desde la dirección base del programa . Algunos ejemplos conocidos son el sistema operativo OS/360 de IBM para sus mainframes System/360 y sus derivados, incluido z/OS para los mainframes z/Architecture .
OS/360 y derivados
En OS/360 y sistemas descendientes, la utilidad del sistema operativo (privilegiada) se llama IEWFETCH, [ 2 ] y es un componente interno del Supervisor del sistema operativo, mientras que la aplicación LOADER (no privilegiada) puede realizar muchas de las mismas funciones, además de las del Editor de enlaces, y es completamente externa al Supervisor del sistema operativo (aunque ciertamente utiliza muchos servicios del Supervisor).
IEWFETCH utiliza programas de canal altamente especializados , y teóricamente es posible cargar y reubicar un ejecutable completo en una sola revolución del medio DASD (aproximadamente 16,6 ms como máximo, 8,3 ms de media, en unidades de 3600 rpm). Para módulos de carga que superan el tamaño de una pista, también es posible cargar y reubicar el módulo completo sin perder una revolución del medio.
IEWFETCH también incorpora funcionalidades para las denominadas estructuras de superposición, lo que facilita la ejecución de archivos ejecutables potencialmente muy grandes con un modelo de memoria mínimo (tan solo 44 KB en algunas versiones del sistema operativo, aunque 88 KB y 128 KB son más comunes).
El núcleo del sistema operativo (la parte del Supervisor que siempre reside en él) está formateado de forma compatible con una versión simplificada de IEWFETCH. A diferencia de los ejecutables normales, el núcleo del sistema operativo se carga de forma dispersa: partes del núcleo se cargan en diferentes porciones de la memoria; en particular, ciertas tablas del sistema deben residir por debajo de los 64 KB iniciales, mientras que otras tablas y código pueden residir en otros lugares.
La aplicación Editor de Enlaces del sistema se llama IEWL. [ 3 ] La función principal de IEWL es asociar módulos de carga (programas ejecutables) y módulos objeto (la salida de, por ejemplo, ensambladores y compiladores), incluidas las "llamadas automáticas" a bibliotecas (funciones integradas de lenguajes de alto nivel), en un formato que IEWFETCH pueda cargar de la manera más eficiente. Hay una gran cantidad de opciones de edición, pero para una aplicación convencional solo se utilizan algunas de ellas.
El formato del módulo de carga incluye un "registro de texto" inicial, seguido inmediatamente por el "registro de reubicación y/o control" para ese registro de texto, seguido de más instancias de pares de registros de texto y registros de reubicación y/o control, hasta el final del módulo.
Los registros de texto suelen ser muy grandes; los registros de reubicación y/o control son pequeños, ya que los tres búferes de registros de reubicación y/o control de IEWFETCH están fijados en 260 bytes (ciertamente son posibles registros de reubicación y/o control más pequeños, pero 260 bytes es el máximo posible, e IEWL garantiza que se cumpla esta limitación, insertando registros de reubicación adicionales, según sea necesario, antes del siguiente registro de texto, si es preciso; en este caso especial, la secuencia de registros puede ser: ..., registro de texto, registro de reubicación, ..., registro de control, registro de texto, ...).
Un byte especial dentro del búfer de registro de reubicación y/o control se utiliza como un área de comunicación de "giro de bits deshabilitado" y se inicializa con un valor único. El CCW de lectura para ese registro de reubicación y/o control tiene el bit de interrupción controlada por programa activado. De este modo, el procesador recibe una notificación cuando el canal accede a ese CCW mediante una salida especial de IOS . En este punto, el procesador entra en el bucle de "giro de bits deshabilitado" (a veces llamado "el bucle más corto del mundo"). Una vez que ese byte cambia de su valor inicial, la CPU sale del giro de bits y se produce la reubicación durante el "espacio" dentro del medio entre el registro de reubicación y/o control y el siguiente registro de texto. Si la reubicación finaliza antes del siguiente registro, el CCW NOP que sigue a la lectura se cambiará a un TIC, y la carga y reubicación continuarán utilizando el siguiente búfer; de lo contrario, el canal se detendrá en el CCW NOP hasta que IEWFETCH lo reinicie mediante otra salida especial de IOS. Los tres búferes se encuentran en una cola circular continua, cada uno apuntando al siguiente, y el último apuntando al primero, y los tres búferes se reutilizan constantemente a medida que avanza la carga y la reubicación.
De este modo, IEWFETCH puede cargar y reubicar un módulo de carga de cualquier tamaño práctico, y en el menor tiempo posible.
Enlazadores dinámicos
Los cargadores de enlace dinámico son otro tipo de cargador que cargan y enlazan bibliotecas compartidas (como archivos .so , archivos .dll o archivos .dylib) con programas en ejecución que ya están cargados.
Cuando dichas bibliotecas compartidas pueden ser utilizadas por múltiples procesos, y solo una copia del código compartido puede aparecer en una dirección (virtual) diferente en el espacio de direcciones de cada proceso, el código de la biblioteca compartida debe ser reubicable; es decir, la biblioteca solo debe usar direcciones internas autorreferenciales o relativas a la base del segmento de código. Algunos procesadores tienen instrucciones que pueden usar referencias de código autorreferenciales para facilitar esto.
Véase también
- lanzador de aplicaciones
- Compatibilidad de errores
- Compilar y ejecutar el sistema
- Encuadernación directa
- El infierno de las DLL
- Biblioteca de vínculos dinámicos
- Eliminación dinámica de código muerto
- Despacho dinámico
- Biblioteca dinámica
- Enlazador dinámico
- Carga dinámica
- Enlazador GNU
- oro (enlace)
- Unión tardía o enlace dinámico
- Biblioteca (informática)
- Enlazador (informática)
- Decoración de nombres
- Encuadernación previa
- prelink
- Enlace previo
- Reubicación (informática)
- Tabla de reubicación
- Shebang (Unix)
- Biblioteca estática
Referencias
- ↑ "exec" . The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition . The Open Group . Consultado el 23 de junio de 2008 .
- ↑ IBM Corporation (1972). Supervisor MVT del sistema operativo IBM (PDF) .
- ↑ IBM Corporation (1972). Editor y cargador de enlaces del sistema operativo IBM (PDF) .
- Bibliotecas informáticas
- núcleos de sistemas operativos