Бьюсь над этим долго. Я написал первичный и вторичный загрузчик, начал писать ядро, могу выводить на экран информацию. Но не могу сменить видеорежим. Прерывания недоступны, есть какая-то таблица дескрипторов или еще что-то, но я решил туда пока не лезть. В связи с этим вопрос: как по простому поменять видеорежим? (в защищенном режиме проца)
Текстовые режимы стандартны. Управление в тектовом режиме экрана достаточно просто. А вот на графические режимы стандартов нет. Каждый производитель делает как хочет и совсем не обязательно говорит как именно. Если информацию по программированию интеловских карточек ещё можно найти, то по другим её практически нет. Ещё можно запускать BIOS функции в виртуальном режиме, но это достаточно сложно для новичка. Так что для вас есть два варианта - либо переключать видео-режим до перехода в PM, либо кодить исключительно под Intelовские карточки. Вот тут немного по русски написано - http://itreant.narod.ru/SwitchDisplayModeIntel.htm. Но совсем чуть-чуть. Полную инфу, но на английском можно найти на официальном сайте.
Выходить из защищенного надо чтобы BIOS прерывания юзать. Кто-то еще говорил что существует 32х битная точка входа для этого, но я не в курсе. Ну и без BIOS'a - через драйвер.
KIV На счет только интеловских конечно перегнул - есть nouveau, ati документация/открытые драйвера http://xorg.freedesktop.org/archive/individual/driver/?C=M;O=D
Да не надо курить никакие дрова. В гугл, искать по ключевым словам VGA, SVGA, VESA -- это древние стандарты досовских времён, которые в той или иной мере поддерживаются производителями железа и сегодня. По-крайней мере уж VGA тянут все. А судя по тому, что моя, отточенная годами, линупсовая командная строка к ядру содержит: video=vesafb:ypan,ywrap, и работает везде, где я её пробовал, я делаю вывод, что и VESA тоже поддерживается. Правда похуже чем VGA, ибо конкретный видеорежим приходится выбирать по новой на каждой железяке. И я уверен, что в гугле достаточно и описаний этих стандартов, и справочников по ним, и примеров программ.
Линукс вполне может юзать 32-битный BIOS или запускать его в виртуальном режиме. VESA это всего лишь программный стандарт. То есть какие функции должен обеспечить BIOS. А как они будут в нём реализововатся - не известно. Можешь поискать в Google BIOS32. Только эта опциональная фича и в BIOS может отсутствовать. Treant Да. Действительно перегнул. Но вот скажем для NVidia стандарты найти практически не возможно. И в любом случае придётся писать дровишки для железяк каждого вида.
KIV Линукс, если и использует биос, то исключительно для сбора информации на начальных этапах загрузки. Но если я запускаю X-сервер поверх фреймбуфера пашущего на vesa графике, то никаких вызовов биоса при каждой перерисовке экрана не будет. Линукс -- это не windows 95, он не делает никаких real-mode вызовов функций биоса.
Лиш бы что-нить отписать. Windows точно так же рисует через frame buffer без BIOS. И в защищённом режиме рисовать через frame buffer может любой кто хоть немного разбирался с графикой. BIOS вызывается для смены видеорежима, и в Linux в том числе если используется VESA. На SVGA аппаратных стандартов нету как на VGA, поэтому смена видеорежима через I/O на каждой карте делается по разному - из-за этого BIOS и используют. Железо копать безперспективно - у каждого производителя всё по своему.
По-простому как это хочет автор темы - никак. А вообще вариантов несколько: 32-битная точка входа для защищённого режима (описана в стандарте VESA), вызов BIOS из V86. Можно и в RM переключиться, поставить режим и вернуться в PM - но для полноценной ОС это не подходит.
строго говоря, никто не запрещает создать 16-разрядный сегмент в защищенном режиме, и из него вызывать те же самые прерывания... Несколько сложновато в плане настройки дескрипторов, но реально (выглядит реально, сам не пробовал )
Главное чтоб код BIOS нормально в таком сегменте работал. Ведь это не VM или RM - в сегментах селекторы, а BIOS может сделать mov ax, 0xF000; mov ds, ax
Расположение памяти используемой BIOS документировано значениями 256 байт с адреса 00400h и 51 байт с адреса 500h, правда инфа это древняя и существует ещё доп. память BIOS адрес которой можно узнать по Int 15h, фн C0h. Насколько помню в RM 64к перекрывающихся сегментов, а в таблицах PM только по 4к селекторов, поэтому сделать подставные селекторы для данных которые будут иммитировать поведение RM сегментов по адресам 400h и 500h должно получиться, а для старших областей памяти это не получится - просто не хватит размера GDT/LDT. Хотя возникающее при этом исключение можно перехватить и в обработчике подменить значение сегментного регистра на корректное, в нормально спроектированном коде BIOS переключение сегментных регистров не должно быть слишком частым, так что притормаживание от добавления к mov ds, ax обработки исключения не должно быть критичным. Впрочем практически таких экспериментов тоже не делал. К тому-же BIOS может пожелать временно переключиться в PM, а потом вернуться в RM, что естественно разрушит все попытки обойтись вызовом BIOS из 16 разрядного сегмента.
r90 Наточняк: Код (Text): pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); pmi_start = (void*)((char*)pmi_base + pmi_base[1]); pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); И, впоследствии: Код (Text): __asm__ __volatile__( "call *(%%edi)" : /* no return value */ : "a" (0x4f07), /* EAX */ "b" (0), /* EBX */ "c" (offset), /* ECX */ "d" (offset >> 16), /* EDX */ "D" (&pmi_start)); /* EDI */ Правда, это какие-то "необязательные" операции типа set_pallete, где вызовы биоса в качестве fallback'а: на случай если через vga не удалось сделать. Смена же режима, через vesa, по-ходу дела происходит ровно один раз, ещё до того, как ядро в PM перейдёт.