La A20 , o línea de dirección 20 , es una de las líneas eléctricas que componen el bus de sistema de un sistema informático basado en x86 . La línea A20, en particular, se utiliza para transmitir el bit 21 del bus de dirección .
Un microprocesador normalmente tiene un número de líneas de dirección igual al logaritmo en base dos del número de palabras en su espacio de dirección física . Por ejemplo, un procesador con 4 GB de espacio físico direccionable por bytes requiere 32 líneas (log 2 (4 GB) = log 2 (2 32 B) = 32), que se denominan A0 a A31. Las líneas se nombran según el número basado en cero del bit en la dirección que están transmitiendo. El bit menos significativo es el primero y, por lo tanto, se numera como bit 0 y se señala en la línea A0. A20 transmite el bit 20 (el bit 21) y se activa una vez que las direcciones alcanzan 1 MB, o 2 20 .
Los procesadores Intel 8086 , Intel 8088 e Intel 80186 tenían 20 líneas de dirección, numeradas de A0 a A19; con ellas, el procesador puede acceder a 220 bytes , o 1 MB. Los registros de dirección internos de dichos procesadores solo tenían 16 bits. Para acceder a un espacio de dirección de 20 bits, una referencia de memoria externa estaba formada por una dirección de desplazamiento de 16 bits sumada a un número de segmento de 16 bits , desplazado 4 bits a la izquierda para producir una dirección física de 20 bits. La dirección resultante es igual a segmento × 16 + desplazamiento . [1] Hay muchas combinaciones de segmento y desplazamiento que producen la misma dirección física de 20 bits. Por lo tanto, había varias formas de direccionar el mismo byte en la memoria. [2] Por ejemplo, aquí hay cuatro de las 4096 combinaciones diferentes de segmento: desplazamiento, todas haciendo referencia al byte cuya dirección física es 0x000FFFFF (el último byte en un espacio de memoria de 1 MB):
En la última referencia, un aumento de uno en el desplazamiento da como resultado F800:8000 , que es una dirección adecuada para el procesador, pero dado que se traduce a la dirección física 0x00100000 (el primer byte sobre 1 MB), el procesador necesitaría otra línea de dirección para el acceso real a ese byte. Dado que no existe dicha línea en la línea 8086 de procesadores, el bit 21 anterior, aunque está configurado, se omite, lo que hace que la dirección F800:8000 "envuelva" [1] y apunte realmente a la dirección física 0x00000000 .
Cuando IBM diseñó la máquina IBM PC AT (1984), decidió utilizar el nuevo microprocesador Intel 80286 de mayor rendimiento . El 80286 podía direccionar hasta 16 MB de memoria del sistema en modo protegido . Sin embargo, se suponía que la CPU debía emular el comportamiento de un 8086 en modo real , su modo de inicio, de modo que pudiera ejecutar sistemas operativos y programas que no estuvieran escritos para el modo protegido. Sin embargo, el 80286 no forzaba la línea A20 a cero en modo real. Por lo tanto, la combinación F800:8000 ya no apuntaría a la dirección física 0x00000000 , sino a la dirección 0x00100000 . Como resultado, los programas que dependían del ajuste de direcciones ya no funcionarían. Para seguir siendo compatible con dichos programas, IBM decidió corregir el problema en la placa base .
Esto se logró insertando una puerta lógica en la línea A20 entre el procesador y el bus del sistema, que se denominó Gate-A20 . Gate-A20 se puede habilitar o deshabilitar mediante software para permitir o evitar que el bus de direcciones reciba una señal de A20. Está configurado para que no pase para la ejecución de programas más antiguos que dependen del wrap-around. En el momento del arranque, el BIOS primero habilita Gate-A20 cuando cuenta y prueba toda la memoria del sistema, y luego lo deshabilita antes de transferir el control al sistema operativo.
Originalmente, la puerta lógica era una puerta conectada al controlador de teclado Intel 8042. [1] Controlarla era un proceso relativamente lento. Desde entonces se han añadido otros métodos para permitir una multitarea más eficiente de los programas que requieren esta integración con programas que acceden a toda la memoria del sistema. Existen múltiples métodos para controlar la línea A20. [3]
Desconectar A20 no cubriría todos los accesos a la memoria por encima de 1 MB, solo aquellos en los rangos de 1-2 MB, 3-4 MB, 5-6 MB, etc. El software de modo real solo se preocupaba por el área ligeramente por encima de 1 MB, por lo que la línea Gate-A20 era suficiente.
Habilitar la línea Gate-A20 es uno de los primeros pasos que un sistema operativo x86 en modo protegido realiza en el proceso de arranque, a menudo antes de que el control haya sido pasado al kernel desde el arranque (en el caso de Linux , por ejemplo).
El modo virtual 8086 , introducido con el Intel 80386 , permite simular el envoltorio A20 utilizando las funciones de memoria virtual del procesador; la memoria física puede asignarse a múltiples direcciones virtuales. De este modo, la memoria asignada en el primer megabyte de memoria virtual puede asignarse nuevamente en el segundo megabyte de memoria virtual. El sistema operativo puede interceptar cambios en la Puerta A20 y realizar cambios correspondientes en el espacio de direcciones de memoria virtual, lo que también hace irrelevante la eficiencia de la alternancia de línea Puerta-A20.
El control de la línea A20 fue una característica importante en una etapa del crecimiento de la arquitectura de IBM PC, ya que agregó acceso a 65.520 bytes adicionales (64 KB − 16 bytes) de memoria en modo real , sin cambios de software significativos.
En lo que podría decirse que fue un "hack", la puerta A20 era originalmente parte del controlador del teclado en la placa base, que podía abrirla o cerrarla dependiendo del comportamiento deseado. [4]
Para mantener la compatibilidad total con el Intel 8086 , la compuerta A20 estuvo presente en las CPU Intel hasta 2008. [5] Como la compuerta se cerraba inicialmente justo después del arranque, los sistemas operativos en modo protegido normalmente abrían la compuerta A20 al principio del proceso de arranque para no volver a cerrarla nunca más. Dichos sistemas operativos no tenían motivos de compatibilidad para mantenerla cerrada, y obtenían acceso a toda la gama de direcciones físicas disponibles al abrirla.
Los procesadores Intel 80486 y Pentium añadieron un pin especial llamado A20M# , que cuando se activaba en modo bajo obligaba a que el bit 20 de la dirección física fuera cero para todos los accesos a la memoria caché integrada o a la memoria externa. Esto era necesario, ya que el 80486 introdujo una memoria caché integrada y, por tanto, ya no era posible enmascarar este bit en la lógica externa. El software todavía necesita manipular la puerta y debe seguir lidiando con los periféricos externos (el chipset ) para ello. [6]
La Guía de diseño de sistemas de PC PC 2001 elimina la compatibilidad para la línea A20: "Si la lógica de generación de A20M# todavía está presente en el sistema, esta lógica debe terminarse de manera que el software escriba en el puerto de E/S 92, bit 1, no dé como resultado que se confirme A20M# al procesador". [7]
La compatibilidad con la compuerta A20 se modificó en la microarquitectura Nehalem (algunas fuentes afirman incorrectamente que se eliminó la compatibilidad con A20). En lugar de que la CPU tenga un pin A20M# dedicado que reciba la señal de si se debe enmascarar o no el bit A20, se ha virtualizado para que la información se envíe desde el hardware periférico a la CPU mediante ciclos de bus especiales. [ cita requerida ] Desde un punto de vista de software, el mecanismo funciona exactamente como antes, y un sistema operativo aún debe programar hardware externo (que a su vez envía los ciclos de bus antes mencionados a la CPU) para deshabilitar el enmascaramiento A20. [ cita requerida ]
Intel ya no admite la compuerta A20, a partir de Haswell . La página 271 del Manual del programador de sistemas Intel, vol. 3A, de junio de 2013, establece: "La funcionalidad de A20M# se utiliza principalmente en sistemas operativos más antiguos y no en sistemas operativos modernos. En los procesadores Intel 64 más nuevos , A20M# puede estar ausente". [8]
El controlador A20 es un software de gestión de memoria de IBM PC que controla el acceso al área de memoria alta (HMA). Los administradores de memoria extendida suelen ofrecer esta funcionalidad. Los controladores A20 reciben su nombre de la línea de dirección número 21 del microprocesador, la línea A20.
En DOS , los administradores de HMA como HIMEM.SYS tienen la "tarea adicional" de administrar A20. HIMEM.SYS proporcionó una API para abrir y cerrar A20. El propio DOS podría usar el área para algunas de sus necesidades de almacenamiento, liberando así más memoria convencional para los programas. Esa funcionalidad fue habilitada por las directivas DOS=HIGH
o HIDOS=ON
en el archivo de configuración CONFIG.SYS .
Desde 1980, el wrap de dirección fue usado internamente por 86-DOS y MS-DOS para implementar el punto de entrada CALL 5 de DOS en el desplazamiento +5 a +9 (que emula el punto de entrada de API CALL 5 BDOS de estilo CP/M-80 en el desplazamiento +5 a +7) en el Prefijo de Segmento de Programa (PSP) (que se parece parcialmente a la página cero de CP/M-80 ). [9] [10] Esto fue utilizado, en particular, por programas traducidos por máquina desde CP/M-80 a través de traductores de lenguaje ensamblador [9] como TRANS86 de Seattle Computer Products . [11] El manejador CALL 5 al que se refiere este punto de entrada reside en la dirección física de la máquina 0x000000C0 (superponiendo así los cuatro bytes del punto de entrada de rutina de servicio de interrupción reservado para INT 30h y el primer byte de INT 31h en la tabla de vectores de interrupción de modo real x86 ). [12] [13] [14] Sin embargo, debido al diseño de CP/M-80, que cargaba el sistema operativo inmediatamente encima de la memoria disponible para que se ejecutara el programa de aplicación, la dirección de destino de 16 bits del 8080 / Z80 almacenada en el desplazamiento +6 a +7 en la página cero también podría interpretarse deliberadamente como el tamaño del primer segmento de memoria. [9] Para emular esto en DOS con su esquema de direccionamiento segmento:desplazamiento 8086, el desplazamiento de 16 bits del punto de entrada de llamada lejana tenía que coincidir con este tamaño de segmento (es decir, 0xFEF0 ), que se almacena en el desplazamiento +6 a +7 en el PSP, superponiendo partes del CALL 5. [13] [14] La única forma de conciliar estos requisitos era elegir un valor de segmento que, cuando se sumaba a 0xFEF0 , daba como resultado una dirección de 0x001000C0 , que, en un 8086, daba como resultado 0x000000C0 . [15] [12] [14]
A20 tuvo que ser deshabilitado para que se produjera el cambio de dirección y para que los programas DOS que utilizan esta interfaz funcionaran. Las versiones más nuevas de DOS que pueden reubicar partes de sí mismas en la HMA, generalmente crean una copia del punto de entrada en FFFF:00D0 en la HMA (que nuevamente se resuelve en 0x001000C0 físico ), de modo que la interfaz pueda funcionar sin tener en cuenta el estado de A20. [14] [16]
Un programa que se sabe que utiliza la interfaz CALL 5 es la versión DOS del compilador Small-C . [17] Además, la utilidad SPELL en Word 3.0 (1987) de Microsoft es uno de los programas que dependen de la interfaz CALL 5 y que deben configurarse de forma correspondiente. [18] PC-NFS (1993) de Sun Microsystems también requiere la corrección de CALL 5. [16]
Además, para ahorrar espacio en el programa, [1] algunos programadores de BIOS y DOS usaban un truco , por ejemplo, para tener un segmento que tuviera acceso a los datos del programa (como de F800:0000 a F800:7FFF , apuntando a las direcciones físicas 0x000F8000–0x000FFFFF ), así como a los datos de E/S (como el búfer del teclado) que se encontraban en el primer segmento de memoria (con las direcciones F800:8000 a F800:FFFF apuntando a las direcciones físicas 0x00000000 a 0x00007FFF ).
Este truco funciona siempre que el código no se ejecute en memoria baja (los primeros 64 KB de RAM), una condición que siempre era cierta en versiones anteriores de DOS sin capacidades de alta carga.
Con el núcleo DOS reubicado en áreas de memoria más altas, la memoria baja se volvió cada vez más disponible para los programas, causando que aquellos que dependían del wraparound fallaran. [19] Los cargadores ejecutables en versiones más nuevas de DOS intentan detectar algunos tipos comunes de programas afectados y los parchean sobre la marcha para que funcionen también en memoria baja [20] o los cargan por encima de los primeros 64 KB antes de pasarles la ejecución. [20] Para los programas que no se detectan automáticamente, se puede usar LOADFIX [21] o MEMMAX -L [21] para forzar que los programas se carguen por encima de los primeros 64 KB.
El truco fue utilizado por el propio IBM/Microsoft Pascal , así como por programas compilados con él, [22] [23] [10] [17] incluyendo MASM de Microsoft . [17] Otras utilidades de desarrollo comúnmente utilizadas que usaban esto eran compresores ejecutables como Spacemaker de Realia [20] (escrito por Robert BK Dewar en 1982 y usado para comprimir versiones tempranas de Norton Utilities [24] [25] [26] [27] ) y EXEPACK de Microsoft [19] [20] [1] [28] [17] (escrito por Reuben Borman en 1985) así como la opción equivalente /E[XEPACK] en LINK 3.02 de Microsoft y superiores. [19] [1] [28] [26] Los programas procesados con EXEPACK mostrarían un mensaje de error "El archivo empaquetado está dañado". [1] [20] [28]
Existen varias utilidades de terceros para modificar ejecutables comprimidos , ya sea reemplazando las rutinas de descompresión problemáticas mediante un reensamblaje o intentando expandir y restaurar el archivo original.
Los cargadores de arranque BIOS heredados modernos (como GNU GRUB ) utilizan la línea A20. [3] Los cargadores de arranque UEFI utilizan el modo protegido de 32 bits o el modo largo de 64 bits .
SYS–0047. A20M# siempre se desactiva (se activa) en el procesador
[…] Este formato se proporciona para simplificar
la traducción de programas 8080/Z80 a código 8086
y no se recomienda para programas nuevos. […] Tamaño de la memoria. Es la cantidad de bytes disponibles en el segmento del programa. […]
(41 páginas)
[…] Algunos programas escritos para el 8086 dependen de [enrollado de dirección] para ejecutarse correctamente. Desafortunadamente, las ubicaciones de memoria se extienden por encima de 1 megabyte en el modo real del 80286 y no se envuelven en ubicaciones de memoria bajas. En consecuencia, los programas, incluidos los escritos en
MicroSoft PASCAL
y los programas que usan la función "Call 5" de MS-DOS, fallarán en el sistema 80286 estándar. […] Por ejemplo, no se cargan programas PASCAL en
memoria por debajo de 64K
, y se coloca una instrucción especial en las ubicaciones de memoria inferiores por encima de 1 megabyte, por ejemplo, la dirección 100000h o 100010h. […]
{{cite web}}
: CS1 maint: bot: estado de URL original desconocido ( enlace )[…] Para obtener acceso a
CP/M-86
[…] Para obtener acceso a CP/M-86 es necesario colocar el código de función en el registro CL, colocar el parámetro de byte en el registro DL o colocar el parámetro de palabra en el registro DX, colocar el segmento de datos en el registro DS (el segmento de datos no suele modificarse en el caso de un programa convertido) y ejecutar una interrupción de software,
INT #224
. El resultado se devuelve en el registro AL si es un valor de byte; si el resultado es un valor de palabra, se devuelve en los registros AX y BX. Los valores de doble palabra se devuelven con el desplazamiento en los registros BX y el segmento en el registro ES. Por lo tanto, la conversión de programas de
CP/M-80
a CP/M-86 requiere reemplazar la llamada a la ubicación 5 por la interrupción de software INT #224. Otro cambio necesario implica el
arranque en caliente
. En CP/M-80, se puede acceder al arranque en caliente mediante una llamada al sistema con un código de función de 0 para un salto a la ubicación 0. Sin embargo, CP/M-86 no admite el salto a la ubicación 0. Como resultado, debe cambiar esta salida de programa en el programa traducido para que el programa se ejecute correctamente. Siempre que la llamada a la ubicación 5 se reemplace con INT #224, que se realice el cambio de arranque en caliente y que los registros se asignen correctamente, no debería haber muchos problemas para que el programa traducido acceda a las funciones del sistema CP/M-86. […] Obtener acceso a
MS-DOS
[…] Aunque MS-DOS tiene un mecanismo "preferido" a través de una interrupción de software,
INT #33
, para acceder al sistema, se proporciona un mecanismo adicional para programas "preexistentes" que es compatible con las convenciones de llamada CP/M-80, al menos para funciones en el rango de 0 a 36. En lo que respecta a las llamadas al sistema dentro del rango de funciones permitido, el programador no tiene que hacer nada con los programas traducidos para que se ejecuten en MS-DOS, excepto asignar correctamente los registros. MS-DOS también admite la función de arranque en caliente de CP/M-80. Un salto a la posición 0 en MS-DOS ejecuta una interrupción de software,
INT #32
, que es funcionalmente un fin de programa y la forma normal de salir de un programa. […]
[2] [3][4][5][6][7][8][9][10][11][12][13][14][15] (13 páginas)
[…]
86-DOS
, y por lo tanto
PC DOS
/
MS-DOS
, usaron un truco inteligente. El byte en el desplazamiento 5 del
PSP
contenía un código de operación de llamada lejana (9Ah); la palabra en el desplazamiento 6 del PSP contenía el valor apropiado para indicar el tamaño del segmento del programa, y también la parte de desplazamiento de la llamada lejana. La palabra en el desplazamiento 8, que servía como parte del segmento de la llamada lejana, fue diseñada de tal manera que cuando se combinaba con el desplazamiento, se ajustaría (una característica bien entendida de la CPU
8086
) y apuntaría a la dirección 0:C0h, que contiene el vector de interrupción 30h. […] Un problema con la interfaz de compatibilidad ocurre cuando el programa cargado tiene de hecho menos de 64 KB disponibles. Si esto sucede, la palabra en el desplazamiento 6 de PSP puede no contener el valor correcto, pero la interfaz CALL 5 seguirá funcionando; la instrucción en el desplazamiento 5 será CALL 0:C0h, lo que hace que el tamaño del segmento de programa informado sea C0h. No está claro por qué DOS hace eso; parece ser un error en DOS 5.0 y versiones posteriores, ya que DOS 4.0 y versiones anteriores simplemente ajustan la porción del segmento para que se ajuste a 0:C0h. Eso funciona siempre que el tamaño del segmento de programa esté alineado con el párrafo, y lo estará. […]
[…] Mediante un proceso demasiado extraño y complicado de explicar, la dirección segmentada se establece de modo que sirva para dos propósitos. No solo apunta al despachador de funciones DOS, sino que la parte de desplazamiento también indica cuánto del segmento de código podemos usar (hasta el hexadecimal FFF0, 16 bytes menos de 64K). La parte de desplazamiento de la dirección, la parte que nos interesa, se encuentra en el desplazamiento 6 dentro del PSP, después del código de operación de la instrucción en el desplazamiento 5. El resultado de esto es que si DOS tiene menos de 64K para darles a nuestros programas, podemos usar este campo para saber cuántos bytes están disponibles, una técnica que debería funcionar con la mayoría o todos los sistemas de ventanas y multitarea. […](426 páginas)
[…] BIOSINIT.A86 1.40 93/11/11 12:25:29 […] Cambios en el encabezado
VDISK
[…] BIOSINIT.A86 1.39 93/11/08 23:19:22 […] SetupHMA realiza la inicialización de CALL5 […] ahora corrige JMPF en
alta memoria
para el enlace CALL5 para
PC-NFS
[…]
[16] (NB. MRS de OpenDOS 7.01 : IBMBIO\BIOSINIT.A86 SetupHMA)
[…] Dejar la línea A20 habilitada causa problemas con los programas que esperan que se produzca un efecto envolvente […] Uno de estos programas era la rutina de desempaquetado que
el propio enlazador de
Microsoft incluía originalmente con cualquier archivo que se hubiera
empaquetado con EXEPACK
para reducir su tamaño. Según Phillip Gardner, autor de la utilidad de mantenimiento shareware DOSMAX
UMB
y un veterano en el área de desensamblado de DOS, el famoso mensaje de error "Packed File Corrupt" que comenzó a aparecer en todas partes poco después de la introducción de DOS 5.0 se debe directamente al hecho de que la línea A20 está habilitada, y la rutina de desempaquetado original dependía del efecto envolvente de segmento para expandir correctamente los archivos comprimidos. […]
(xviii+856+vi páginas, disquete de 3,5" [17]) Erratas: [18][19] (NB: En la página 350, el libro tiene una descripción detallada del funcionamiento interno de la problemática rutina de descompresión EXEPACK).
[…]
DR Concurrent DOS 386
(desde 1988-07-08) cargará programas
EXEPACKED
por encima de la marca de 64K, es decir, fuera de la "
memoria más baja
", ampliando el bloque de memoria que contiene el entorno del programa […]
DR DOS 5.0
+ siempre carga programas en formato
.EXE
sin correcciones, y (desde 1990-05-25) también programas en formato
.COM
comprimidos con
SpaceMaker
- y por lo tanto comenzando con 9Ch 55h (PUSHF/PUSH BP) - por encima de la marca de 64K para evitar el error de envoltura de EXEPACK. Hace esto ampliando el bloque de memoria que contiene el entorno del programa, desde 1989-12-14 incluso asignará múltiples rellenos cuando sea necesario. Este código de expansión de entorno está deshabilitado si el nombre del programa padre tal como está almacenado en el MCB es "WIN" para mejorar el rendimiento cuando
WIN.COM
inicia KERNEL.EXE (0 elementos de reubicación). […] el núcleo
MS-DOS
/
PC DOS 5.0+
[…] busca una variedad de secuencias de código en ejecutables de formato .EXE y aplica parches para varias versiones de archivos EXEPACKED para permitirles ejecutarse en la memoria más baja (cuando DOS está en el
HMA
), es decir, un segmento de carga < 64 Kb. De lo contrario, mostrarían "Archivo empaquetado corrupto". El código verifica que el punto de entrada del código […] no sea < 0002h […] y luego lee la PALABRA que precede inmediatamente al punto de entrada […] Si esta PALABRA lee 5242h ("RB"), se supone que el archivo está EXEPACKED. Luego, el código busca una de varias combinaciones de secuencias de código en desplazamientos desde esta firma "RB". […] el núcleo MS-DOS 5.0+[…] busca una clase desconocida de
ejecutables
.COM
. Si se encuentran sus firmas en el archivo, la variable de cuenta regresiva A20 en el desplazamiento 18h en la tabla de información del búfer de disco (consulte la Tabla "Información del búfer de disco de DOS 5.0-6.0") se establecerá en 10, lo que hará que A20 se desactive después de las llamadas INT 21h para que siga este recuento de llamadas INT 21h. Es de suponer que esta clase de programas requiere que A20 se desactive durante algún tiempo después de que comience la ejecución. (Ocurren acciones similares al ingresar en INT 21h/AH=25h y AH=49h). […]
{{cite book}}
: |work=
ignorado ( ayuda ) (NB: el enlace proporcionado apunta a una versión convertida a HTML del NWDOSTIP.TXT
, que es parte de la MPDOSTIP.ZIP
colección). [20]…] DX es DS final (puede ser negativo) […] valor DS final (puede ser negativo) […]
[…]
SPACEMAKER
y TERMULATOR, software comercial para IBM PC (
utilidad de compresión de archivos
PC DOS y emulador
VT-100
), comercializado por Realia, Inc.
RBK Dewar
(1982-1983), lenguaje ensamblador 8088, 8.000 líneas […]
[…] La opción /E del enlazador debería generar un archivo EXE que sea lógicamente equivalente al archivo EXE sin comprimir. La versión actual […] hace que AX sea superado. AX al ingresar a un archivo EXE tiene un significado definido (indica la validez de la unidad para los parámetros), por lo tanto, debería pasarse a la imagen sin comprimir. Dada esta violación muy obvia de las reglas de la interfaz, puede haber otras, no me he molestado en investigar más […] Escribí el programa
Realia SpaceMaker
que hace algo similar a la opción
EXEPACK
(pero no hace falta decir que no tiene esta […]