OSDev http://osdev.su/ |
|
Не могу перейти в защищённый режим (рестарт компьютера) http://osdev.su/viewtopic.php?f=6&t=344 |
Страница 1 из 2 |
Автор: | s3dworld [ 23 окт 2010, 13:41 ] |
Заголовок сообщения: | Не могу перейти в защищённый режим (рестарт компьютера) |
Всем доброго дня! Это моя первая тема на данном форуме. Не так давно я решил продолжить изучать работу процессора (хотя раньше я знал совсем не много). Читав статьи и книги, я подумал что пора от теории переходить к практике. Первым делом я написал загрузочный сектор, который позволял пользователю выбрать между продолжением загрузки операционной системы, либо искать загрузочный сектор с другого носителя. Пишу я всё на FASM. Вот мой файл boot.asm: Код: ; ******************************************************************************* ; Имя: boot ; Описание: Загрузочный сектор ; Автор: Дубровкин Сергей ; Начало: 21.10.2010 - 17:54 ; Завершение: ??.??.???? - ??:?? ; ******************************************************************************* use16 org 0x7C00 ; ******************************************************************************* ; К О Д ; ******************************************************************************* boot__Code16: mov AX,CS mov DS,AX mov ES,AX mov FS,AX mov GS,AX mov AX,boot__Stack16 mov SS,AX mov AX,boot__StackStart16 mov SP,AX call Boot__SaveScreen call Boot__InitScreen mov BL,00000000b call Boot__ClearScreen mov SI,boot__TextTitle mov BL,00001111b mov DH,2 mov DL,32 call Boot__DrawText mov SI,boot__TextDescription mov BL,00001111b mov DH,3 mov DL,27 call Boot__DrawText mov SI,boot__TextKey1 mov BL,00001111b mov DH,10 mov DL,26 call Boot__DrawText mov SI,boot__TextKey2 mov BL,00001111b mov DH,12 mov DL,28 call Boot__DrawText mov SI,boot__TextAutors mov BL,00001111b mov DH,22 mov DL,20 call Boot__DrawText mov SI,boot__TextYear mov BL,00001111b mov DH,23 mov DL,36 call Boot__DrawText call Boot__KeyDown cmp AL,0x00 jz Boot__LabelEnd jmp Boot__LabelContinue Boot__LabelEnd: call Boot__LoadScreen int 0x18 Boot__LabelContinue: mov DH,0x00 mov DL,0x00 call Boot__SetCursorPos mov BL,00010000b call Boot__ClearScreen mov AX,CS mov ES,AX mov AH,0x02 ; Функция mov AL,0x02 ; Количество секторов mov CH,00000000b ; Номер цилиндра mov CL,00000010b ; Номер сектора mov DH,0x00 ; Номер головки mov DL,0x00 ; Номер дисковода mov BX,boot__End int 0x13 jmp boot__End ; ******************************************************************************* ; П Р О Ц Е Д У Р Ы ; ******************************************************************************* ; ------------------------------------------------------------------------------{ ; Название: BootKeyDown() ; Описание: Нажатие клавиши ; Вход: Нет ; Выход: AL - код ; ------------------------------------------------------------------------------- Boot__KeyDown: Boot__KeyDownRepeat: mov AH,0x00 int 0x16 cmp AH,0x01 jz Boot__KeyDownEscape cmp AH,0x1C jz Boot__KeyDownEnter jmp Boot__KeyDownRepeat Boot__KeyDownEscape: mov AL,0x00 jmp Boot__KeyDownEnd Boot__KeyDownEnter: mov AL,0x01 Boot__KeyDownEnd: ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootSaveScreen() ; Описание: Сохранение видео-режима ; Вход: Нет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__SaveScreen: mov AH,0x0F int 0x10 mov [boot__ScreenMode],AL mov [boot__Symbols],AH mov [boot__PageNumber],BH ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootLoadScreen() ; Описание: Загрузка видео-режима ; Вход: Нет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__LoadScreen: mov AH,0x00 mov AL,[boot__ScreenMode] int 0x10 mov AL,[boot__PageNumber] call Boot__SetScreenPage ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootInitScreen() ; Описание: Инициализация видео-режима ; Вход: Нет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__InitScreen: mov AH,0x00 mov AL,0x03 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootClearScreen() ; Описание: Очистка экрана ; Вход: BL - цвет ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__ClearScreen: mov AH,0x09 mov AL,' ' mov BH,0x00 mov CX,2000 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootSetScreenPage() ; Описание: Установка страницы ; Вход: AL - номер страница ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__SetScreenPage: mov AH,0x05 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootSetCursorPos() ; Описание: Установка положения курсора ; Вход: DH - номер строки ; DL - номер столбца ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__SetCursorPos: mov AH,0x02 mov BH,0x00 int 0x10 ret ; ------------------------------------------------------------------------------} ; ------------------------------------------------------------------------------{ ; Название: BootDrawText() ; Описание: Вывод текста ; Вход: BL - атрибуты текста ; DH - номер строки ; DL - номер столбца ; Выход: Нет ; ------------------------------------------------------------------------------- Boot__DrawText: mov CX,1 Boot__DrawTextLoop: call Boot__SetCursorPos mov AH,0x09 mov BH,0x00 lodsb cmp AL,0x00 jz Boot__DrawTextExit int 0x10 inc DL jmp Boot__DrawTextLoop Boot__DrawTextExit: ret ; ------------------------------------------------------------------------------} ; ******************************************************************************* ; Д А Н Н Ы Е ; ******************************************************************************* boot__Data16: boot__ScreenMode db 0x00 boot__Symbols db 0x00 boot__PageNumber db 0x00 boot__TextTitle db "Hello in BOS!",0x00 boot__TextDescription db "(Basic Operation System)",0x00 boot__TextKey1 db "Press 'Enter' for continue.",0x00 boot__TextKey2 db "Press 'Escape' for exit.",0x00 boot__TextAutors db "Dubrovkin Sergei & Konstantin Dement'ev",0x00 boot__TextYear db "(2010)",0x00 ; ******************************************************************************* ; С Т Е К ; ******************************************************************************* boot__Stack16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 boot__StackStart16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ; ******************************************************************************* ; Д О П О Л Н И Т Е Л Ь Н О ; ******************************************************************************* ; Заполнение до 510 байт rb 510-($-$$) ; Метка загрузочного сектора db 0x55,0xAA boot__End: include "translation_pmode.asm" ; Дубровкин Сергей © 2010 И есть у меня файл translation_pmode.asm где осуществляется переход в защищённый режим (P-Mode) работы процессора. Вот его код: Код: ; Имя: translation_pmode ; Описание: Перевод процессора в защищённый режим ; Автор: Дубровкин Сергей ; Начало: 23.10.2010 - 11:48 ; Завершение: ??.??.???? - ??:?? ; ******************************************************************************* use16 ; ******************************************************************************* ; К О Д ; ******************************************************************************* translation_pmode__Code16: cli in AL,0x92 or AL,2 out 0x92,AL lgdt [translation_pmode__GDTR] mov EAX,CR0 or AL,1 mov CR0,EAX jmp 0000000000001000b:translation_pmode__Code32 ; Index(13), TI(1), RPL(2) translation_pmode__Code32: use32 sti hlt ; ******************************************************************************* ; Д А Н Н Ы Е ; ******************************************************************************* translation_pmode__Data16: translation_pmode__GDTR: dw 8*5-1 dq translation_pmode__gdt translation_pmode__gdt: translation_pmode__descriptor0: db 00000000b ; Base Address(8) db 00000000b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 0000000000000000b ; Segment Limit(16) translation_pmode__descriptor1: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 10011000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__descriptor2: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 10010010b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__descriptor3: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 11111000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__descriptor4: db 00000000b ; Base Address(8) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 11110010b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; Base Address(8) dw 0000000000000000b ; Base Address(16) dw 1111111111111111b ; Segment Limit(16) translation_pmode__Data32: ; ******************************************************************************* ; С Т Е К ; ******************************************************************************* translation_pmode__Stack16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__Stack32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 rb (1024*1024*1)-1-($-$$) db 0x00 Всё это я потом тестирую в Bochs. Уж не знаю что я делаю не так, но у меня после нажатия на кнопку Enter должны загрузиться 1024 байта (2 сектора) и передаётся на них управление. После идёт подготовка глобальной таблицы дескрипторов (GDT) и загрузка её начала и размера в регистр GDTR (команда lgdt), и осуществляется дальний прыжок в сегмент 32-битного кода. Однако на практике у меня получается, после нажатия на кнопку Enter, перезагрузка компьютера. Мне кажется что случилось нарушение защиты процессора (системы) и он так отреагировал (хотя я думал что он должен был бы на нарушения просто остановиться). Подскажите, что я сделал не так? Дайте советы по коду, оформлению. Большое спасибо за любые советы и замечания! |
Автор: | KIV [ 23 окт 2010, 14:04 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
Может быть потому что у вас не настроена таблица прерываний? После перехода в PM таблица прерываний RM уже не подойдёт - надо свою делать. |
Автор: | SII [ 23 окт 2010, 17:00 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
Лень вникать, но ещё навскидку: надо TSS на всякий случай правильно заполнить (указать SS:ESP для 0-го кольца) и загрузить TR, а потом уже разрешать прерывания. Есно, и сами SS:ESP должны быть после перехода в защищённый режим правильно загружены. |
Автор: | s3dworld [ 23 окт 2010, 17:15 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
А без TSS вообще разве нельзя? |
Автор: | s3dworld [ 23 окт 2010, 17:25 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
KIV писал(а): Может быть потому что у вас не настроена таблица прерываний? После перехода в PM таблица прерываний RM уже не подойдёт - надо свою делать. Убрал sti и всё равно тоже самое. Что не так? |
Автор: | s3dworld [ 23 окт 2010, 18:55 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
Я вроде бы сегменты настроил: Код: mov AX,0000000000010000b
mov DS,AX mov ES,AX mov FS,AX mov GS,AX mov SS,AX mov EAX,translation_pmode__StackStart32 mov ESP,EAX |
Автор: | s3dworld [ 23 окт 2010, 19:00 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
Спасибо всем за помощь. Изменил описание дескрипторов (были наоборот поля описаны) и инициализировал сегменты с указателем стека. Теперь всё работает! Код: ; Имя: translation_pmode
; Описание: Перевод процессора в защищённый режим ; Автор: Дубровкин Сергей ; Начало: 23.10.2010 - 11:48 ; Завершение: ??.??.???? - ??:?? ; ******************************************************************************* use16 ; ******************************************************************************* ; К О Д ; ******************************************************************************* translation_pmode__Code16: cli in AL,0x92 or AL,2 out 0x92,AL lgdt [translation_pmode__GDTR] mov EAX,CR0 or AL,1 mov CR0,EAX jmp 0000000000001000b:translation_pmode__Code32 ; Index(13), TI(1), RPL(2) translation_pmode__Code32: use32 mov AX,0000000000010000b mov DS,AX mov ES,AX mov FS,AX mov GS,AX mov SS,AX mov EAX,translation_pmode__StackStart32 mov ESP,EAX hlt ; ******************************************************************************* ; Д А Н Н Ы Е ; ******************************************************************************* translation_pmode__Data16: translation_pmode__GDTR: dw 8*3-1 dq translation_pmode__gdt translation_pmode__gdt: translation_pmode__descriptor0: ;db 00000000b ; Base Address(8) ;db 00000000b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ;db 00000000b ; P(1), DPL(2), S(1), Type(4) ;db 00000000b ; Base Address(8) ;dw 0000000000000000b ; Base Address(16) ;dw 0000000000000000b ; Segment Limit(16) dw 0000000000000000b ; Segment Limit(16) dw 0000000000000000b ; Base Address(16) db 00000000b ; Base Address(8) db 00000000b ; P(1), DPL(2), S(1), Type(4) db 00000000b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; Base Address(8) translation_pmode__descriptor1: ;db 00000000b ; Base Address(8) ;db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ;db 10011000b ; P(1), DPL(2), S(1), Type(4) ;db 00000000b ; Base Address(8) ;dw 0000000000000000b ; Base Address(16) ;dw 1111111111111111b ; Segment Limit(16) dw 1111111111111111b ; Segment Limit(16) dw 0000000000000000b ; Base Address(16) db 00000000b ; Base Address(8) db 10011000b ; P(1), DPL(2), S(1), Type(4) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; Base Address(8) translation_pmode__descriptor2: ;db 00000000b ; Base Address(8) ;db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ;db 10010010b ; P(1), DPL(2), S(1), Type(4) ;db 00000000b ; Base Address(8) ;dw 0000000000000000b ; Base Address(16) ;dw 1111111111111111b ; Segment Limit(16) dw 1111111111111111b ; Segment Limit(16) dw 0000000000000000b ; Base Address(16) db 00000000b ; Base Address(8) db 10010010b ; P(1), DPL(2), S(1), Type(4) db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) db 00000000b ; Base Address(8) ;translation_pmode__descriptor3: ; db 00000000b ; Base Address(8) ; db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ; db 11111000b ; P(1), DPL(2), S(1), Type(4) ; db 00000000b ; Base Address(8) ; dw 0000000000000000b ; Base Address(16) ; dw 1111111111111111b ; Segment Limit(16) ;translation_pmode__descriptor4: ; db 00000000b ; Base Address(8) ; db 11001111b ; G(1), D(1), NULL(1), AVL(1), Segment Limit(4) ; db 11110010b ; P(1), DPL(2), S(1), Type(4) ; db 00000000b ; Base Address(8) ; dw 0000000000000000b ; Base Address(16) ; dw 1111111111111111b ; Segment Limit(16) translation_pmode__Data32: ; ******************************************************************************* ; С Т Е К ; ******************************************************************************* translation_pmode__Stack16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart16: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__Stack32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 translation_pmode__StackStart32: db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 rb (1024*1024*1)-1-($-$$) db 0x00 |
Автор: | SII [ 23 окт 2010, 19:34 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
s3dworld писал(а): А без TSS вообще разве нельзя? Нельзя. |
Автор: | s3dworld [ 24 окт 2010, 09:54 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
SII писал(а): s3dworld писал(а): А без TSS вообще разве нельзя? Нельзя. Так ведь я слышал что многозадачность многие реализовывают программно (не устраивают их аппаратные возможности многозадачности). А TSS - это разве не статус задачи? Тогда я не понимаю, зачем его использовать обязательно для не аппаратной многозадачности? |
Автор: | SII [ 24 окт 2010, 11:36 ] |
Заголовок сообщения: | Re: Не могу перейти в защищённый режим (рестарт компьютера) |
А это скажите спасибо архитекторам Intel, придумавшим всю эту дурость. TSS нужна даже в 64-разрядном режиме, где аппаратная многозадачность вообще упразднена. Можете для начала считать, что она требуется для хранения указателей стеков (точней, пар SS:ESP) для различных режимов работы процессора (на самом деле функций несколько больше, но в первом приближении это неважно, особенно если работа ведётся исключительно в нулевом кольце). Строго говоря, с точки зрения здравого смысла TSS не нужна до тех пор, пока программа пользуется только нулевым кольцом. Но я отнюдь не уверен, что всё пойдёт гладко при возникновении прерываний, даже если и прерываемая программа, и обработчик работают в нулевом кольце, а значит, аппаратное переключение стеков не выполняется: боюсь, что процессор всё равно будет по крайней мере проверять наличие TSS (правильное заполнение TR и наличие самой TSS в GDT), а при её отсутствии генерить GP. Так что делайте себе единственную TSS, заполните там необходимые поля, загрузите её адрес в TR и работайте дальше. Пы.Сы. И изучайте интеловские мануалы -- во всяких умных книжках есть далеко не всё, а разжёвывать Вам каждую мелочь на форумах не будут. Я английский выучил именно подобным образом, только документация была другой, поскольку "учу" его этим способом последние 20 лет. |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |