OSDev http://osdev.su/ |
|
Определение адресов ОЗУ в адресной памяти http://osdev.su/viewtopic.php?f=6&t=347 |
Страница 1 из 1 |
Автор: | s3dworld [ 27 окт 2010, 11:09 ] |
Заголовок сообщения: | Определение адресов ОЗУ в адресной памяти |
Всем доброго дня! Среди 4 ГБ адресной памяти я хочу получить те адреса, которые являются оперативной памятью (ОЗУ). На основании полученных сведений я смогу построить таблицу страниц (по 4 МБ на страницу), где у меня будет задействована именно оперативная память (ОЗУ). Для достижения своих целей решил я использовать функция 0xE820 прерывания 0x15 (http://ru.osdev.wikia.com/wiki/%D0%9E%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BE%D0%B1%D1%8A%D1%91%D0%BC%D0%B0_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D0%B8). Это BIOS прерывание и естественно получать информацию я буду из режима реальных адресов (R-Mode). Написал модуль для определения объёма и карты распределения памяти: Код: ; Имя: test_memory ; Описание: Определение карты памяти ; Автор: Дубровкин Сергей ; Начало: 26.10.2010 - 13:19 ; Завершение: ??.??.???? - ??:?? ; ******************************************************************************* use16 ; ******************************************************************************* ; П Р О Ц Е Д У Р Ы ; ******************************************************************************* ; ------------------------------------------------------------------------------{ ; Название: Test_Memory__Main() ; Описание: Определение карты памяти ; Вход: Нет ; Выход: Нет ; ------------------------------------------------------------------------------- Test_Memory__Main: mov EAX,0x0000E820 xor EBX,EBX mov EDI,test_memory__item mov ECX,24 mov EDX,"SMAP" int 0x15 cmp EAX,"SMAP" jnz Test_Memory__Main_Label_1 push EDI mov EAX,[EDI] call UnsignedNumberToString mov ESI,EDI mov BL,00001111b mov DH,0 mov DL,0 call Boot__DrawText pop EDI add EDI,4 push EDI mov EAX,[EDI] call UnsignedNumberToString mov ESI,EDI mov BL,00001111b mov DH,1 mov DL,0 call Boot__DrawText pop EDI add EDI,4 push EDI mov EAX,[EDI] call UnsignedNumberToString mov ESI,EDI mov BL,00001111b mov DH,2 mov DL,0 call Boot__DrawText pop EDI add EDI,4 push EDI mov EAX,[EDI] call UnsignedNumberToString mov ESI,EDI mov BL,00001111b mov DH,3 mov DL,0 call Boot__DrawText pop EDI add EDI,4 push EDI mov EAX,[EDI] call UnsignedNumberToString mov ESI,EDI mov BL,00001111b mov DH,4 mov DL,0 call Boot__DrawText pop EDI add EDI,4 mov EAX,[EDI] call UnsignedNumberToString mov ESI,EDI mov BL,00001111b mov DH,5 mov DL,0 call Boot__DrawText jmp Test_Memory__Main_Label_End Test_Memory__Main_Label_1: mov ESI,test_memory__end mov BL,00001111b mov DH,0 mov DL,0 call Boot__DrawText Test_Memory__Main_Label_End: ret ; ------------------------------------------------------------------------------} ; ******************************************************************************* ; Д А Н Н Ы Е ; ******************************************************************************* test_memory__Data16: test_memory__itemSize db 24 test_memory__item db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 test_memory__end db "Function no complete!",0 После вызова данной процедуры, у меня значение двадцати четырёх байт, на начало которых указывает переменная test_memory__item, так и остаётся нулевым. И регистр EAX не содержит сигнатуру SMAP. О чём это может говорить: либо я что-то не так делаю, либо BIOS моего Bochs не совместим с ACPI? Как же мне тогда узнать адреса в адресной памяти в 4 ГБ, где у меня располагается оперативная память (ОЗУ)? |
Автор: | s3dworld [ 27 окт 2010, 12:24 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Уж не знаю на сколько эта функция мне подходит, но теперь она работает. Причина была в том, что команду с сигнатурой: Код: mov EDX,"SMAP" int 0x15 cmp EAX,"SMAP" Нужно было заменить на: Код: mov EDX,0x534d4150
int 0x15 cmp EAX,0x534d4150 |
Автор: | s3dworld [ 27 окт 2010, 12:42 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Ребят, вызываю функцию 0x0000E820 прерывания 0x15. В ответ получаю следующее: Начальный адрес диапазона, младшие 32 бита: 0 Начальный адрес диапазона, старшие 32 бита: 0 Длина диапазона, младшие 32 бита: 651264 Длина диапазона, старшие 32 бита: 062156 Тип диапазона: 162156 Расширенные атрибуты диапазона: 062156 И что это значит? Откуда такая длина? У меня всего 2 ГБ оперативной памяти (ОЗУ). Да и что-то значение в Длина диапазона, старшие 32 бита равно значению в Расширенные атрибуты диапазона. Сначала я подумал что возможно тупит моя функция перевода числа в строку, но я её тестировал (подсовывал ей значения и смотрел на результат) и она работала правильно. Хотя интересно, что в тексте впереди стоит 0, так ведь не должно быть. В чём может быть дело? Вот код перевода: Код: ; ******************************************************** ; П Р О Ц Е Д У Р А ; ******************************************************** ; -------------------------------------------------------{ ; Название: UnsignedNumberToString() ; Описание: Преобразование 32-битного числа в строку ; Вход: EAX - 32-битное число ; Выход: EDI - указатель на строку ; ECX - количество символов в строке ; -------------------------------------------------------- UnsignedNumberToString: mov EDI,string1 mov ECX,0 mov EBX,10 UnsignedNumberToString__Label_Div: mov EDX,0 div EBX add EDX,48 mov [EDI],byte DL inc EDI inc ECX cmp EAX,0 jz UnsignedNumberToString__Label_NoDiv jmp UnsignedNumberToString__Label_Div UnsignedNumberToString__Label_NoDiv: cmp ECX,1 jz UnsignedNumberToString__Label_NoBuild jmp UnsignedNumberToString__Label_Build UnsignedNumberToString__Label_Build: ;mov ESI,string1 ;mov EDI,string2 mov EBX,0 UnsignedNumberToString__Label_Build_Copy: mov EDX,ECX sub EDX,EBX sub EDX,1 ;add ESI,EBX ;add EDI,EDX ;mov AL,byte [ESI] ;mov [EDI],byte AL mov EDI,string1 add EDI,EBX mov AL,byte [EDI] mov EDI,string2 add EDI,EDX mov [EDI],byte AL inc EBX cmp ECX,EBX jz UnsignedNumberToString__Label_BuildComplete jmp UnsignedNumberToString__Label_Build_Copy UnsignedNumberToString__Label_BuildComplete: mov EDI,string2 jmp UnsignedNumberToString__Label_End UnsignedNumberToString__Label_NoBuild: mov EDI,string1 UnsignedNumberToString__Label_End: ret ; -------------------------------------------------------} ; ******************************************************** ; Д А Н Н Ы Е ; ******************************************************** UnsignedNumberToString__Data: string1 db 0,0,0,0,0,0,0,0,0,0,0 string2 db 0,0,0,0,0,0,0,0,0,0,0 |
Автор: | phantom-84 [ 27 окт 2010, 13:44 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Сделай вывод в 16-ричной системе. Так будет более понятно. Адрес буфера для структуры вроде бы должен передаваться в es : di. Может, у тебя es не проинициализирован. |
Автор: | s3dworld [ 27 окт 2010, 14:25 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
У меня все регистры установлены на 0, так же как и CS. В чём может быть дело? |
Автор: | s3dworld [ 27 окт 2010, 15:34 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Ошибка найдена (не мной) и исправлена (мной). Заключалась она в обнулении значения строк: Код: ; ******************************************************** ; П Р О Ц Е Д У Р А ; ******************************************************** ; -------------------------------------------------------{ ; Название: UnsignedNumberToString() ; Описание: Преобразование 32-битного числа в строку ; Вход: EAX - 32-битное число ; Выход: EDI - указатель на строку ; ECX - количество символов в строке ; -------------------------------------------------------- UnsignedNumberToString: mov EDI,string1 mov ECX,0 mov EBX,10 mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 mov EDI,string2 mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 inc EDI mov [EDI],byte 0 mov EDI,string1 UnsignedNumberToString__Label_Div: mov EDX,0 div EBX add EDX,48 mov [EDI],byte DL inc EDI inc ECX cmp EAX,0 jz UnsignedNumberToString__Label_NoDiv jmp UnsignedNumberToString__Label_Div UnsignedNumberToString__Label_NoDiv: cmp ECX,1 jz UnsignedNumberToString__Label_NoBuild jmp UnsignedNumberToString__Label_Build UnsignedNumberToString__Label_Build: ;mov ESI,string1 ;mov EDI,string2 mov EBX,0 UnsignedNumberToString__Label_Build_Copy: mov EDX,ECX sub EDX,EBX sub EDX,1 ;add ESI,EBX ;add EDI,EDX ;mov AL,byte [ESI] ;mov [EDI],byte AL mov EDI,string1 add EDI,EBX mov AL,byte [EDI] mov EDI,string2 add EDI,EDX mov [EDI],byte AL inc EBX cmp ECX,EBX jz UnsignedNumberToString__Label_BuildComplete jmp UnsignedNumberToString__Label_Build_Copy UnsignedNumberToString__Label_BuildComplete: mov EDI,string2 jmp UnsignedNumberToString__Label_End UnsignedNumberToString__Label_NoBuild: mov EDI,string1 UnsignedNumberToString__Label_End: ret ; -------------------------------------------------------} ; ******************************************************** ; Д А Н Н Ы Е ; ******************************************************** UnsignedNumberToString__Data: string1 db 0,0,0,0,0,0,0,0,0,0,0 string2 db 0,0,0,0,0,0,0,0,0,0,0 Результат такой: ![]() Первое значение на рисунке - это значение для регистра EBX (нужно для обработки следующих диапазонов). То что у меня идёт строка в обратном порядке, это точно. Но всё же получается что адрес с 0x00000000 (0) по 0x0009F000 (651264) у меня будет принадлежать именно к оперативной памяти (ОЗУ)? А значение 1 будет определять что память доступна для использования. Так? Но есть очень интересный момент: последнее значение равно 0. А в статье написано следующее: Цитата: Если содержит 0, ОС должна игнорировать этот описатель диапазона адресов (он содержит недействительную информацию) То есть данный диапазон использовать мне не стоит и продолжать дальше искать адреса. Так? |
Автор: | Himik [ 27 окт 2010, 16:16 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Адреса с 0x00000000 (0) по 0x0009F000 использовать не запрещается. Но первый килобайт занимает таблица BIOS прерываний, а второй килобайт занимают данные BIOS. |
Автор: | s3dworld [ 27 окт 2010, 16:20 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Ага, только я же всё это хочу для защищённого режима. Пока вот наберусь данных, а уже в защищённом режиме составлю каталог страниц. |
Автор: | s3dworld [ 27 окт 2010, 16:23 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Решил я вызвать большее количество раз функцию, передавая ей то в EBX, что она сама вернула. Вот что у меня получилось: ![]() Но не понимаю, почему два раза значение 5. Кто-нибудь вообще объяснит? Напомню, что самым первым в каждой группе цифр отображается то значение, которое оказалось в регистре EBX после вызова прерывания 0x15. |
Автор: | SII [ 27 окт 2010, 21:23 ] |
Заголовок сообщения: | Re: Определение адресов ОЗУ в адресной памяти |
Что возвращается в ЕБХ, никого волновать не должно, нужно лишь соблюдать все требования системного вызова. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |