Programación General > ASM (Ensamblador)

 Problemas Con El Salto A Modo Protegido

<< < (2/5) > >>

sharek:

--- Cita de: "sharek" --- Uso nasm para compilar... ¿pq demonios no entiende el jmp y me ensambla un jmp tan feo como "jmp far 1:0" ? es absurdo!
--- Fin de la cita ---
Mil perdones, dije compilar y es ensamblar

Eternal Idol:

--- Cita de: "sharek" --- Espera, que nos desviamos del tema, las interrupciones ya llegarán, he probado una cosa, he cogido la definicion de los segmentos de el post del Bootloader (por si mis definiciones eran incorrectas) y ahora me da un error bastante gracioso, adjunto código

Uso nasm para compilar... ¿pq demonios no entiende el jmp y me ensambla un jmp tan feo como "jmp far 1:0" ? es absurdo!
--- Fin de la cita ---
¿Nos desviamos del tema?

Creo los descriptores de segmento, tal y como indica la documentación de intel, 200mil webs y tres o cuatro libros, paso a modo protegido tal y como indica y hago el salto corto para "entrar" a un segmento válido y ete aqui el problema
siempre, SIEMPRE SIEMPRE, invariablemente, si habilito las interrupciones, "error de protección general"

¿Tienen que ver las interrupciones o no?


Seguramente tenes que hacer algo asi (pero no podemos saberlo sin tener la direccion de donde cargas tu codigo):

[bits 16]
  jmp 08h:01000h

PD. Ese salto que queres en 16 bits no se puede hacer y en 32 es lo que te muestra NASM (o fasm o cualquier ensamblador) jmp 0x1:0x0.

sharek:
Bien, entonces, avanzamos un poco mas, si lo hago 16 bit:

--- Código: Text ---   cli  lgdt  [selector_taula_descriptors]   mov  EAX, CR0  or  AL, 1  mov  CR0, EAX  jmp 08h:10000h  No me coge el desplazamiento, ya que supera los 16bit y salta a 08h:0 en vez de a 08h:10000h

Se que deben ser cosas básicas, pero no puedo con ellas...

sharek:
Superado el trauma, ahora solo tengo el problema que si habilito las interrupciones, rebienta todo..

Si no se crea una tabla de interrupciones válido, ¿peta por error de protección general?
no lo entiendo:

fijate:

--- Código: Text --- [BITS 32]inicio:  jmp  &#036;  
no genera ningún error (si activo el debug de bochs veo como va ejecutando el bucle infinito sin problema
en cambio:

--- Código: Text --- [BITS 32]inicio:  sti  jmp  &#036;  

me da como resultado:

--- Citar ---00002428246e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown
 status is 00h, resetting
00002428246i[SYS  ] bx_pc_system_c::Reset(SOFTWARE) called
00002428246i[APIC0] local apic in CPU 0 initializing
00002428246e[CPU0 ] CPU_LOOP bx_guard.interrupt_requested=1
Next at t=2428246
(0) [0x00010001] 0008:10001 (unk. ctxt): jmp .+0xfffffffe (0x00000001) ; ebfe

--- Fin de la cita ---


mis descriptores de segmento son los siguientes:

--- Código: Text --- taula_descriptors:  &#59; taula de descriptors de segments.nul:    &#59; Segment nul  dw  0  &#59; Limit L0-L15  dw  0  &#59; base B0-B15  db  0  &#59; base B16-B23  db  00000000b&#59; Drets d' accés  db  00000000b&#59; Granularitat/D/0/AV/Nibble Limit L16-L19  db  0  &#59; Base B24-B31.codi:    &#59; Segment de codi lectura/escriptura, no conformat  dw  0FFFFh  &#59; Limit L0-L15  dw  0  &#59; base B0-B15  db  0  &#59; base B16-B23  db  10011010b&#59; Drets d' accés  db  11001111b&#59; Granularitat/D/0/AV/Nibble Limit L16-L19  db  0  &#59; Base B24-B31.dades:    &#59; Segment de dades, lectura/escriptura, expansió cap avall  dw  0FFFFh  &#59; Limit L0-L15  dw  0  &#59; base B0-B15  db  0  &#59; base B16-B23  db  10010010b&#59; Drets d' accés  db  11001111b&#59; Granularitat/D/0/AV/Nibble Limit L16-L19  db  0  &#59; Base B24-B31.fi:  
estoy en el segmento 08h:10000h (como se aprecia en el error de bochs) y no tengo tabla de interrupcion creada

¿alguien sabe si es normal este error sin tabla? probé a crear una tabla pero creo que la documentación que consulté no era demasiado de fiar... obtenía el mismo error

Enko:

--- Citar ---a grandes rasgos... esa excepción solo debería suceder si el segmento no es válido y no creo que sea el caso... ¿alguien sabe si hay que hacer algún paso adicional salvo cargar (lgdt) la tabla de descriptores, crear una tabla de interrupciones (aunque creo que no es imprescindible) pasar a modo protegido, hacer un salto largo y tirar millas?

--- Fin de la cita ---
Yo tuve el mismo problema y no pasa porque la gtdr este mal sino la direccion a la que apunta el descriptor de la tabla general de descriptores de segmentos.

--- Código: Text --- global_descriptor_table:null_descriptor:  dw  0x0000, 0x0000, 0x0000, 0x0000system_code:  dw  0xFFFF, 0x0000, 0x9A00, 0x00CFsystem_data:  dw  0xFFFF, 0x0000, 0x9200, 0x00CFglobal_descriptor_end:gdtr:  dw  global_descriptor_end - global_descriptor_table -1  dd   null_descriptor  El problema que tuve fue con :

--- Citar ---dd null_descriptor

--- Fin de la cita ---
Al principio intentaba pasar a modo protegido una vez cargador el kernel, pero no se porque no logré hacer que funcionara en cuanto la direccion  estaba mal.
El kernel lo cargaba en la direccion fisica: 0x1000:0000  así que probe sumarle a null_descriptor  0x1000  que no funciono.

Lo solucioné pasando a modo protegido en el Bootloeader, tal vez algo poco recomendable pero así si me funcionó.

--- Código: Text --- ;protected mode switch      cli    lgdt  [gdtr]  mov  eax, cr0  or  al, 1  mov  cr0, eax    jmp  pword 0x8:0x10000  Si te sirve, puedes fijarte en el ejemplo que dejo>
http://foros.solocodigo.com/index.php?act=...=post&id=108861
Fijate en el archivo boot.asm.
ACLARACION IMPORTANTE> fijate que a la direccion de la tabla le sumo 0x7c00 es porque alli es donde es cargado el loeader por la bios y no uso org 0x7c00 sino un jmp a esa direccion. Esto porque al final hago > db   510 - $  dup 0
Si se usa org, hay que hacer 510 - $$-$ o lago parecido, como no sabia no lo hice asi.

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

[*] Página Anterior

Ir a la versión completa