Как получить информацию о BIOS VESA
Я следую инструкциям Phil-Opp о написании ОС в Rust, и, немного поиграв с ним, я хочу поиграть с отображением реальной графики на экране.
Я выяснил, что, вероятно, я должен начать с использования Linear Frame Buffer, с VESA. Я нашел несколько уроков на osdev.org здесь и здесь, но они продолжают говорить о "функциональных кодах" и es:di
. Вторая ссылка говорит следующее:
FUNCTION: получить информацию о BIOS VESA
Код функции: 0x4F00
Описание: возвращает информацию о BIOS VESA, включая производителя, поддерживаемые режимы, доступную видеопамять и т.д. Вход: AX = 0x4F00
Вход: ES: DI = Сегмент: указатель смещения, где хранить информацию о структуре VESA BIOS.
Выход: AX = 0x004F при успехе, другие значения указывают на то, что VESA BIOS не поддерживается.
Во всяком случае, вышеприведенная функция возвращает следующую структуру и сохраняет ее в ES: DI, поскольку они были на входе. При вводе ES: DI должен содержать указатель на следующую структуру:
vbe_info_structure:.signature db "VBE2"; indicate support for VBE 2.0+.table_data: resb 512-4; reserve space for the table below
Хотя я изучил некоторые уроки языка ассемблера, я понятия не имею, что такое "код функции". Из того, что я понимаю, если я mov ax, 0x4f00
и создаю структуру, подобную той, что была выше, она волшебным образом перезапишет структуру, которую я мог бы передать в качестве параметра для моего кода Rust? Как мне, или мне нужно, установить мой es:di
? (Из исследования я подумал, что он просто автоматически устанавливается на современных процессорах)
Должен ли я делать все это в Inline Assembly вместо этого? Должен ли я использовать UEFI и переписывать свое ядро? Мне бы очень хотелось, если бы вы могли привести пример доступа к vbe_info_structure в коде Rust (я работаю в long mode
).
Вот мой файл boot.asm
до сих пор, но он пока не работает: https://gist.github.com/nebrelbug/5a0042d4de32f942bb72e71fe282bdd2. Спасибо!
Ответы
Ответ 1
В файле boot.asm у вас есть:
get_vesa_info:
mov ax, 0x4f00
mov [es:di], vbe_info_structure
int 0x10
ret
Третья строка должна быть заменена на
mov di, vbe_info_structure
Объяснение: как и сейчас, он пытается записать константу vbe_info_structure по адресу, на который указывает es: di (что не определено в вашем случае). Вместо этого вы должны загрузить адрес vbe_info_structure в di и передать его в процедуру int 0x10.
Кстати, int 0x10 выполняет несколько функций. Чтобы указать, какой из них вы хотите вызвать, вы передаете "код функции" в регистре топора. Подумайте о функциональном коде как имени функции (в сборке нет имен, просто номеров и адресов).
Кроме того, вам нужно правильно настроить es. Либо сделайте
push ds
pop es
предполагая, что ds уже указывает на section.data или с помощью директивы ассемблера (assume es section.data
? - не уверен в этом, это было давно, так как я использовал ассемблер). Или может быть так:
mov ax, @section.data
mov es, ax
что должно быть сделано до загрузки 0x4f00 в топор, конечно.