Всем доброго дня!
Это моя первая тема на данном форуме. Не так давно я решил продолжить изучать работу процессора (хотя раньше я знал совсем не много). Читав статьи и книги, я подумал что пора от теории переходить к практике. Первым делом я написал загрузочный сектор, который позволял пользователю выбрать между продолжением загрузки операционной системы, либо искать загрузочный сектор с другого носителя. Пишу я всё на
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, перезагрузка компьютера. Мне кажется что случилось нарушение защиты процессора (системы) и он так отреагировал (хотя я думал что он должен был бы на нарушения просто остановиться).
Подскажите, что я сделал не так? Дайте советы по коду, оформлению.
Большое спасибо за любые советы и замечания!