linux kernel - Diferencia entre la dirección de memoria física/lógica/virtual
linux-kernel operating-system (9)
Dirección física: cuando el procesador está en modo de sistema, la dirección utilizada por el procesador es la dirección física.
No necesariamente cierto. Depende de la CPU en particular. En las CPU x86, una vez que haya habilitado la traducción de páginas, todo el código dejará de funcionar con direcciones físicas o trivialmente convertibles en direcciones físicas (excepto SMM, AFAIK, pero eso no es importante aquí).
Dirección lógica: cuando el procesador está en modo de usuario, la dirección utilizada es la dirección lógica. estos se asignan de todos modos a alguna dirección física agregando un registro base con el valor de compensación.
Las direcciones lógicas no se aplican necesariamente al modo de usuario exclusivamente. En las CPU x86 también existen en el modo kernel.
Me he topado con la discusión de que las direcciones virtuales y lógicas / espacio de direcciones son iguales. ¿Es verdad?
Depende de la CPU en particular. Las CPU x86 se pueden configurar de tal manera que los segmentos no se usen explícitamente. Se utilizan de forma implícita y sus bases siempre son 0 (excepto para segmentos de almacenamiento local de subprocesos). Lo que queda cuando se suelta el selector de segmento de una dirección lógica es un desplazamiento de 32 bits (o 64 bits) cuyo valor coincide con la dirección virtual de 32 bits (o 64 bits). En esta configuración simplificada, puede considerar que los dos son iguales o que las direcciones lógicas no existen. No es cierto, pero para los propósitos más prácticos, es lo suficientemente bueno como una aproximación.
Estoy un poco confundido acerca de los términos direcciones físicas / lógicas / virtuales en un sistema operativo (uso Linux-SUSE abierto)
Esto es lo que entiendo:
Dirección física: cuando el procesador está en modo de sistema, la dirección utilizada por el procesador es la dirección física.
Dirección lógica: cuando el procesador está en modo de usuario, la dirección utilizada es la dirección lógica. De todos modos, estos se asignan a alguna dirección física agregando un registro base con el valor de compensación. De alguna manera, proporciona una especie de protección de memoria.
Me he topado con la discusión de que las direcciones virtuales y lógicas / espacio de direcciones son iguales. ¿Es verdad?
Cualquier ayuda es muy apreciada.
Dirección física es la dirección que ve la unidad de memoria, es decir, una carga en el registro de direcciones de memoria. Dirección lógica es la dirección que genera la CPU. El programa del usuario nunca puede ver la dirección física real. La unidad de mapeo de memoria convierte la dirección lógica en dirección física. La dirección lógica generada por el proceso del usuario debe asignarse a la memoria física antes de ser utilizada.
En Usermode o UserSpace, todas las direcciones que ve el programa son direcciones virtuales. Cuando están en modo kernel, las direcciones que ve el kernel aún son virtuales pero se denominan lógicas ya que son iguales a las de conjunto de páginas + físicas. Las direcciones físicas son las que se ven en la memoria RAM. Con la memoria virtual cada dirección en el programa pasa por las tablas de páginas.
La memoria lógica es relativa al programa respectivo, es decir (punto de inicio del programa + desplazamiento)
La memoria virtual utiliza una tabla de páginas que se asigna a RAM y disco. De esta manera, cada proceso puede prometer más memoria para cada proceso individual.
Normalmente, cada dirección emitida (para la arquitectura x86) es una dirección lógica que se traduce a una dirección lineal a través de las tablas de segmentos. Después de la traducción en dirección lineal, se traduce a dirección física a través de la tabla de páginas.
Un buen artículo explicando lo mismo en profundidad:
http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation/
cuando escribes un programa pequeño, por ejemplo:
int a=10;
int main()
{
printf("%d",a);
}
compile: >gcc -c fname.c
>ls
fname.o //fname.o is generated
>readelf -a fname.o >readelf_obj.txt
/ readelf es un comando para comprender los archivos objeto y el archivo ejecutable que estará en 0s y 1s. la salida se escribe en el archivo readelf_onj.txt /
`>vim readelf_obj.txt`
/ * debajo de "encabezado de sección" verá las secciones .data .text .rodata de su archivo de objeto. cada inicio o la dirección base se inicia desde 0000 y crece hasta el tamaño respectivo hasta que alcanza el tamaño bajo el encabezado "tamaño" ----> estas son las direcciones lógicas. * /
>gcc fname.c
>ls
a.out //your executabe
>readelf -a a.out>readelf_exe.txt
>vim readelf_exe.txt
/ * aquí la dirección base de todas las secciones no es cero. Comenzará desde una dirección particular y terminará en la dirección particular. El enlazador dará las direcciones continuas a todas las secciones (observe en el archivo readelf_exe.txt. Observe la dirección base y el tamaño de cada sección. Comienzan continuamente) por lo que solo las direcciones base son diferentes .---> esto se llama virtual espacio de dirección.*/
Dirección física-> la memoria tendrá la dirección física. cuando su archivo ejecutable se cargue en la memoria tendrá una dirección física. En realidad, las direcciones virtuales se asignan a direcciones físicas para la ejecución.
Mi respuesta es cierta para las CPU de Intel que se ejecutan en un sistema Linux moderno, y estoy hablando de procesos a nivel de usuario, no de código de kernel. Aún así, creo que te dará una idea suficiente para pensar en las otras posibilidades.
Tipos de direcciones
Respecto a la pregunta 3:
Me he topado con la discusión de que las direcciones virtuales y lógicas / espacio de direcciones son iguales. ¿Es verdad?
Por lo que sé, son lo mismo, al menos en los sistemas operativos modernos que se ejecutan sobre los procesadores Intel.
Déjame intentar definir dos nociones antes de explicar más:
- Dirección física : la dirección donde se encuentra físicamente algo en el chip RAM.
- Dirección lógica / virtual : la dirección que utiliza su programa para alcanzar sus objetivos. Normalmente se convierte en una dirección física más tarde mediante un chip de hardware (en su mayoría, ni siquiera la CPU es consciente de esta conversión).
Dirección virtual / lógica
La dirección virtual es correcta, una dirección virtual, el sistema operativo junto con un circuito de hardware llamado MMU (Unidad de administración de memoria) evitan que su programa se ejecute solo en el sistema, tiene todo el espacio de direcciones (tener un sistema de 32 bits significa que El programa pensará que tiene 4 GB de RAM; más o menos hablando).
Obviamente, si tiene más de un programa ejecutándose en ese momento (siempre lo hace, GUI, proceso Init, Shell, aplicación de reloj, calendario, lo que sea), esto no funcionará.
Lo que sucederá es que el sistema operativo pondrá la mayor parte de la memoria de su programa en el disco duro, las partes que más utilice estarán presentes en la RAM, pero eso no significa que tengan la dirección que usted conoce.
Ejemplo: Su proceso puede tener una variable llamada (contador) que recibe la dirección virtual 0xff (imaginablemente ...) y otra variable llamada (a menudo sin uso) que recibe la dirección virtual (0xaa).
Si lees el ensamblaje de tu código compilado después de que haya ocurrido todo el enlace, los accederás usando esas direcciones, pero bueno, la variable (a menudo no utilizada) no estará realmente en la RAM en 0xaa, estará en el disco duro porque no lo estas usando
Además, la variable (contador) probablemente no estará físicamente en (0xff), estará en otro lugar en la RAM, cuando su CPU intente obtener lo que hay en 0xff, la MMU y una parte del sistema operativo, hará una asignación y obtenga esa variable desde donde está realmente disponible en la RAM, ni siquiera notará que no estaba en 0xff.
Ahora, ¿qué sucede si su programa solicita la variable (a menudo no utilizada)? El MMU + OS notará este "error" y lo buscará para usted desde el disco duro a la RAM y luego se lo entregará como si estuviera en la dirección (0xaa); esta recuperación significa que algunos datos que estaban presentes en la RAM se enviarán de vuelta al disco duro.
Ahora imagine que esto se ejecuta para cada proceso en su sistema. Todos piensan que tienen 4 GB de RAM, nadie lo tiene, pero todo funciona porque todos tienen algunas partes de su programa disponibles físicamente en la RAM, pero la mayoría del programa reside en el disco duro. No confunda esta parte de la memoria del programa que se coloca en HD con los datos del programa a los que puede acceder a través de las operaciones de archivos.
Resumen
Dirección virtual : la dirección que usa en sus programas, la dirección que usa su CPU para obtener datos, no es real y se traduce a través de MMU a alguna dirección física; todos tienen uno y su tamaño depende de su sistema (Linux que ejecuta 32 bits tiene un espacio de direcciones de 4GB)
Dirección física : la dirección que nunca alcanzará si está ejecutando en la parte superior de un sistema operativo. Es donde sus datos, independientemente de su dirección virtual, residen en la memoria RAM. Esto cambiará si sus datos se envían de ida y vuelta al disco duro para acomodar más espacio para otros procesos.
Todo lo que he mencionado anteriormente, aunque es una versión simplificada de todo el concepto, es lo que se llama la parte de administración de memoria del sistema informático.
Consecuencias de este sistema.
- Los procesos no pueden acceder a la memoria, cada uno tiene sus direcciones virtuales separadas y cada proceso recibe una traducción diferente a diferentes áreas, aunque a veces puede buscar y encontrar que dos procesos intentan acceder a la misma dirección virtual.
- Este sistema funciona bien como un sistema de almacenamiento en caché, por lo general, no usa los 4 GB completos que tiene disponibles, así que ¿por qué desperdiciarlo? que otros lo compartan y que también lo usen; cuando necesite más, obtendrá sus datos del HD y los reemplazará, a un costo del curso.
Direcciones virtuales de usuario Estas son las direcciones regulares que ven los programas de espacio de usuario. Las direcciones de usuario tienen una longitud de 32 o 64 bits, según la arquitectura de hardware subyacente, y cada proceso tiene su propio espacio de direcciones virtuales.
Direcciones físicas Las direcciones utilizadas entre el procesador y la memoria del sistema. Las direcciones físicas son cantidades de 32 o 64 bits; incluso los sistemas de 32 bits pueden usar direcciones físicas de 64 bits en algunas situaciones.
Direcciones de bus Las direcciones utilizadas entre buses periféricos y memoria. A menudo, son las mismas que las direcciones físicas utilizadas por el procesador, pero ese no es necesariamente el caso. Las direcciones de los autobuses son muy dependientes de la arquitectura, por supuesto.
Direcciones lógicas del núcleo Forman el espacio de direcciones normal del núcleo. Estas direcciones asignan la mayor parte o la totalidad de la memoria principal y, a menudo, se tratan como si fueran direcciones físicas. En la mayoría de las arquitecturas, las direcciones lógicas y sus direcciones físicas asociadas difieren solo por un desplazamiento constante. Las direcciones lógicas utilizan el tamaño del puntero nativo del hardware y, por lo tanto, es posible que no puedan abordar toda la memoria física en sistemas de 32 bits muy equipados. Las direcciones lógicas generalmente se almacenan en variables de tipo sin signo long o void *. La memoria devuelta desde kmalloc tiene una dirección lógica.
Direcciones virtuales del kernel Se diferencian de las direcciones lógicas en que no necesariamente tienen una asignación directa a direcciones físicas. Todas las direcciones lógicas son direcciones virtuales del núcleo; La memoria asignada por vmalloc también tiene una dirección virtual (pero no una asignación física directa). La función kmap devuelve direcciones virtuales. Las direcciones virtuales se almacenan generalmente en variables de puntero.
Si tiene una dirección lógica, la macro __pa () (definida en) devolverá su dirección física asociada. Las direcciones físicas se pueden volver a asignar a direcciones lógicas con __va (), pero solo para páginas con poca memoria.
Me refiero a la siguiente base de respuestas en Intel x86 CPU
Diferencia entre la dirección lógica a la virtual
Siempre que su programa esté en ejecución, la CPU genera una dirección lógica para las instrucciones que contiene (Selector de segmento de 16 bits y desplazamiento de 32 bits). Básicamente virtual (dirección lineal) se genera utilizando campos de dirección lógica.
El selector de segmento es un campo de 16 bits, de los cuales el primer 13bit es un índice (que es un puntero al descriptor de segmento que reside en GDT, descrito a continuación), campo TI de 1 bit (TI = 1, consulte LDT, TI = 0 Consulte GDT)
Ahora el Selector de Segmento O diga que el identificador de segmento se refiere a Segmento de Código O Segmento de Datos O Segmento de Apilamiento, etc. Linux contiene un GDT / LDT (Tabla de Descriptor Global / Local) que contiene un descriptor de 8 bytes de cada segmento y contiene la dirección base (virtual) del segmento.
Por lo tanto, para cada dirección lógica, la dirección virtual se calcula utilizando los pasos a continuación.
1) Examina el campo TI del selector de segmento para determinar qué tabla de descriptor almacena el descriptor de segmento. Este campo indica que el Descriptor está en el GDT (en cuyo caso la unidad de segmentación obtiene la dirección lineal básica del GDT del registro de gdtr) o en el LDT activo (en cuyo caso la unidad de segmentación obtiene la dirección lineal de esa base). LDT desde el registro ldtr).
2) Calcula la dirección del Descriptor de segmento en el campo de índice del Selector de segmento. El campo de índice se multiplica por 8 (el tamaño de un Descriptor de segmento), y el resultado se agrega al contenido del registro gdtr o ldtr.
3) Agrega el desplazamiento de la dirección lógica al campo Base del Descriptor de segmento, obteniendo así la dirección lineal (Virtual).
Ahora es el trabajo de la unidad de Pagging traducir la dirección física de la dirección virtual.
Consulte: Comprensión del núcleo de Linux, Capítulo 2 Direccionamiento de memoria