Проблема с защищенным режимом

Тема в разделе "WASM.BEGINNERS", создана пользователем newty, 10 июн 2008.

  1. newty

    newty New Member

    Публикаций:
    0
    Регистрация:
    10 июн 2008
    Сообщения:
    10
    Доброго времени суток
    Недавно начал разбираться с protected mode и столкнулся с проблемой: код, приведенный ниже (небольшая модификация из статьи тов. Great'а о прерываниях в PM) не работает на реальной машине (после загрузки идет перезагрузка, и все по новой), причем под Bochs запускается отлично.
    Если же убрать 2 строки с очисткой экрана (mov ax, 0x3, int 0x10), все работает.. Подскажите, из-за чего это происходит?
    Код (Text):
    1. org 0x7c00
    2. use16
    3. startsect:
    4.  
    5. jmp rm_entry
    6.  
    7. ;Kernel's descriptor table
    8. GDT:
    9.   dd 0x00000000, 0x00000000 ;Zeroed descriptor
    10.   db 0xff, 0xff, 0x00, 0x00, 0x00, 10011010b, 11001111b, 0x00   ;Kernel code segment
    11.   db 0xff, 0xff, 0x00, 0x00, 0x00, 10010010b, 11001111b, 0x00   ;Kernel data segment
    12.  
    13. gdtsize equ $-GDT
    14.  
    15. gdtlimit dw gdtsize-1
    16. gdtbase dd GDT
    17.  
    18.  
    19. ;Kernel's interrupt descriptor table
    20.  
    21.  
    22. rm_entry:
    23.         mov ax, cs
    24.         mov ss, ax
    25.         mov dx, ax
    26.         mov es, ax
    27.         mov sp, startsect
    28.         mov bp, sp
    29.     mov  ax,3
    30.     int  10h
    31.  
    32. ;Loading the rest of sectors
    33.         mov ax, 0x0000
    34.         mov es, ax
    35.         mov bx, continue_rmode
    36.         mov ax, 0x0210 ;read 10h sectors
    37.         mov cx, 0x0002 ;start from zero track, 2nd sector
    38.         mov dx, 0x0000 ;0 head, 0 drive
    39.         int 0x13
    40.         jnc continue_rmode
    41. endsect:
    42.   rb 510-(endsect-startsect)
    43.   db 0x55, 0xAA
    44.  
    45. continue_rmode:
    46.         in al, 0x92
    47.         or al, 2
    48.         out 0x92, al
    49.  
    50.         cli
    51.         in al, 0x70
    52.         or al, 0x80
    53.         out 0x70, al    ;NMI denial
    54.  
    55.         lgdt fword [gdtlimit]
    56.  
    57.         mov eax, cr0
    58.         or eax, 1
    59.         mov cr0, eax
    60.  
    61.  
    62.         jmp 1000b:pm_entry
    63.  
    64. use32
    65. pm_entry:
    66.      jmp $
    P.S. Возможно проблема со стеком, который затирает таблицу GDT? Я пробовал переместить две строки с очисткой перед инициализацией сегментных регистров (как в статье и было), но результат тот же
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Стек не может затирать GDT, он растет вниз.
    Насчет примера из моей статьи: я, кажется, что-то менял, чтобы код заработал на реальной машине. Уж не помню сейчас что.
    Трезвым беглым взглядом на твой (мой?) код ошибок явных не нашел.. Могу лишь посоветовать настроить IDT и ловить код исключения (перезагрузка идет из-за того, что по определенной причине, которую и надо установить, происходит исключение, таблицы прерываний нет -> генерируется double fault -> его обработчика тоже нет - возникает тройной отказ, процессор уходит в shutdown, дальше чипсет видит, что дело плохо и перезагружает систему).
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    быть может,
    ?
    у тебя ds неверно инициализирован походу дела -> lgdt fword ptr ds:[gdtlimit] загружает совсем не ту таблицу, которая у тебя -> переход в защищенный режим ничем хорошим не закончится. опечатка, я так понимаю, но весьма суровая)
     
  4. newty

    newty New Member

    Публикаций:
    0
    Регистрация:
    10 июн 2008
    Сообщения:
    10
    Да, она и была проблемой. Спасибо за подробное объяснение

    P.S. код из статьи работает на реальной машине
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Пожалуйста.

    Оу.. значит, перепутал с чем-то другим.