Mecanismo de paginación de Linux iniciado (X86)

  
 

Habilitar el mecanismo de paginación Cuando Linux se inicia, primero se ejecuta en modo real y luego pasa al modo protegido. Debido a que en el mecanismo del segundo capítulo, hemos introducido la configuración de segmentación de Linux, aquí se analizan principalmente los problemas relacionados con el mecanismo de paginación. El punto de entrada al código del kernel de Linux es startup_32 en /arch/i386/kernel/head.S.

1. Inicialización inicial de la tabla de páginas:


/*

* Las tablas de páginas se inicializan en solo 8 MB aquí. La página final se encuentra en

*. Más tarde dependiendo del tamaño de la memoria.

* /

.org 0x2000

ENTRY (pg0)


.org 0x3000 < Br>

ENTRY (pg1)


/*

* empty_zero_page debe seguir inmediatamente las tablas de páginas! (El

* bucle de inicialización cuenta Hasta empty_zero_page)

* /


.org 0x4000

ENTRY (empty_zero_page)


/*

* Inicializar tablas de páginas

* /


movl $ pg0 -__ PAGE_OFFSET,% edi /* inicializar tablas de páginas * /

movl $ 007,% eax /* " 007 "no significa con derecho a matar, pero

PRESENTE + RW + USUARIO * /

2: stosl

Agregue $ 0x1000,% eax

cmp $ empty_zero_page -__ PAGE_OFFSET,% edi

jne 2b

Este código es ejecutado por el kernel porque el mecanismo de la página aún no se ha habilitado. No entró en el modo de protección, por lo que la dirección en el registro de instrucciones EIP sigue siendo la dirección física, pero debido a que pg0 almacena el terreno virtual (Piense en la dirección simbólica formada por gcc después de compilar el kernel es una dirección virtual), por lo tanto, "$ pg0 -__ PAGE_OFFSET", para obtener la dirección física de pg0, se puede ver que pg0 se almacena en el lugar con respecto al punto de inicio del código de kernel es 0x2000, es decir, la dirección física Es 0x00102000, y la dirección física de pg1 es 0x00103000. Las entradas en las dos tablas de páginas Pg0 y pg1 se configuran en 0x007, 0x1007, 0x2007, etc. Los tres bits más bajos son 1, lo que indica que las dos páginas son páginas de usuario, grabables, y el contenido de la página está en la memoria (consulte la Figura 2.24). La dirección base de la página física asignada es 0x0, 0x1000, 0x2000, etc., es decir, las páginas 0, 1, 2, 3, etc. en la memoria física, y un total de 2K páginas, es decir, se asignan 8 MB de espacio de almacenamiento. Se puede ver que el kernel de Linux tiene un requisito mínimo de memoria física de 8 MB. A continuación se almacena la página empty_zero_page (es decir, la página cero). La página cero almacena los parámetros de inicio del sistema y los parámetros de la línea de comandos. Para obtener más información, consulte el Capítulo 13.


2. Habilitar el mecanismo de paginación:


/*

* Esto se inicializa para crear un mapeo de identidad en 0-8M (para propósitos de inicio de

*) Y otra asignación del área 0-8M en la dirección virtual

* PAGE_OFFSET.

* /

.org 0x1000

ENTRY (swapper_pg_dir)

.long 0x00102007

.long 0x00103007

.fill BOOT_USER_PGD_PTRS-2,4,0

/* predeterminado: 766 entradas * /

.long 0x00102007

.long 0x00103007

/* predeterminado: 254 entradas * /

.fill BOOT_KERNEL_PGD_PTRS-2,4,0

/*


* Habilitar paginación

* /

3:

movl $ swapper_pg_dir -__ PAGE_OFFSET,% eax

movl% eax,% cr3 /* establece el puntero de la tabla de página .. * /

movl% cr0,% eax

orl $ 0x80000000,% eax

movl% Eax,% cr0 /* .. y configurar el bit de paginación (PG) * /

jmp 1f /* vaciar la cola de captura previa * /

1:

movl $ 1 f,% eax

jmp *% eax /* asegúrese de que eip se reubica * /

1:



we Veamos primero la función de este código. Este código es para cargar la dirección física del directorio de la página swapper_pg_dir en el registro de control cr3, y establecer la posición más alta en cr0 a 1, lo que abre el mecanismo de paginación.

Sin embargo, el mecanismo de paginación está habilitado, lo que no significa que el kernel de Linux realmente entre en el modo de protección, porque en este momento, la dirección en el registro de instrucciones EIP sigue siendo una dirección física, no una dirección virtual. " jmp 1f " La instrucción no dice nada lógicamente, pero funcionalmente actúa para descartar el contenido de la línea de instrucciones (esto lo sugiere Intel en la documentación técnica de i386) porque es un breve Salto, EIP sigue siendo una dirección física. Las siguientes instrucciones de movimiento y jmp cargan la segunda dirección, numerada con 1, en el registro EAX y saltan allí. Durante la ejecución de estas dos instrucciones, el EIP aún apunta a la dirección física < 1MB + en algún lugar ". Debido a que el compilador hace todas las direcciones de símbolos en el espacio de la memoria virtual, la dirección de la segunda etiqueta 1 está en algún lugar del espacio de la memoria virtual ((PAGE_OFFSET + en algún lugar), por lo que después de que se ejecute la instrucción jmp, el EIP apunta al virtual Una dirección en el espacio del kernel, que hace que la CPU entre en el espacio del kernel, completando así una transición sin problemas del modo real al modo protegido.

Luego mire el contenido del directorio de la página swapper_pg_dir. Se sabe que las direcciones físicas iniciales de las dos tablas de páginas pg0 y pg1 son 0x00102000 y 0x00103000 respectivamente. Como se puede ver en la Fig. 2? .22, los 12 bits más bajos de la entrada del directorio de la página se usan para describir los atributos de la tabla de la página. Por lo tanto, el primero en swapper_pg_dir 0 y la primera entrada de directorio 0x00102007, 0x00103007, significa que las dos tablas de páginas pg0 y pg1 son tablas de páginas de usuario, de escritura y el contenido de la tabla de páginas está en la memoria.

A continuación, coloque la segunda en swapper_pg_dir ~ 767 Un total de 766 entradas de directorio se establecen en 0. Debido a que el tamaño de una tabla de páginas es de 4 KB, cada entrada ocupa 4 bytes, es decir, cada tabla de páginas contiene 1024 entradas y cada página tiene también un tamaño de 4 KB. , por lo que estas 768 entradas de directorio están mapeadas El espacio virtual es 768? 1024? 4K = 3G, es decir, las primeras 768 entradas de directorio en el espacio de usuario del mapa de la tabla swapper_pg_dir.

Finalmente, pg0 y pp se almacenan en las entradas de directorio 768 y 769. Pg1 direcciones y atributos de las dos tablas de páginas, y establece 254 entradas de directorio de 770 a 1023 a 0. El espacio de direcciones virtuales asignado por las 256 entradas de directorio es 256? 1024? 4K = 1G, que es la tabla swapper_pg_dir. Las últimas 256 entradas de directorio se asignan al espacio del kernel.



Se puede ver que en el directorio de la página inicial swapper_pg_dir, tanto el espacio del usuario como el del kernel están disponibles. Solo las dos primeras entradas de directorio están asignadas, es decir, 8 MB de espacio, y tienen la misma asignación, como se muestra en la Figura 6.6.

Figura 6.6 Asignación de la página inicial del directorio swapper_pg_dir

Reader P: el kernel se ejecuta en el espacio del kernel después de que comience a ejecutarse. Entonces, ¿por qué el espacio bajo (8M) del espacio del usuario también se asigna, y la asignación al espacio bajo del espacio del kernel es la misma? En resumen, es del modo real al modo protegido. Transición suave. Específicamente, cuando la CPU ingresa al punto de inicio del código de kernel startup_32, En este caso, si el directorio de la página solo asigna el espacio del kernel y no asigna el espacio bajo del espacio del usuario, una vez que el mecanismo de asignación de la página esté habilitado, la ejecución no podrá continuar. Esto se debe a que la CPU en este momento El registro de instrucciones EIP en el centro aún apunta al área baja, y la dirección física buscará la instrucción hasta que se llame a la transferencia absoluta o la subrutina para una dirección de símbolo. Por lo tanto, el kernel de Linux ha adoptado la solución anterior.

Copyright © Conocimiento de Windows All Rights Reserved