OSDev

для всех
Текущее время: 28 апр 2024, 13:28

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 11 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: переход в PM
СообщениеДобавлено: 23 май 2013, 21:27 

Зарегистрирован: 25 фев 2013, 22:01
Сообщения: 63
имеется загрузчик, полностью рабочий
Код:
use16
org 7C00h
start:
   cli
   xor ax, ax   ;настройка сегментных регистров
   mov ds, ax
   mov es, ax
   mov ss, ax
   mov [device], dl
   mov sp, 7C00h   ;установка sp на начало кода (т.к. стек растет вниз, код не затрется)
   mov ax, 0B800h
   mov fs, ax   ;fs направим на область текстовой видео-памяти
   sti

   mov ax, 3
   int 10h    ;установка видеомоды + очистка экрана
   mov ah, 1
   mov ch, 20h
   int 10h
   call MenuItem1     ;рисуем меню
GetKey:
   xor ax, ax
   int 16h     ; ждем нажатие клавиши
   cmp al, 0Dh
   je option        ;если Enter, то выбираем с чего грузить
   cmp ah, 48h     ;вверх
   je up
   cmp ah, 50h   ;вниз
   je down
   jmp short GetKey
option:
   cmp [MenuItem], 0   ;первый пункт меню, грузим с диска С:\
   jne StartOS
   mov si, load_C       ;перемещаем кусок кода на адрес 8000h
   mov di, 8000h
   mov cx, end_C-load_C
   cld
   rep movsb
   jmp 8000h
up:
   cmp [MenuItem], 0    ;перерисовываем пункты
   je GetKey
   call MenuItem1
   jmp short GetKey
down:
   cmp [MenuItem], 1
   je  GetKey
   call MenuItem2
   jmp short GetKey
MenuItem1:
   mov [MenuItem], 0     ;первый пункт активен (белый текст красный фон)
   xor dx, dx
   mov cx, 18
   mov bx, 4Fh
   mov bp, load1
   mov ax, 1301h
   int 10h
   mov bp, load2
   mov cx, 23
   mov dx, 0100h         ;второй не активен    (белый по черному)
   mov bx, 0fh
   int 10h
   ret
MenuItem2:
   mov [MenuItem], 1     ;первый не активен
   xor dx, dx
   mov cx, 18
   mov bx, 0Fh
   mov bp, load1
   mov ax, 1301h
   int 10h
   mov bp, load2       ;второй активен
   mov cx, 23
   mov dx, 0100h
   mov bx, 4fh
   int 10h
   ret

load_C:
   mov ax, 3       ;очистка экрана
   int 10h
   mov ax, 0201h
   mov dx, 80h
   mov cx, 1
   mov bx, 7c00h
   int 13h        ;грузим MBR в адрес 7C00h
   push es
   push 7C00h
   retf          ;и передаем ему бразды правления
end_C:
   

StartOS:
   mov ax, 3         ;очистка экрана
   int 10h
   pushd 16   ;сектор который нужно прочитать
   push  0F00h    ;сегмент в который будет произведено чтение
   call ReadSector     ;читаем первичный сектор
   mov eax, [0F000h+0A6h]    ;сохраним размер корневого каталога
   mov [RootSize], eax

   pushd [RootSize]
   pushd [0f000h+158]
   push 0F00h
   call ReadFile        ;читаем корневой каталог
   mov di, file1
   xor ax, ax

SearchFile:
   mov si, 0F000h       ;адрес где лежит корневой каталог
   cmp byte [di], 0    ;если все файлы загружены
   je exit        ;то грузим ядро
   call WriteLoadFile    ;иначе выводим имя файла, которое собрались загружать
@@:
   xor cx, cx
   cmp byte [si], 0    ;если больше нет записей в каталоге
   je FileNotFound     ;то файл не найден
   mov cl, [si+32]     ;длинна имени файла в каталоге
   cmp cl, byte [di]    ;сравниваем с длинной
   jne FindNext       ;если не равны, то берем следующую запись каталога
   push di        ;сохраним начало записи и файловой структуры
   push si
   add di, 3       ;настроим si и di на первые байты имени файла
   add si, 33
   rep cmpsb       ;сравнение
   pop si          ;восстановим si di
   pop di
   jne FindNext      ;если не тот файл, то ищем дальше
   pushd [si+10]         ;размер файла
   pushd [si+2]      ;адрес экстента
   mov bx, [di+1]
   push word [di+1]   ;сегмент в который нужно читать файл
   call ReadFile
   call OK        ;выводим сообщение об успешной загрузке файла
   mov al, [di]
   xor ah, ah      ;следующая файловая структура
   add di, ax
   add di, 4

   ;xor ax, ax
   ;int 16h
   ;push word [di+1]         ;сегмент
   ;call debug
   jmp short SearchFile
FindNext:
   mov al, [si]       ;длинная текущей записи
   xor ah, ah
   add si, ax      ;следующая запись в каталоге
   jmp short @b
FileNotFound:
   push 0400h
   push 12
   push [x]
   push error
   call WriteString   ;вывод сообщения что файл не найден
exit:
   push [kernel_seg]
   push 0
   retf
OK:
   push 0E00h
   push 12
   push [x]
   push ok
   call WriteString
   inc [x]
   ret


ReadFile:
   push bp
   mov bp, sp
   mov ecx, [bp+10]   ;размер корневого каталога
   add ecx, 7FFh      ;непонятные мне махинации
   shr ecx, 11

   mov dx, [bp+4]      ;сегмент
   mov eax, [bp+6]     ;начальный сектор
.NextSector:
   push eax
   push dx
   call ReadSector
   add dx, 80h
   loop .NextSector
   mov sp, bp
   pop bp
   ret 6

ReadSector:
   push bp
   mov bp, sp
   push ax dx si
   mov ax, [bp+4]      ;формируем пакет для EDD
   mov [DataSeg], ax  ;сегмент
   mov eax, [bp+6]
   mov [LBAlow], eax  ;сетора в формате LBA

   mov ah, 42h
   mov si, Packet     ;адрес пакета
   mov dl, [device]  ;номер привода с которого грузится загрузчик
   int 13h
   jc .error     ;если произошла ошибка то скажем об этом и зависнем

   pop si dx ax
   mov sp, bp
   pop bp
   ret 6
.error:
   push 0fh
   push 0
   push 0
   push ErrorMsg
   call WriteString
   jmp $

WriteLoadFile:
   push di
   add di, 3
   push 0a00h
   push 0
   push [x]
   push di
   call WriteString          ;вывод имени загружаемого файла
   pop di
   ret

WriteString:
   push bp
   mov bp, sp
   pusha

   mov ax, [bp+6]       ;строка
   mov bx, 160
   mul bx
   mov di, ax
   mov ax, [bp+8]
   shl ax, 1       ;колонка
   add di, ax
   mov si, [bp+4]       ;адрес строки
   push es
   push fs             
   pop es               ;es на сегмент видео-памяти                                 ;будем писать в самое начало
   mov ax, [bp+10]              ;аттрибуты символов
@@:
   lodsb
   or al, al            ;пока не встретим нуль
   je @f
   stosw               ;пишем символы в видео-память
   jmp @b
@@:
   pop es
   popa
   mov sp, bp
   pop bp
   ret 8

debug:
   push bp
   mov bp, sp
   push ds
   mov ds, [bp+4]    ;сегмент, которые подвергается дампу
   pusha
   mov cx, 8
   xor di, di
   xor si, si
.a1:
   push cx
   mov cx, 16
   push di
        .a2:
      lodsb
      call byte2hex
      add di, 6
      loop .a2
   pop di
   add di, 160
   pop cx
   loop .a1
   popa
   pop ds
   mov sp, bp
   pop bp
   ret 2

byte2hex:
      pusha
      push ax
      shr al, 4
      cmp al, 9
      ja @1
      or al, 30h
      jmp write1
@1:
      add al, 'A'-10
write1:
      mov ah, 0Fh
      mov word [fs:di], ax
      pop ax
      add di, 2
      and al, 0fh
      cmp al, 9
      ja @2
      or al, 30h
      jmp write2
@2:
      add al, 'A'-10
write2:
      mov ah, 0Fh
      mov word [fs:di], ax
      popa
      ret

 
word2hex:
      pusha
      xchg al, ah
      call byte2hex
      add di, 4
      xchg al, ah
      call byte2hex
      popa
      ret

 
dword2hex:
      push eax
      push eax
      shr eax, 16
      call   word2hex
      add di, 8
      pop eax
      and eax, 0ffffh
      call word2hex
      pop eax
      ret

align 4             ;выравнивание на адрес кратный четырем
Packet:
             db 0x10     ; размер пакета
             db 0x00
             dw 0x0001  ; число читаемых секторов
             dw 0x0000  ; смещение
   DataSeg          dw 0x0000  ;сегмент данных
   LBAlow          dd 0x00000000   ;сектор в формате LBA
             dd 0x00000000

