Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
td3:de0a3en64 [2012/07/05 21:50]
carloscuttitta
— (actual)
Línea 1: Línea 1:
-====== Cambiar de nivel cero a tres en IA-32e  ====== 
  
-===== Objeto del documento ===== 
- 
-Brindar recomendaciones para el pasaje de nivel de privilegio cero a tres en IA-32e. A partir del ejemplo de programa en IA-32e aportado por el Ing. Dario Alpern. 
- 
-===== Punto de partida ===== 
- 
-El programa long.asm (disponible haciendo click [[http://www.electron.frba.utn.edu.ar/~mdoallo/descargas/ej3.3-pag_ia32e.tar.gz|aquí]]) propone lo siguiente: \\ 
- 
-''; Hacer un programa que muestre la cantidad de decimas de segundo que estuvo \\ 
-; corriendo en modo largo (64 bits) y la cantidad de teclas presionadas. \\ 
-; Utilizar para ello las interrupciones en modo protegido 8 (reloj) y 9 (teclado). \\ 
-; El cuerpo principal de ejecución se detiene con hlt\\ 
-; \\ 
-; Hecho por Dario Alejandro Alpern el 11 de marzo de 2008. \\ 
-; \\ '' 
- 
-==== Que dice "info gdt" ==== 
- 
-  * Entrada nula 
-  * Segmento de código de 64 bits con DPL=0 
-  * Segmento de código de 32 bits con DPL=0 
-  * Segmento de datos de 32 bits 
- 
-==== Que dice "info idt" ==== 
- 
-  * Puerta de interrupción en 8 (cs_sel_64:int8han) con DPL=0 
-  * Puerta de interrupción en 9 (cs_sel_64:int9han) con DPL=0 
- 
-Con esto podemos deducir que el PIC no está siendo reubicado. 
- 
-==== Que dice "info tab" ==== 
- 
-''<bochs:4> info tab\\ 
-cr3: 0x00090000\\ 
-0x00000000-0x001fffff -> 0x00000000-0x001fffff\\ 
-<bochs:5> \\ 
-'' 
- 
-Esto nos dice que tenemos una página de dos MB con **identity mapping** 
- 
-===== ¿Cual es la idea? ===== 
- 
-La paginación permanece invariable.\\ 
-Utilizar "int 30h" para bajar el código de nivel cero a tres.\\ 
-Luego el timer tick se usa para actualizar pantalla ejecutando código de nivel 0 como antes.\\ 
-Lo mismo para el manejo del teclado.\\ 
-Probar "int 80h" para acceder a nivel cero desde el tres.\\ 
-Finalmente el programa para detenerse debe utilizar "jmp $" en vez de "halt" (Está claro que esto consume CPU, es sólo porque está en nivel tres).\\ 
- 
-===== Manos a la obra ===== 
- 
-  * En la GDT declaramos tres segmentos nuevos. Uno para código de 64 bits con DPL=0, otro de datos de 32 bits también con DPL=3 y otro para TSS (Task State Segment) también de 64 bits. 
-  * En la IDT agregamos una puerta de interrupción en 30h con DPL=0, que será para hacer el cambio de privilegio (de cero a tres). También agregamos otra puerta de interrupción en 80h, esta será para acceso a servicios del kernel por código que corre en nivel tres. 
-  * Dado que describimos una TSS en la GDT debemos reservar espacio en memoria a tal efecto. 
- 
-Esto se logra con: ''TSS: times tss64_struc_size               db  0  ''\\ 
- 
-La estructura de TSS de 64 bits está disponible mas abajo. 
- 
-  * Asegurarse que la página esté accesible a nivel USER. 
-  * Definir pila de nivel cero (porque no me gusta como está en long.asm) 
-''mov rsp,pila_0 \\ 
-mov ax,ds_sel \\ 
-mov ss,ax '' 
- 
-Donde pila_0 de define como:\\ 
-''align 256 \\ 
-times 256 db 0 \\ 
-pila_0:'' 
- 
-  * Definir pila de nivel tres. 
-  * Inicializar la base del descriptor de TSS en la GDT 
-''mov     eax,TSS \\ 
-mov     [TSS_sel+gdt+2],ax'' 
- 
-  * Guardar rsp de nivel 0 en la TSS 
-''mov     [TSS+4],rsp''\\ 
- 
-  * Cargar TSS en TR 
-''mov eax,TSS_sel\\ 
-ltr ax''\\ 
- 
-  * Invocar INT 30h para pasar de nivel cero a tres 
- 
-==== La magia está en int 30h ==== 
- 
-Al ejecutar la interrupción se guarda en la pila de nivel 0 lo siguiente: RIP, CS, RFLAGS, RSP y SS. \\ 
-La idea es alterar CS, RSP y SS de la pila. Para que luego al hacer IRETQ se cambie de nivel.\\ 
-''push rbp \\ 
-mov rbp,rsp \\ 
-push rax    ; para trabajar \\ 
-mov rax,cs_sel3_64 \\ 
-mov [rbp+16],rax \\ 
-mov rax,pila_3 \\ 
-mov [rbp+32],rax \\ 
-mov rax,ds_sel3 \\ 
-mov [rbp+40],rax \\ 
-pop rax \\ 
-pop rbp \\   
-iretq \\ 
-'' 
- 
-==== Estructura de TS de 64 bits ==== 
- 
-struc tss64_struc \\ 
-                       resd 1      ; Reservada \\ 
-        .reg_RSP0      resq 1 \\ 
-        .reg_RSP1      resq 1 \\ 
-        .reg_RSP2      resq 1 \\ 
-        resq 1      ; Reservada \\ 
-        .reg_IST1      resq 1 \\ 
-        .reg_IST2      resq 1 \\ 
-        .reg_IST3      resq 1 \\ 
-        .reg_IST4      resq 1 \\ 
-        .reg_IST5      resq 1 \\ 
-        .reg_IST6      resq 1 \\ 
-        .reg_IST7      resq 1 \\ 
-                       resd 1      ; Reservada \\ 
-                       resd 1      ; Reservada \\ 
-                       resw 1      ; Reservada \\ 
-        .reg_IOMAP     resw 1 \\ 
-endstruc \\ 
- 
- 
-===== Agradecimientos ===== 
- 
-A Dario Alpern por el aporte de long.asm. A Alejandro Furfaro por meternos en este baile. A Mariano Gonzalez y Juan Carlos Cuttitta que colaboran con ideas todo el tiempo. Al cuerpo docente de la cátedra de TDIII.\\ 
-Se aceptan críticas y comentarios.\\ 
- 
- --- //[[mdoallo@electron.frba.utn.edu.ar|Marcelo Doallo]] 2012/07/05 21:03//