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 el11
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