ErrorMsg  db 'Error read table ways.', 0
load1 db 'Load from harddisk'
load2 db 'Starting Fatal_Error OS'
ok    db 'LOADED', 0
error db 'ERROR', 0
device db ?

file1      db 10                           ;длинна имени файла
kernel_seg dw 100h                      ;сегмент, в который нужно грузить файл
name1      db 'KERNEL.BIN', 0          ;и собственно имя.
file2      db 9
segment2   dw 200h
name2      db 'CDROM.BIN', 0                 ;эти файлы вообще ничего в себе не содержат. гуржу, дабы проверить работоспособность
file3      db 10
segment3   dw 500h
name3      db 'DVDROM.BIN', 0
file4      db 0

RootSize dd ?

MenuItem db 0

и ядро
Код:
include 'constants.inc'
org 1000h
start:
                mov ax,3
                int 10h
                mov ah, 1
                mov ch, 20h
                int 10h

                in              al,92h
                or              al,2
                out             92h,al

                lgdt            fword [GDTR]

                cli
                in              al,70h
                or              al,80h
                out             70h,al

                mov             eax,cr0
                or              al,1
                mov             cr0,eax

                jmp fword CODE_SELEKTOR:PROTECTED_MODE_ENTRY_POINT

align 8
include 'GDT.inc'
use32
PROTECTED_MODE_ENTRY_POINT:
                mov ax, DATA_SELEKTOR
                mov ds, ax
                mov ss, ax
                mov ax, VIDEO_SELEKTOR
                mov es, ax
                mov esp, STACK_BASE_ADDRESS

                cld
PM_CODE:
                include 'PM_CODE.asm'
PM_CODE_END:

таблица GDT
Код:
GDT:
   NULL_descr   db      8 dup(0)
   CODE_descr   db      0FFh,0FFh,00h,00h,10h,10011010b,11001111b,00h
   DATA_descr   db      0FFh,0FFh,00h,00h,10h,10010010b,11001111b,00h
   GDT_SIZE   =       $-GDT

label GDTR fword
      dw      GDT_SIZE-1
      dd      GDT

так вот. загрузчик успешно загружает мое ядро, в отладчике bochs'а я дохожу до команды jmp fword CODE_SELEKTOR:PROTECTED_MODE_ENTRY_POINT и тут все... осуществляется прижок в никуда... идет команда add [eax], какое-то_число и лезет исключение... бочс перезагружается... само ядро рабочее, я пробовал грузить его через флоппик - результат удовлетворительный. а с сидюка бред... я понимаю, что код читать трудоемко и долго, но все же надеюсь на вашу помощь :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 23 май 2013, 22:13 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
А как ты записываешь на CD, в формате дискеты?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 23 май 2013, 22:18 
Аватара пользователя

Зарегистрирован: 20 апр 2011, 10:54
Сообщения: 145
Покажи GDT.

_________________
Found a CPU. LAPIC ID: 00


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 24 май 2013, 04:47 

Зарегистрирован: 10 сен 2012, 18:39
Сообщения: 5
lgdt, впринципе, должна выглядить так "lgdt fword [cs:GDTR]"
нету настройки cs:ip в загрузчике, или есть?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 24 май 2013, 05:53 

Зарегистрирован: 25 фев 2013, 22:01
Сообщения: 63
Цитата:
Покажи GDT.

есть, чуть ниже кода ядра
Himik писал(а):
А как ты записываешь на CD, в формате дискеты?

через ультра исо. файл-новый-загрузочный СД.
Цитата:
lgdt, впринципе, должна выглядить так "lgdt fword [cs:GDTR]"
нету настройки cs:ip в загрузчике, или есть?

они в загрузчике первыми строками идут.
вобщем упрощу задачу: я пробовал в таблицу GDT записать одну переменную, и потом считать ее - рузультат удовлетворительный. следовательно, все данные присутствуют в оперативе, чтение с сидюка прошло успешно.
еще одна странность:
так все норм:
Код:
include 'constants.inc'
org 1000h
start:
                mov ax,3
                int 10h
                mov ah, 1
                mov ch, 20h
                int 10h
                push 0
                push l

                retf
l:
                jmp PROTECTED_MODE_ENTRY_POINT
                mov ax, cs
                mov ax, ds
                in              al,92h
                or              al,2
                out             92h,al

                lgdt            fword [GDTR]

                cli
                in              al,70h
                or              al,80h
                out             70h,al

                mov             eax,cr0
                or              al,1
                mov             cr0,eax

                jmp CODE_SELEKTOR:PROTECTED_MODE_ENTRY_POINT

