saltos salto original linea data content assembly x86 bootloader gdt

assembly - original - saltos de linea en jquery



Salto lejano en gdt en el gestor de arranque (1)

x86 admite dos esquemas de memoria virtual ( lea sobre esto aquí ):

  • segmentación, debe, administrado usando la tabla de segmento, GDT.
  • paginación, opcional, administrado usando la tabla de páginas, PDT.

La mayoría de los sistemas operativos quieren usar paginación y no quieren la segmentación, pero no se puede y debe simplemente deshabilitar.

Entonces, el truco es deshabilitar su efecto ya que no estaba allí. Esto generalmente se puede hacer creando 4 descriptores de segmentos superpuestos grandes (al lado del segmento nulo):

  • índice de segmento 0: descriptor de segmento nulo
  • índice de segmento 1: descriptor de segmento de código para el modo privilegiado (kernel)
  • índice de segmento 2: descriptor de segmento de datos para el modo privilegiado (kernel)
  • índice de segmento 3: descriptor de segmento de código para el modo no privilegiado (usuario)
  • índice de segmento 4: descriptor de segmento de datos para el modo no privilegiado (usuario)

todos estos segmentos comienzan desde 0x00000000 hasta 0xffffffff , por lo que termina con segmentos grandes superpuestos que son código y datos privilegiados, y código y datos no privilegiados al mismo tiempo. Esto debería abrir la memoria virtual y desactivar el efecto de segmentación.

El procesador utiliza los selectores de segmento (registros de segmento cs , ds , ss ...) para encontrar el segmento correcto (una vez más, la segmentación es obligatoria).

Cada selector de segmento tiene un tamaño de 16 bits y tiene el siguiente diseño ( fuente ):

  • Los primeros dos bits indican que el nivel de privilegio, x86 admite 4 niveles, pero solo dos de ellos se usan realmente (el 00 más alto y el 11 más bajo).

  • El tercer bit indica que se debe usar la tabla, en su mayoría 0 , el GDT.

  • El resto de 13 bits indica el índice del segmento.

Si interpretó el 0x08 que está cargado en cs , será en binario:

0000000000001 0 00 index 1 (code) GDT privileged

y el 0x10 que está cargado en ds , ss , ...:

0000000000010 0 00 index 2 (data) GDT privileged

Si lee los selectores de segmento de cualquier programa de modo de usuario, debería ver que el valor de cs es 27 ( 0x1b ), lo que significa:

0000000000011 0 11 index 3 (code) GDT non-privileged

y los selectores de datos ds , ss , ..., deben almacenar 35 ( 0x23 ):

0000000000100 0 11 index 4 (data) GDT non-privileged

Los selectores de segmentos de datos (registros) se pueden modificar fácilmente usando instrucciones mov simples, pero los cs no se pueden usar con mov , por lo que se usa jmp 0x08:OFFSET para cargar las configuraciones de segmentos en el selector del segmento de códigos.

flush_gdt: lgdt [gdtr] jmp 0x08:complete_flush complete_flush: mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ret

No puedo entender lo que hace este código. flush_gdt es una etiqueta correcta, luego lgdt [gdtr] carga el puntero de 48-bit en el registro gdtr y luego de jmp 0x08:complet_flush .

¿Qué hace la instrucción jmp? y entonces ¿por qué estamos moviendo 0x10 a ax y luego a otros registros