User-accessible MMIO

Kernel architecture questions
  • art_zh

    Выдели память user_alloc (68.12), проверь линейный адрес и мапь туда MMIO страницы с флагами PG_SHARED|PG_UW и не забываем про кеширование PG_NOCACHE.

    Обратный процесс - вызов user_free (68.13).

    Update.

    Размер mmio часто больше одной страницы. Таку что лучше мапить страницы commit_pages и освобождать unmap_pages.
  • Serge wrote:Выдели память user_alloc (68.12), проверь линейный адрес и мапь туда MMIO страницы с флагами PG_SHARED|PG_UW
    ...и наслаждайся глюками, которые возникнут, когда при внезапном завершении программы менеджер памяти попытается такие страницы освободить.
    Ушёл к умным, знающим и культурным людям.
  • Serge
    Спасибо, учту. PG_NOCACHE - зевнул, это точно
    diamond wrote:
    Serge wrote:Выдели память user_alloc (68.12), проверь линейный адрес и мапь туда MMIO страницы с флагами PG_SHARED|PG_UW
    ...и наслаждайся глюками, которые возникнут, когда при внезапном завершении программы менеджер памяти попытается такие страницы освободить.
    А чем эти глюки принципиально будут отличаться от обычной незакрытой кучи?
    Только тем, что реальные физические страницы не потеряются, а останутся на своем месте, по тем же BIOS-адресам.
    Евангелие от Иоанна: стих 1

    Code: Select all

    ; В начале было Слово:
    B32:        mov     ax, os_stack       ; Selector for os
    [/size]
  • art_zh wrote:А чем эти глюки принципиально будут отличаться от обычной незакрытой кучи?

    Code: Select all

    proc free_page
    ;arg:  eax  page address
               pushfd
               cli
               shr eax, 12                        ;page index
               bts dword [sys_pgmap], eax         ;that's all!
    
    Вопрос на засыпку: что будет, если free_page (начало кода которой приведено выше) попытается освободить страницу, находящуюся за пределами физической памяти (на которую рассчитан битовый массив sys_pgmap)?
    Ушёл к умным, знающим и культурным людям.
  • diamond wrote:Вопрос на засыпку: что будет, если free_page (начало кода которой приведено выше) попытается освободить страницу, находящуюся за пределами физической памяти (на которую рассчитан битовый массив sys_pgmap)?
    В данном конкретном случае - ничего страшного не случится. Поскольку физические адреса MMIO находятся в самой верхней зоне адресного пространства, просто будет поставлен бит где-то в самом конце таблицы sys_pgmap, куда менеджер памяти никогда не заглядывает.
    Неплохо было бы при инициализации забить всю верхнюю зону этой таблицы единицами, тогда и на счетчике свободных страниц это никак не отразится

    Code: Select all

    ; ( proc free_page)
    .....
               bts dword [sys_pgmap], eax         ;that's all!
               cmc
               adc [pg_data.pages_free], 0
    
    далее идет
    cmp [page_start], eax
    и сразу же - на выход, без каких-бы то ни было катастрофических последствий.
    Евангелие от Иоанна: стих 1

    Code: Select all

    ; В начале было Слово:
    B32:        mov     ax, os_stack       ; Selector for os
    [/size]
  • art_zh wrote:В данном конкретном случае - ничего страшного не случится. Поскольку физические адреса MMIO находятся в самой верхней зоне адресного пространства, просто будет поставлен бит где-то в самом конце таблицы sys_pgmap
    Ответ неверный. Рекомендую подумать ещё раз, учитывая (уже приведённый) факт, что массив sys_pgmap рассчитан на покрытие физической памяти.
    Ушёл к умным, знающим и культурным людям.
  • diamond

    user_free расшареные страницы не трогает. В остальных случаях terminate вызывает destroy_app_space, та destroy_page_table

    Code: Select all

    proc destroy_page_table stdcall, pg_tab:dword
    
           push esi
    
           mov esi, [pg_tab]
           mov ecx, 1024
    .free:
           mov eax, [esi]
           test eax, 1
           jz .next
               test eax, 1 shl 9
               jnz .next                      ;skip shared pages
           call free_page
    .next:
           add esi, 4
           dec ecx
           jnz .free
           pop esi
           ret
    endp
    
    Или есть другой способ "разобрать" адресное пространство ?
  • Пардон, не заметил флага PG_SHARED. Тогда вопрос снимается.
  • Я написал план, пофиг на ваше мнение, выполняйте. (c) главнокомандующий
    diamond, заметь, я такого не говорил и не писал (ни тут, ни в вике).
    А то, что я написал в вике - обобщения с форума.
  • Serge wrote:art_zh

    Выдели память user_alloc (68.12), проверь линейный адрес и мапь туда MMIO страницы с флагами PG_SHARED|PG_UW и не забываем про кеширование PG_NOCACHE.

    Обратный процесс - вызов user_free (68.13).

    Update.

    Размер mmio часто больше одной страницы. Таку что лучше мапить страницы commit_pages и освобождать unmap_pages.
    Все так и сделал
    pci32.7z (3.72 KiB)
    Downloaded 427 times
    Система грузится нормально :roll: вплоть до установки видеорежима.... Потом вышибает на перезагрузку.

    Отключил АТI- драйвер - все загрузилось без проблем.
    Похоже, ATIKMS где-то перехватывает сервис PCI?
    Евангелие от Иоанна: стих 1

    Code: Select all

    ; В начале было Слово:
    B32:        mov     ax, os_stack       ; Selector for os
    [/size]
  • art_zh

    Не перехватывает, но активно юзает.
    pci_api
    pci_read8
    pci_read16
    pci_read32
    pci_write8
    pci_write16
    pci_write32

    А до изменений нормально грузилось ?
  • Serge
    Оказалось, что я зацепил pci_write копипастом, fixed.
    Еще там была пара багов с перераскладкой регистров при системном вызове, разобрался с помощью diamond'а.
    Сейчас вроде все нормально; для тестирования слегка переделал утилиту pcidev.asm, теперь она видит выделенные юзеру каналы MMIO, распознает и маппит RAM-блоки, после чего пробует прочитать первую страницу из бортовой памяти.

    После 1 января выложу файлы здесь.
    На svn залью когда дадут аккаунт.

    Очень надеюсь, что новый сервис будет кому-нибудь так же полезен, как и мне. (а для меня это просто подарок к Новому году!)
    Спасибо, с наступающим!
    Евангелие от Иоанна: стих 1

    Code: Select all

    ; В начале было Слово:
    B32:        mov     ax, os_stack       ; Selector for os
    [/size]
  • Вначале нужно добавить поддержку PCI потом думать о том как его в user mode тянуть. Сейчас PCI это костыль таких размеров что многие думают что PCI есть, но на самом деле, его нет...
  • pci32.7z (9.05 KiB)
    новый PCI API и утилита PciDev.asm
    Downloaded 422 times
    Самая важная - функция 62:12.
    Она не только маппит блок необходимой длины на юзерспейс, но еще и избавляет от нудных манипуляций с BAR-регистрами и физическими адресами. Единственное, что надо держать в памяти: длина блока задается в байтах, а смещение в физической памяти - в целых страницах (1стр = 4к байт).
    Это так и задумано, иначе у юзера будет соблазн выставить не выравненный по началу страницы оффсет, что обязательно приведет либо к потере данных при маппинге, либо к сдвигу реальных линейных адресов относительно запрашиваемых приложением.
    Last edited by art_zh on Sat Jan 02, 2010 3:18 pm, edited 1 time in total.
    Евангелие от Иоанна: стих 1

    Code: Select all

    ; В начале было Слово:
    B32:        mov     ax, os_stack       ; Selector for os
    [/size]
  • Who is online

    Users browsing this forum: No registered users and 6 guests