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
00más alto y el11má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