PROTECTED_MODE_ENTRY_POINT:
                mov ax, DATA_SELEKTOR
                mov ds, ax
                mov ss, ax
                mov ax, VIDEO_SELEKTOR
                mov es, ax
                mov esp, STACK_BASE_ADDRESS

                cld
PM_CODE:
                include 'PM_CODE.asm'
PM_CODE_END:
align 8
include 'GDT.inc'
use32

но без защищенного режима. а вот так нет:
Код:
include 'constants.inc'
org 1000h
start:
                mov ax,3
                int 10h
                mov ah, 1
                mov ch, 20h
                int 10h
                push 0
                push l

                retf
l:
                mov ax, cs
                mov ax, ds
                in              al,92h
                or              al,2
                out             92h,al

                lgdt            fword [GDTR]

                cli
                in              al,70h
                or              al,80h
                out             70h,al

                mov             eax,cr0
                or              al,1
                mov             cr0,eax

                jmp CODE_SELEKTOR:PROTECTED_MODE_ENTRY_POINT

PROTECTED_MODE_ENTRY_POINT:
                mov ax, DATA_SELEKTOR
                mov ds, ax
                mov ss, ax
                mov ax, VIDEO_SELEKTOR
                mov es, ax
                mov esp, STACK_BASE_ADDRESS

                cld
PM_CODE:
                include 'PM_CODE.asm'
PM_CODE_END:
align 8
include 'GDT.inc'
use32

если надо могу скинуть образ.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 24 май 2013, 10:57 

Зарегистрирован: 19 май 2011, 14:54
Сообщения: 73
У вас регистр ds неверно присваивается. Вместо mov ax, ds судя по-всему должно быть наоборот.
Во-вторых, процессор не умеет одним прыжком переходить сразу в 32-битный режим. Сначала нужно сделать jmp с 16-битным смещением, потом следом уже с 32-битным. Примерно как в поправленном варианте ниже.

Код:
               
                mov ax, cs
                mov ds, ax
                in              al,92h
                or              al,2
                out             92h,al

                lgdt            fword [GDTR]

                cli
                in              al,70h
                or              al,80h
                out             70h,al

                mov             eax,cr0
                or              al,1
                mov             cr0,eax

                jmp 0x8:OFFSET16_ENTRY_POINT
OFFSET16_ENTRY_POINT:
use32
            jmp 0x8:PROTECTED_MODE_ENTRY_POINT

PROTECTED_MODE_ENTRY_POINT:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 24 май 2013, 12:22 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Всё он умеет. Советую вам разобрать что да как происходит и в чём разница.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 24 май 2013, 13:04 

Зарегистрирован: 10 сен 2012, 18:39
Сообщения: 5
Fatal_Error писал(а):
вобщем упрощу задачу: я пробовал в таблицу GDT записать одну переменную, и потом считать ее - рузультат удовлетворительный. следовательно, все данные присутствуют в оперативе, чтение с сидюка прошло успешно.
этот тест работать не будет если вы делаете это во время исполнения програмы и если какието проблемы с сег. регистрами.
Не надо записывать, надо только считать и сравнить с без использования дополнительной памяти


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 24 май 2013, 14:26 

Зарегистрирован: 19 май 2011, 14:54
Сообщения: 73
pavia писал(а):
Всё он умеет. Советую вам разобрать что да как происходит и в чём разница.


Возможно... В таком случае советую дать какой-нибудь дельный совет коллеге с проблемами, если вы уж так быстры на советы.

Я лишь хотел сказать что первый jmp после mov cr0,eax должен быть с 16-битным аргументом в качестве смещения. 32 битные смещения могут использоваться только после первого jmp.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: переход в PM
СообщениеДобавлено: 24 май 2013, 16:06 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
achesnokov писал(а):
Во-вторых, процессор не умеет одним прыжком переходить сразу в 32-битный режим. Сначала нужно сделать jmp с 16-битным смещением, потом следом уже с 32-битным.

Если используется префикс 32-битного сегмента, то и смещение может быть 32-битным. Только надо правильно закодировать инструкцию перехода, добавив префикс 32-битного адреса. Думаю, что-то типа jmp fword ...
Я использовал такой метод
pushd SelCS32
pushd OffsetEntryPoint32
retfd
Это код 16-битного сегмента для перехода на 32-битный.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB