Board.KolibriOS.org

Официальный форум KolibriOS
Текущее время: Пт май 25, 2018 4:21 am

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 13 сообщений ] 
Автор Сообщение
 Заголовок сообщения: Phoenix BIOS
СообщениеДобавлено: Чт мар 29, 2018 12:10 am 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Ребят, а может кто-то подсказать в какую сторону двигаться, вопрос следующий:
Есть несколько машин с разными BIOS, и есть код в реальном режиме, который выводит символы (текстовая чёрно-белая консоль). На виртуалках и на всех машинах с award bios код работает корректно. На машинах с Phoenix BIOS не выводятся символы/строки, но логика - остальное всё работает. Я читал, что Phoenix и AMI на некоторые прерывания затирают регистры (чего не делают остальные), но у меня в коде перед вызовом прерывания и так происходит очистка регистров - это не критично. Какие ещё отличия есть?
Не работает даже банальное:
Код:
INT 10h, 0Eh (14)       Write Character in Teletype (TTY) Mode

Загрузка происходит с флешки, проц Intel Core 2 Duo, прерывания включаю прямо перед очередным выводом. Никакого результата даже если в начало MBR записать что-то вроде этого:
Код:
sti
mov ah, 0x0e    ;0Eh; Display Character
mov al, 'y'     ; AL = code of character to display
int 0x10     
cli


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Чт мар 29, 2018 9:20 am 
Не в сети

Зарегистрирован: Ср мар 26, 2008 12:44 pm
Сообщения: 165
theonlymirage писал(а):
Никакого результата даже если в начало MBR записать что-то вроде этого:

Про стек, надеюсь, не забыл?


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Чт мар 29, 2018 6:27 pm 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Да, в основной программе со стеком всё хорошо, там много чего не работало бы без стека. В минимальном коде чего я уже не делал, который я сейчас мучаю (считай mbr) стек задал так:
Код:
mov sp, main+500h ;main указывает на начало кода mbr

видел делают так:
Код:
mov sp, 7C00h ; адрес загрузки кода. Вопрос: так можно, там же до кода биоса должно быть что-то в виде пустой прослойки?

Как лучше всего? Могу зашить в код, выделить и внутри кода память под стек.
Если что ss = 0: адресация же ss:sp, верно?

Плюс нашёл одну ошибку в начале кода, исправил:
Код:
mov ax, cs  ;было xor ax, ax

но на этом биосе всё хорошо (cs = 0).


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Чт мар 29, 2018 9:00 pm 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Давайте конкретизирую вопрос неким базовым кодом:
Код:
use16
org 0x7C00

main:
  cli
  mov ax, cs ;xor ax, ax
  mov ds, ax
  mov ss, ax
  mov sp, stack_start ; тут надо исправить глубину стека
  mov bp, stack_start
  sti
  mov si, text
  call put
  cli
  ;hlt
  jmp $

put:
  mov ah, 0x0e
  mov bh, 0
  lodsb
  test al, al
  jz endc
  int 10h
  jmp put
endc:
  ret

  text db 'Hello!', 10, 13, 0

stack_end:
  db 200 dup(0)
stack_start:

  times 510-($-main) db 0
  db 0x55, 0xAA
 

Помогите исправить все ошибки, из того что я вижу: правильно задать стек, смещения с учётом cs, возможно нужно задать режим отрисовки и очистить экран перед выводом и плюс задать позицию ввода и сегмент.


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Пт мар 30, 2018 12:26 pm 
Не в сети

Зарегистрирован: Ср мар 26, 2008 12:44 pm
Сообщения: 165
theonlymirage писал(а):
видел делают так:
Код:
mov sp, 7C00h ; адрес загрузки кода.

Если ss = 0, вполне работающий вариант.

theonlymirage писал(а):
Плюс нашёл одну ошибку в начале кода, исправил:
Код:
mov ax, cs  ;было xor ax, ax

но на этом биосе всё хорошо (cs = 0).

Разные биосы могут запускать загрузочный сектор с адресов либо 0:7C00, либо 7C0:0.


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Пт мар 30, 2018 6:32 pm 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Ужас нарастает. Выяснил, что прошивка пытается автоматически определить, какой режим загрузки использовать. Как она это делает:
-- по первой инструкции (xor ax, ax или jmp 00:main)
-- по таблице разделов
-- по области BPB
-- с помощью иной магии
От этого может меняться значение в cs и адрес загрузки кода.

Если в начале jmp, то считается есть область BPB, которую мы перепрыгиваем. Этот переходный BIOS, который одним краем граничит с UEFI, в этом случае вполне может заполнить эту область данными о загрузочном устройстве - затерев наш код.

Получается, что более менее универсальный MBR в современном мире будет ещё более ограничен в размерах (на целую область BPB, которая не всегда и не всем нужна).


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Пт мар 30, 2018 8:56 pm 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Ещё одна моя ошибка:
Код:
mov ss, <значение>

порождает прерывания, это есть в мануалах intel. Такое поведение существует аж с 8088. Команда cli не может его замаскировать. После этой команды не следует класть что-то в регистр sp, что я сделал в коде выше.

Самая главная ошибка была в другом, я зря терял время, нужно было сбросить флаг направления инструкцией cld. В этих bios'ах он выставлен и происходит декремент при печати строки, а не инкремент.


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Пн апр 02, 2018 9:42 am 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Нашёл аналогичную ошибку в Колибри - внёс изменения на SVN. На моих машинах вывод сообщений от Колибри теперь заработал.
Молюсь, чтобы нигде не ошибся для других ;)


Про последовательность инструкций:
Код:
mov ss, <значение1>
mov sp, <значение2>

не стал править и не обязательно - этого наверное никто не делает и оно везде работает, но следует помнить, что иногда может произойти проваливание в прерывания и никакое cli не поможет.


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Пн апр 02, 2018 5:30 pm 
Не в сети

Зарегистрирован: Вс окт 30, 2011 6:43 pm
Сообщения: 1261
theonlymirage, а это только на Фениксы влияет? Есть где-то информация?


Вернуться к началу
 Заголовок сообщения: Re: Помогите новичку
СообщениеДобавлено: Пн апр 02, 2018 11:30 pm 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Сразу отмечу, что с официальной информацией не густо.
На опыте, на практике такая проблема возникла только на Фениксах. Конечно, у меня было мало разных железок за всё время, но факт есть факт.

Есть ABI-стандарт и соглашение, где у всех чётко прописано значение 0 по дефолту и рекомендация обнулять флаг направления при выходе из каждой функции. Об этом есть в System V Intel386 ABI (Registers and the Stack Frame), AMD64 ABI и в других документах и почти на всех форумах. Найти оф. описание, касаемо выставленного флага, Фениксов мне не удалось, зато есть множество тем, где люди с этим сталкивались. Чтобы понять, что проблема длится достаточно давно, я приведу эту ссылку и цитату:
Цитата:
Years ago, I worked for Tandy when they built their first AT compatible. I had written a disk drive diagnostic that ran fine on a real AT but hung up every time I ran it on our prototype (which worked fine otherwise, including running DOS). We traced the problem to the fact that the BIOS that Tandy licensed from Phoenix (also at an early revision level) used a series of string moves without clearing the direction flag, and my diagnostic happened to set the flag in a display routine. Somebody tried to argue that maybe DOS expected the flag to be cleared at all times. But they couldn't produce any documentation, and besides we could see where the IBM BIOS used a similar series of string moves and did establish the state of the direction flag first, so Phoenix added it. Presumably, Phoenix used a "cleanroom" system: one group of software engineers studied the IBM BIOS source code (which IBM published) and wrote a specification which was then designed and coded by another group of programmers.

Posted by Ellis Easley on 25 Sept 2003, 5:13 p.m.

Соответственно нужно смотреть исходники IBM BIOS и ожидать там такой же проблемы. А пока же мой практический опыт показывает: добавляем cld и всё работает, убираем - и ничего (в лучшем случае, экран пустой чёрный с мигающей кареткой ввода).


Про догадки об умном BIOS'е: https://stackoverflow.com/questions/392 ... 3#39248323
Так же видел это в каком-то оф. документе, но не сохранил - найду скину ссылку сюда.
Цитата:
Цитата:
In theory you wouldn't need a BPB when writing a MBR and not a VBR, and the presence of the xor ax, ax instruction wouldn't influence the booting.
You should include a xor bh, bh however (more on Int 10/AH=0Eh)

Sadly this is just theory.

Specially for USB devices a BPB is implicitly assumed by some firmware, including the full FDC descriptor (with a valid OS name).
Many thanks to Michael Petch for stressing this out.

Since the introduction of UEFI implementations, particularly the parts dealing with CSM (Compatibility Support Module), i.e. legacy booting, writing a fully supported MBR has became tricky.

The firmware will sometimes try to automatically detect what boot mode to use and since all UEFI devices are also legacy devices per specification, the firmware must rely on some quirk to tell them apart.

My firmware detect a device as "legacy", even when explicitly told so, only when at least one of these is true:

There is a bootable, non empty, partition in the MBR partition table.
The starting/ending address, either in CHS or LBA, are not checked at all.
The first instruction is a xor ax, ax (in either forms: 33 C0 or 31 C0). This is because the first thing most bootloaders do is to set the segment registers to zero through AX.
There may be other "signatures", like a jump at the first bytes, but I haven't tested them (yet).

If the firmware fails to detect the device as legacy and it is not a UEFI compliant device, it will be skipped.

Posted by Margaret Bloom


По немаскируемым прерываниям и магии при изменении сегментных регистров ещё большая каша. Я просто приведу несколько ссылок:
Ссылка: https://dev64.wordpress.com/2012/05/14/ ... reference/
Цитата:
Цитата:
Дополнительная информация для обработки исключения

Особенное внимание должно быть уделено тому, чтобы исключение возникающее в процессе явного переключения стека не приводила к использованию процессором invalid stack pointer (CS:ESP). Программы, написанные для 16-ти битных IA-32 процессоров часто используют пару инструкций для переключения на новый стек, например:
MOV SS, AX
MOV SP, StackTop
При выполнении этого кода на одном из 32-битных IA-32 процессоров, возможно получить page fault, general protection fault (#GP) или aligment check fault (#AC) исключения после загрузки сегментного селектора в регистр SS, но прежде загрузки регистра SP значением нового StackTop. В этот момент пара SS:ESP является нецелостной. Новый стековый сегмент, и старое значение ESP (stack pointer).
...
В системах, обрабатывающих page-fault, general-protection или aligment check исключения внутри задачи генерирующей fault (с помощью trap или interrupt gate), программа выполняющаяся на том же уровне привелегий, что и обработчик исключения, должна инициализировать новый стек используя LSS инструкцию, вместо пары MOV инструкций, приведенных выше.


Ссылка: https://c9x.me/x86/html/file_module_x86_id_304.html
Ссылка: http://www.vcfed.org/forum/archive/inde ... 41453.html

Ссылка: https://web.itu.edu.tr/kesgin/mul06/int ... r/mov.html
Цитата:
Цитата:
If the destination is SS interrupts are disabled except on early buggy 808x CPUs. Some CPUs disable interrupts if the destination is any of the segment registers


Если кратко, то есть около 4 типажей процессоров, которые по-разному относятся к этой последовательности инструкций.


Вернуться к началу
 Заголовок сообщения: Re: Phoenix BIOS
СообщениеДобавлено: Пт апр 06, 2018 11:51 am 
Не в сети

Зарегистрирован: Вт апр 12, 2011 11:19 pm
Сообщения: 1091
Выделил вопрос в отдельную тему
KolibriOS » Список форумов » Основные темы » Ядро » Загрузчик » Phoenix BIOS

_________________
я лишь учусь


Вернуться к началу
 Заголовок сообщения: Re: Phoenix BIOS
СообщениеДобавлено: Ср апр 11, 2018 4:32 am 
Не в сети
Mentor
Аватара пользователя

Зарегистрирован: Пн окт 19, 2009 10:58 am
Сообщения: 361
Intel SDM, Vol. 2, Ch. 2, MOV -- Move:
Цитата:
Loading the SS register with a MOV instruction inhibits all interrupts until after the execution of the next instruction.
This operation allows a stack pointer to be loaded into the ESP register with the next instruction (MOV ESP, stack-
pointer value) before an interrupt occurs. Be aware that the LSS instruction offers a more efficient method of
loading the SS and ESP registers.
Насколько могу судить, в cli/sti оборачивать не нужно.


Вернуться к началу
 Заголовок сообщения: Re: Phoenix BIOS
СообщениеДобавлено: Ср апр 11, 2018 8:51 am 
Не в сети

Зарегистрирован: Сб апр 22, 2017 6:11 pm
Сообщения: 66
Не все процессоры ведут себя так. Выше я как раз писал об этом, приводя ссылки.
Но, конечно же, в целом все придерживаются такого поведения. Особенно если мы говорим о современном железе.

У меня было время посмотреть другие загрузчики Колибри (самые что называется "боевые" и рабочие), и там всё это есть (и cli, sti и cld) в определённой мере. Ну, например, загрузчик FAT32 с USB.
Код:
@@:
        xor     eax, eax
        mov     ds, ax
        mov     ss, ax
        mov     sp, 7C00h
        mov     bp, sp
        mov     [boot_drive], dl
        cld
        sti


К сожалению, я выяснил, что необходимость в cld не единственная проблема для моих Phoenix BIOS при загрузке с USB. Возможно он анализирует что-то ещё, просто записанный MBR на флешку не работает, нужна структура файловой системы/разделов. Например, такая же разметка FAT32, как у загрузчика в примере выше - тогда всё работает.
Короче, пока я не разобрался со всеми нюансами. Думаю есть люди, которые знают больше и лучше расскажут об этом.

P.S. Если экономить место на байтах загрузчика, то да, не нужно и до этого работало на большинстве железок. Кстати, для экономии можно попробовать пожать загрузчик аналогом kpack. Ахахах... я где-то такое видел =)


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 13 сообщений ] 

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB