Снова карта памяти

Тема в разделе "WASM.OS.DEVEL", создана пользователем _s_a_t_a_n_, 10 июн 2008.

  1. _s_a_t_a_n_

    _s_a_t_a_n_ New Member

    Публикаций:
    0
    Регистрация:
    5 май 2008
    Сообщения:
    13
    Попытаюсь сжать мой предыдущий пост как можно больше а то такое чувство что народу лень читать.

    Суть вот в чем:
    Я хочу получить карту памяти, которую загрузчик GRUB передал программе
    в составе Multiboot Information Structure.
    После того как загрузчик передал управление программе, в регистре EBX
    содержится физический адрес информационной структуры.

    В этой структуре по смещению 0 находится поле флагов.
    Если бит 6 установлен, то загрузчик передал программе карту памяти.
    Я проверяю установлен ли бит 6 следующим кодом:

    mov eax,dword [ebx]
    mov dword [infotable.flags],eax
    test [infotable.flags],1000000b
    jnz get_mmap_data
    jmp do_something

    В отладике вижу что бит 6 поля флагов установлен

    Там же по смещению 44 находится поле, содержащее размер карты памяти
    и по смещению 48 поле, содержащее физический адрес карты памяти.
    вот тут-то и начинаются странности.
    Адрес карты памяти: 0x00054D84
    Ее размер: 0x00000090 ;СЛИШКОМ МАЛЕНЬКИЙ ДЛЯ КАРТЫ ПАМЯТИ!!!

    Карта памяти состоит из одной или нескольких структур, описывающих
    свободные и занятые участки памяти.
    Состав такой структуры:
    Смещение Размер Поле
    -4 4 size ; Размер этой стуктуры
    0 4 base_addr_low ; Младший DWORD адреса
    участка памяти, описываемого этой
    структурой.
    4 4 base_addr_high ; аналогично, старший DWORD
    8 4 length_low ; Младший DWORD длины структуры
    12 4 length_high ; старший
    16 4 type ; если 1 - то этот участок можно
    использовать, если что-то другое то
    это зарезервиврованный участок.

    Результаты еще более странные.
    Оказывается что вся карта памяти состоит из одной только этой структуры
    Отсюда такой маленький размер 0x90 и поля этой структуры следующие:
    size: 0x00000000
    base_addr_low: 0x00000014
    base_addr_high: 0x00000000
    length_low: 0x0000000
    length_high: 0x0009FC00
    type: 0x00000000 ; участок непригоден для использования

    Вот код который парсит первую структуру карты памяти:

    ; копируем первый DWORD информационной стуктуры в EAX
    ; и записываем его в infotable.flags
    mov eax,dword [ebx]
    mov dword [infotable.flags],eax

    ; проверяем установлен ли бит 6 в поле флагов
    ; если да - прыгаем на get_mmap_data
    test [infotable.flags],1000000b
    jnz get_mmap_data
    jmp do_something

    get_mmap_data:

    ; получаем размер карты памяти по смещению 44
    mov eax, dword [ebx+44d]
    mov dword [infotable.mmap_length],eax

    ; и адрес по которому карта памяти расположена в памяти
    mov eax, dword [ebx+48d]
    mov dword [infotable.mmap_addr],eax

    ; Парсим карту памяти (первую структуру)
    mov edx, [infotable.mmap_addr]

    ; Получаем размер
    mov eax, dword [edx-4]
    mov dword [map.size],eax

    ; Младший DWORD адреса
    mov eax, dword [edx]
    mov dword [map.base_addr_low], eax

    ; Старший DWORD адреса
    mov eax, dword [edx+4d]
    mov dword [map.base_addr_high],eax

    ; Младший DWORD размера
    mov eax, dword [edx+8d]
    mov dword [map.length_low],eax

    ; Старший DWORD размера
    mov eax, dword [edx+12d]
    mov dword [map.length_high],eax

    ; Тип
    mov eax, dword [edx+16d]
    mov dword [map.type],eax
     
  2. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Не из одной их несколько. 90h/24=6 записей
    читай спецификацию внимательно.
    Там Size имеет смещение -4 потомучто size указывает размер следующих полей на самом деле никаких -4 нету, а все идет сплошным.
     
  3. _s_a_t_a_n_

    _s_a_t_a_n_ New Member

    Публикаций:
    0
    Регистрация:
    5 май 2008
    Сообщения:
    13
  4. _s_a_t_a_n_

    _s_a_t_a_n_ New Member

    Публикаций:
    0
    Регистрация:
    5 май 2008
    Сообщения:
    13
    Все понял. Спасибо. Тема закрыта
     
  5. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Поле Size есть оно показывает размер записи обычно размер 20 плюс 4 на само поле Size
    Если надо могу найти когда не равно 20.

    Просто считай что структура такая
    запись 0

    0 4 size0 ; Размер этой стуктуры
    4 4 base_addr_low0 ; Младший DWORD адреса
    участка памяти, описываемого этой
    структурой.
    8 4 base_addr_high0 ; аналогично, старший DWORD
    12 4 length_low0 ; Младший DWORD длины структуры
    16 4 length_high0 ; старший
    20 4 type0 ; если 1 - то этот участок можно
    использовать, если что-то другое то
    это зарезервиврованный участок.
    запись1
    24 4 size1 ; Размер этой стуктуры
    28 4 base_addr_low1 ; Младший DWORD адреса
    участка памяти, описываемого этой
    структурой.
    32 4 base_addr_high1 ; аналогично, старший DWORD
    36 4 length_low1 ; Младший DWORD длины структуры
    40 4 length_high1 ; старший
    44 4 type1 ; если 1 - то этот участок можно
    использовать, если что-то другое то
    это зарезервиврованный участок.


    запись1 начитнается со смещения 4 +Size0
    запись2 начитнается со смещения 4 +Size0 +4+Size1
    и тд.