2011-06-03 23 views
5

Al inicializar el kernel, tengo algunas cosas que deben ocurrir: 1) paginación debe estar habilitado, 2) el administrador de memoria física tiene que analizar el mapa de memoria del prisionero, y 3) la puesta en marcha surtidos el código necesita acceder a los datos que deben permanecer allí para más adelante (por ejemplo, GDT, IDT, estructuras de administración de memoria).mitad superior del núcleo de inicialización

Las dependencias entre estos pasos me están volviendo loco. Con la mitad superior, el kernel está vinculado en su dirección virtual y las opciones que he encontrado son 1) habilitar la paginación en el ensamblaje, lo que implica seguir todos los punteros de arranque múltiple (en el ensamblaje) para que aún estén accesibles al administrador de la memoria física y luego desmarcarlos todos, 2) vincular el código de inicio en su dirección física y luego hacer alguna manipulación del puntero para acceder también a las estructuras del kernel en sus direcciones físicas, o 3) no usar una mitad superior núcleo.

Además, hay que precisar bootstrapping el administrador de memoria física sin conocer la cantidad de memoria física en tiempo de compilación. Estoy bastante seguro de que debo evitar cuidadosamente todas las estructuras de arranque múltiple al asignar las primeras estructuras, o usarlas todas primero y luego no preocuparme por sobrescribirlas (aunque todavía tendría que tratar con módulos y este enfoque probablemente implica copiar las tablas de arranque múltiple en una ubicación conocida, ya que las necesito al configurar el administrador de memoria física).

Estos problemas son por eso he evitado una mitad superior del núcleo hasta ahora. ¿Alguien tiene un buen sistema para resolver estas dependencias? ¿Tal vez alguna variación en this GDT trick para acceder tanto al kernel en su dirección vinculada/virtual como a las tablas de arranque múltiple en su dirección física, o usando algún tipo de tablas de página predefinidas que eviten los problemas anteriores, tal vez con PSE?

Respuesta

4

Así es como me abordado este problema:

imagen Mi núcleo se carga por GRUB (física) 0x01000000 dirección (16 MB, justo por encima de la región de ISA DMA). Esta imagen básicamente consta de dos partes:

  1. Una sección "init inicial". Esta sección contiene código que se ejecuta para prepararse para saltar al medio kernel superior. También reservo algo de espacio en esta sección para una pila y un montón usado durante esta preparación. Todo el código de esta sección está vinculado a la dirección (virtual) 0x01000000.
  2. El resto de la imagen contiene código y datos que forman parte de la mitad superior del kernel. Todo el código de esta parte está vinculado a la dirección (virtual) 0xc0000000 (3GB).

Dado que el código en la sección init inicial está vinculado en la misma dirección donde está cargado, GRUB puede saltar a este código sin ningún problema. Este código init inicial realiza los siguientes pasos:

  1. Reubique la estructura MBI que GRUB pasa al kernel. El montón dentro de la sección init inicial se usa para esto.
  2. Identity map todas las páginas que comienzan en la dirección física 0x0 hasta la dirección física de la última página utilizada por la sección init inicial. El mapeo de identidad significa que las direcciones virtuales son las mismas que las direcciones físicas. Esto asegura que el código en la sección init inicial aún se puede ejecutar después de que la paginación esté habilitada.
  3. Identifica la mitad del kernel superior en la dirección virtual 0xc0000000.
  4. Habilite la búsqueda.
  5. Salta a la mitad superior del kernel.

En este punto, el resto de la inicialización se realiza desde el medio código superior. Esto incluye la configuración de GDT, IDT, administración de memoria, ... Tenga en cuenta que el MBI se traslada a una ubicación conocida, por lo que no debe preocuparse de sobrescribirlo con sus propias estructuras de datos.

Una pequeña palabra sobre el administrador de memoria física: Lo que hago es calcular la cantidad de páginas necesarias para mis estructuras de datos, asignar estas estructuras comenzando en la primera página después de la imagen del kernel y comenzar a tratar páginas comenzando después de estas estructuras de datos.

Espero que esta explicación sea clara. Si no es así, házmelo saber. También podría proporcionarle una copia de mi kernel si así lo desea.

+0

¡Gracias! Una pregunta: el montón de inicialización (supongo) contiene el MBI reubicado, que puede descartarse cuando haya terminado con él, pero parece que también contiene las tablas de página para la asignación inicial. ¿Desechas también esos una vez que creas tu primer proceso? – rpjohnst

+0

@Rusky: Sí, el MBI podría descartarse pero no lo hago porque es muy pequeño. No coloco el directorio de página y las tablas de página en ese montón, pero en algún lugar con muy poca memoria (alrededor de 4 KB). No los descarto porque el primer proceso que ejecuto los heredará. Es decir. mi primer proceso se ejecutará en el espacio de direcciones que configuré durante la inicialización. – Job

Cuestiones relacionadas