2011-03-06 21 views
24

Tengo dificultades para entender cómo funciona un gestor de arranque simple. El gestor de arranque del que estoy hablando es el del curso de MIT "Ingeniería de sistemas operativos".gestor de arranque - conmutando el procesador al modo protegido

En primer lugar, permítame mostrarle un pedazo de código ensamblador el BIOS ejecuta:

[f000:fec3] 0xffec3: lidtw %cs:0x7908 
[f000:fec9] 0xffec9: lgdtw %cs:0x7948 
[f000:fecf] 0xffecf: mov %cr0,%eax 
[f000:fed2] 0xffed2: or  $0x1,%eax 
[f000:fed6] 0xffed6: mov %eax,%cr0 
[f000:fed9] 0xffed9: ljmpl $0x8,$0xffee1 

Desde el aspecto de la misma, este código configura la tabla de interrupciones y de la tabla de descriptores y luego se activa el modo protegido .

  1. ¿Por qué entramos en el modo protegido en el BIOS? En caso de que no la gestor de arranque se ejecute en modo real (por cierto - ¿Por qué necesita para funcionar en modo real ?)
  2. he buscado, pero no encontró ninguna parte exactamente cómo la instrucción ljmpl obras, y es la diferencia entre y ljmp y jmp regular - I agradecería si alguien fuera apunta en la dirección correcta.
  3. ¿Por qué realizamos el salto? ¿Cuál es el propósito de esta instrucción?

Pasando al código del gestor de arranque -

# Switch from real to protected mode, using a bootstrap GDT 
# and segment translation that makes virtual addresses 
# identical to their physical addresses, so that the 
# effective memory map does not change during the switch. 
lgdt gdtdesc 
movl %cr0, %eax 
orl  $CR0_PE_ON, %eax 
movl %eax, %cr0 

# Jump to next instruction, but in 32-bit code segment. 
# Switches processor into 32-bit mode. 
ljmp $PROT_MODE_CSEG, $protcseg 
  1. Se dice que el procesador está en el modo real - pero sólo vio que el interruptores de BIOS al modo protegido ... Estoy confundido, ¿cómo puede ser ?
  2. ¿Cómo cambiamos al modo de 32 bits? ¿Qué hace que el procesador vaya mágicamente a en modo de 32 bits debido a la instrucción ljmp ?

Y otra cosa que no entiendo - cuando el seguimiento de la ejecución del gestor de arranque con gdb veo que se ejecuta la siguiente instrucción (que es la instrucción LJMP a partir del código del gestor de arranque):

ljmp $0x8,$0x7c32 

Pero cuando miré en el archivo asm vi lo siguiente:

ljmp $0xb866,$0x87c32 

totalmente perdido aquí - ¿Cómo es que la instrucción escrito en el archivo asm y la instrucción ejecutada son diferentes? Tengo la corazonada de que esto tiene que ver con el modo protegido y la forma en que traduce las direcciones, pero realmente no lo entiendo.

¡Agradecería cualquier ayuda!

+0

Votación para cerrar como demasiado amplia: demasiadas preguntas en una. –

Respuesta

24
  1. Algunas implementaciones de BIOS pasan al modo protegido antes de ingresar al gestor de arranque. La mayoría no. Es posible que el BIOS cambie al modo protegido durante un breve período y vuelva a conectarse antes de ir al gestor de arranque, lo que le permitiría utilizar algunos de los beneficios del modo protegido (como 32 bits es el tamaño predeterminado de la dirección). La razón por la que el gestor de arranque debería estar en modo real es que la mayoría de las funciones del BIOS solo funcionan en modo real, por lo que debe estar en modo real para usarlas.

  2. ljmp especifica un segmento de código para cambiar además de la dirección a la que desea ir. Son tan similares que (al menos en GAS) el ensamblador cambiará un jmp con 2 operandos a un ljmp por usted.

  3. ljmp es una de las únicas formas de cambiar el registro cs. Esto debe hacerse para activar el modo protegido, ya que el registro cs debe contener el selector para un segmento de código en el GDT. (En caso de que quiera saber, las otras formas de cambiar cs son llamadas lejanas, retorno lejano e interrupción de retorno)

  4. Consulte el elemento 1. O el BIOS volvió al modo real, o este gestor de arranque no funcionará con este BIOS

  5. Véase el punto 3. Cambia cs para especificar un segmento de código de 32 bits, por lo que el procesador entra en modo de 32 bits.

  6. Cuando miró el archivo .asm, la instrucción se interpretó como si el tamaño de la dirección fuera de 32 bits, pero GDB lo interpretó como si el tamaño de la dirección fuera de 16 bits. Los datos en la dirección de la instrucción serían 0xEA 32 7C 08 00 66 B8. EA es el código de operación de salto largo. En un espacio de direcciones de 32 bits, la dirección se especificará utilizando los siguientes cuatro bytes, para una dirección de 0x87C32, pero en un espacio de direcciones de 16 bits, solo se utilizan 2 bytes, para una dirección de 0x7C32. Los 2 bytes posteriores a la dirección especifican el segmento de código solicitado, que sería 0xB866 en el modo de 32 bits y 0x0008 en el modo de 16 bits. El 0x66 B8 es el comienzo de la siguiente instrucción, que está moviendo un valor inmediato de 16 bits en el registro de hacha, probablemente para configurar los segmentos de datos para el modo protegido.

+3

Impresionante - realmente me aclaraste las cosas, ¡gracias! – s0li

2

¿Por qué entramos en modo protegido en el BIOS? El gestor de arranque no debería ejecutarse en modo real (por cierto, ¿por qué necesita ejecutarse en modo real?)

El modo protegido simplemente ofrece mucha más característica que el modo real: esencialmente el mecanismo de privilegio de anillo de protección de la CPU Intel (http: // en.wikipedia.org/wiki/Ring_(computer_security), ejecución en modo de 32 bits, etc.

Busqué pero no encontré en ninguna parte exactamente cómo funciona la instrucción ljmpl, y es la diferencia entre él y ljmp y jmp regular - Le agradecería si alguien podría apuntar en la dirección correcta

ljmpl y LJMP es lo mismo contexto aquí

.. 210

¿Por qué realizamos el salto? ¿Cuál es el propósito de esta instrucción?

Esto es necesario ya documentado en el manual de Intel, y documentado inline en el código que se muestra a continuación, así ..

Para la transición a-real-protegida, que se implementa en el gestor de arranque stage2 aquí:

http://src.illumos.org/source/xref/illumos-gate/usr/src/grub/grub-0.97/stage2/asm.S#real_to_prot

974 /* load the GDT register */ 
975 DATA32 ADDR32 lgdt gdtdesc 
976 
977 /* turn on protected mode */ 
978 movl %cr0, %eax 
979 orl $CR0_PE_ON, %eax 
980 movl %eax, %cr0 
981 
982 /* jump to relocation, flush prefetch queue, and reload %cs */ 
983 DATA32 ljmp $PROT_MODE_CSEG, $protcseg 
984 

Como u puede ver, cada parte del código tiene una función, y LJMP es esencialmente para eliminar o En la cola de captación previa, como se requiere en el manual de Intel, no recuerdo dónde.

Cuestiones relacionadas