Страничный режим

Тема в разделе "WASM.OS.DEVEL", создана пользователем rei3er, 30 мар 2007.

  1. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Всем привет!
    Подскажите, как правильно включить страничный режим
    ситуация такая: мы в защищенном режиме (режим страничной адресации выключен), выполняющийся код расположен по линейному (физическому) адресу 0x100000. Таблицы страниц настроены и отображают этот код на 0xC0100000. После выставления PG в CR0 и jump-а идет вылет с перезагрузкой
    Код (Text):
    1. ; настройка cr3 и пр
    2. ...
    3.     lgdt [gdtr - OFFSET] ; OFFSET = 0xC0000000, в gdtr линейный адрес GDT уже отображенный, т. е 0xC...
    4.     mov eax, cr0
    5.     or eax, 1 SHL 31
    6.     mov cr0, eax
    7.     jmp far 08h:@F
    8. @@: ; физический адрес = 0x100200, в предыдущем jmp смещение = 0xC0100200, селектор = 8
    9. ; сюда не попадаем
    10. ...
    в мануале от Intel прочитал
    (см. выделенное)
    изменил gdtr (поле линейного адреса теперь содержит физический адрес (но который можно интерпретировать и как виртуальный (отображается сам в себя))) и подправил таблицы страниц, кроме того подправил jmp
    Код (Text):
    1. jmp far 08h:@F - OFFSET
    но все равно не работает
    в чем может быть дело?
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    http://www.wasm.ru/article.php?article=pipm06
    http://www.wasm.ru/article.php?article=pipm09

    PS. Maybe +OFFSET, а не -OFFSET?
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Great
    слушай, да знаю я это
     
  4. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    именно -
     
  5. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.578
    Адрес:
    Russia
    rei3er
    Значит не все знаешь. Либо неверно инициализированна карта таблиц страниц...
    Переключение у меня работает :

    Код (Text):
    1.  mov eax,cr0 ;Read CR0.
    2.  bts eax,31 ;Set PE=1.
    3.  mov cr0,eax ;Write CR0.
    4.  db 0ebh,0 ;jmp0
    А вообще будте спокойнее и приведите пожалуйсто весь ваш код.
     
  6. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    извините, просто действительно непонятно, где ошибка
    код я конечно привести могу, но сомневаюсь, что кто-то будет в нем разбираться: уж очень он большой
     
  7. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.578
    Адрес:
    Russia
    rei3er
    Приаттачь исходник, или приведи хотяб то что относится к инициализации страничной адресации.
     
  8. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Не совсем понял, зачем в 'lgdt [gdtr - OFFSET]' отнимается OFFSET -- ведь страничное преобразование еще не включено...
     
  9. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    в том то и дело
    если оставить так
    Код (Text):
    1. lgdt [gdtr]
    то получим
    а необходим физический адрес, т. е
     
  10. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.578
    Адрес:
    Russia
    rei3er
    Бред. У тебя еще нет страничной адресации... в реальном режиме лин=физ адресу как правило.
    я делал так :

    lgdt [pGDT32]

    ...

    mydata:
    pGDT32:
    dw gdtend-gdt ;GDT лимит
    dd gdt ;и 32-битная база GDT
    dd 0

    и все работало.
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Код (Text):
    1. org 0x100000 + OFFSET
    2. start:
    3.     ; на самом деле этот код при выполнении находится по адресу 0x00000500
    4.     mov esi, 0x00000500
    5.     mov edi, 0x100000
    6.     mov ecx, KSIZE / 4 ; KSIZE = 0x3000
    7.     cld
    8.     rep
    9.     movsd
    10.     mov eax, entry_32 - OFFSET
    11.     jmp eax ; переходим на 0x100000 + (entry_32 - start)
    12.  
    13. entry_32:
    14.     mov eax, [OPTIONS_SEG SHL 4 + MEM_SIZE_OFFSET] ; OPTIONS_SEG = 0x9000 (получаем общее количество памяти в системе в байтах (тут все правильно!!))
    15.     shr eax, 7
    16.     and eax, (NOT 0) SHL 5 ; размер всех блоков по 32 байта, каждый из которых описывает физическую страницу памяти
    17.     add eax, 0x100000 + KSIZE ; физический адрес начала таблиц страниц
    18.     mov ebx, eax
    19.     and eax, NOT ((NOT 0) SHL 12)
    20.     jz @F ; если адрес выравнен по размеру страницы
    21. ; иначе выравниваем
    22.     sub eax, 4096
    23.     neg eax
    24.     add ebx, eax
    25. @@:
    26.     xor edx, edx
    27.     mov ebp, page_dir - OFFSET + (OFFSET SHR 22 - 1) SHL 2 ; начинаем с 768 элемента каталога страниц
    28. @@1:
    29.     mov eax, 3 ; установить P и W биты
    30.     or eax, ebx ; 20 старших бит физического адреса таблицы страниц
    31.     add ebp, 4
    32.     mov dword [ebp], eax ; установить PDE (здесь ss = ds, потому можно использовать [ebp])
    33. @@2:
    34.     mov eax, 3
    35.     or eax, edi ; 20 старших бит физического адреса реальной страницы
    36.     mov dword [ebx], eax ; установить PTE
    37.     add ebx, 4
    38.     add edi, 4096
    39.     cmp edi, ebx
    40.     jae @F
    41.     test ebx, NOT ((NOT 0) SHL 12)
    42.     jnz @@2 ; текущая таблица страниц заполнена не до конца
    43.     jmp @@1 ; переходим к следующему элементы каталога страниц
    44. @@:
    45.     lgdt [gdtr - OFFSET]
    46.     mov eax, page_dir - OFFSET
    47.     mov cr3, eax
    48.     mov eax, cr0
    49.     or eax, 1 SHL 31
    50.     mov cr0, eax
    51.     jmp 08h:@F
    52. @@:
    53.     ...
    54. gdtr:
    55.     dw BOOT_GDT_TABLE - 1
    56.     dd gdt
    57. gdt:
    58.     dq 0x0000000000000000
    59.     dq 0x00CF98000000FFFF ; 32-ух битный код
    60.     dq 0x00CF92000000FFFF ; 32-ух битные данные
    61. BOOT_GDT_TABLE = $ - gdt
    62. align 4096
    63. page_dir:
    64.     db 4096 dup(0)
     
  12. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    во-первых, у меня защищенный режим
    во-вторых, потому как страничная адресация не включена, мне и нужен физический адрес gdtr,
    т. е 0x00100300, а не 0xC0100300, который зашивается в команде
    Код (Text):
    1. lgdt [gdtr]
     
  13. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.578
    Адрес:
    Russia
    rei3er
    Хм.. я конечно могу посмотреть в чем проблема.
    Но сразу скажу, если запускаешь под Досом, то зачем такой org делать (сделал бы 100h)
    далее - эти привязки к адресам в начале кода .. ты не умеешь получать дельта смещение ?.. и эти оффсеты..

    В общем эти замечания при первом взгляде. Конкретно попозже сообщу... а может кто до меня успеет.
     
  14. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    TermoSINteZ
    я привел часть кода, причем сильно упрощенную
    DOS и пр. вообще не причем: идет загрузка через boot-сектор (свой)
    мне нужно, чтобы код работал и в страничном режиме и в обычном защищенном без страничного
    для этого сделан org = 0xC0100000
    любой физический адрес в пределах кода/данных отображается на виртуальный с использованием OFFSET, т. е
    Код (Text):
    1.     lgdt [gdtr - OFFSET] ; ТУТ СТРАНИЧНЫЙ РЕЖИМ НЕ ВКЛЮЧЕН, ПОЭТОМУ В КОМАНДУ ЗАШИТ АДРЕС 0x00100300
    2.     mov eax, page_dir - OFFSET
    3.     mov cr3, eax
    4.     mov eax, cr0
    5.     or eax, 1 SHL 31
    6.     mov cr0, eax
    7.     jmp 08h:@F
    8. @@:
    9.     lgdt [gdtr] ; ТУТ СТРАНИЧНЫЙ РЕЖИМ ВКЛЮЧЕН, ПОЭТОМУ НУЖЕН АДРЕС 0xC0100300
    10. gdtr:
    11.     dw BOOT_GDT_TABLE - 1
    12.     dd gdt
    13. gdt:
    14.     dq 0x0000000000000000
    15.     dq 0x00CF98000000FFFF ; 32-ух битный код
    16.     dq 0x00CF92000000FFFF ; 32-ух битные данные
    17. BOOT_GDT_TABLE = $ - gdt
    18. align 4096
    19. page_dir:
    20.     db 4096 dup(0)
     
  15. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.578
    Адрес:
    Russia
    rei3er
    Теперь понятно как все работает
    Мнеб глянуть полный код... Чтоб можно было протестить . А без него скажу -
    И еще - как ты определяешь, что код не доходит до того места, ты можешь хотяб посмотреть какое происходит исключение.
    Я почему-то уверен , что дело в таблицах страниц. Попробуй их по началу просто отобразить линейно... одна база кода , одна база данных, одна база стека (с 0 адреса на 4 гига) и проверить . правильно ли заполнено.
    Например записав в видеопамять что нибудь.
     
  16. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Код (Text):
    1. ; если тут вставить, что-нибудь, например запись в видеопамять, то все ОК
    2. ;   mov word [0xB800 SHL 4], 0x0F30
    3.     mov eax, cr0
    4.     or eax, 1 SHL 31
    5.     mov cr0, eax
    6.     jmp 08h:@F
    7. @@:
    8. ; если сюда вставить запись в видеопамять, то ничего не выводится (кроме того идет reboot)
    проверял на VMWare
    говорит Kernel Stack Fault
    причем тут стек, вообще непонятно...
     
  17. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.578
    Адрес:
    Russia
    rei3er
    А что еслид объявишь дескриптор описатель стека , и инициализируешь селектор ss. Может будет другая ошибка ?
     
  18. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    не думаю, стек у меня вообще не используется, а VMWare по-моему для любой ошибки, которая приводит к перезагрузке пишет Kernel Stack Fault
     
  19. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.578
    Адрес:
    Russia
    Тогда я бы поставил QEMU и посмотрел бы ошибку ..
    либо сделал бы обработчик исключений, точнее обработчики прерываний и нарушений и выводил бы на экран код ошибки ... (он в стеке должен быть)
     
  20. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Вообще, лучше всего для таких целей подходит Bochs -- у него и отладчик есть и лог достаточно подробный. А VMWare в этом вопросе верить нельзя -- она на все что угодно говорит "Kernel Stack Fault".

    Кстати, полного кода действительно не хватает.