linux - kid3 - ¿Para qué se utiliza la memoria anterior a 0x08048000 en una máquina de 32 bits?
easytag (4)
En Linux, aprendí que cada proceso almacena datos a partir de 0x08048000 en una máquina de 32 bits (y 0x00400000 en una máquina de 64 bits).
Pero no sé la razón por la que a partir de ahí. ¿Para qué se utiliza la memoria anterior a 0x08048000 ?
Actualización : Algunas personas piensan que está mapeado para el kernel. Sin embargo, por lo que sé, el kernel de Linux utiliza la memoria de gama alta que comienza después de la pila del usuario.
El mapa de carga típico para x86 para una aplicación estática pequeña de 32 bits se ve así:
Address Contents
0x08048000 code
0x08052000 data
0x0805A000 bss (zero data)
0x08072000 end of data (brk marker)
0xBFFFE000 stack
Todo esto está en reversa: la pila está en la parte superior y se mueve hacia abajo mientras los datos se mueven hacia arriba. Supongo que la dirección antes de 0x08048000 está vinculada de forma estática a algo similar al MBR por sistema operativo.
La dirección de carga es arbitraria, pero se estandarizó con SYSV para x86. Es diferente para cada arquitectura. Lo que va por encima y por debajo también es arbitrario y, a menudo, está ocupado por las bibliotecas y las regiones mmap ().
La dirección de inicio para cargar el código ejecutable está determinada por los encabezados ELF para el ejecutable. Por ejemplo:
/bin/ls
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x08049bb0
No hay nada que impida que un ejecutable especifique una dirección de carga diferente; Por la razón que sea, la configuración predeterminada del enlazador lo puso allí. Se podría anular con un script de vinculador personalizado.
De forma predeterminada, en linux / x86, no verá direcciones bajas por debajo de 0x08000000
utilizadas por mucho; aunque el núcleo puede usarlo si se solicita en una llamada mmap
, o si se queda sin espacio para mmaps. Además, ha habido propuestas para usar direcciones en el rango 0x00000000 - 0x01000000
para las asignaciones de bibliotecas, para dificultar los desbordamientos de búfer (incrustando un byte NUL para terminar cadenas).
La respuesta es realmente: un montón de cosas. No hay un significado mágico para la dirección de carga del ejecutable y casi cualquier cosa puede asignarse a las direcciones inferiores. Ejemplos comunes que incluyen: la biblioteca C (como la biblioteca C), el cargador dinámico ld.so y el kernel VDSO (biblioteca de código dinámico asignada al kernel que proporciona parte de la interfaz al kernel en x86 Linux). Pero puede hacer prácticamente un mapa de lo que desee, utilizando la llamada al sistema mmap ().
Por ejemplo, en mi máquina específica, el mapa es el siguiente (adquirido pero "cat / proc / self / maps"):
gby@watson:~$ cat /proc/self/maps
001c0000-00317000 r-xp 00000000 08:01 245836 /lib/libc-2.12.1.so
00317000-00318000 ---p 00157000 08:01 245836 /lib/libc-2.12.1.so
00318000-0031a000 r--p 00157000 08:01 245836 /lib/libc-2.12.1.so
0031a000-0031b000 rw-p 00159000 08:01 245836 /lib/libc-2.12.1.so
0031b000-0031e000 rw-p 00000000 00:00 0
00376000-00377000 r-xp 00000000 00:00 0 [vdso]
00852000-0086e000 r-xp 00000000 08:01 245783 /lib/ld-2.12.1.so
0086e000-0086f000 r--p 0001b000 08:01 245783 /lib/ld-2.12.1.so
0086f000-00870000 rw-p 0001c000 08:01 245783 /lib/ld-2.12.1.so
08048000-08051000 r-xp 00000000 08:01 2244617 /bin/cat
08051000-08052000 r--p 00008000 08:01 2244617 /bin/cat
08052000-08053000 rw-p 00009000 08:01 2244617 /bin/cat
09ab5000-09ad6000 rw-p 00000000 00:00 0 [heap]
b7502000-b7702000 r--p 00000000 08:01 4456455 /usr/lib/locale/locale-archive
b7702000-b7703000 rw-p 00000000 00:00 0
b771b000-b771c000 r--p 002a1000 08:01 4456455 /usr/lib/locale/locale-archive
b771c000-b771e000 rw-p 00000000 00:00 0
bfbd9000-bfbfa000 rw-p 00000000 00:00 0 [stack]