LINUX.ORG.RU

Теперь дебажим SDL1; уточнение вопроса поломки работы с фреймбуфером свежих ядер

 , ,


1

3

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

strace показывает, что сегфолт происходит в районе вызова FBIOPUT_VSCREENINFO. Такое в SDL1 есть и при тестировании видеорежимов. Однако, критичным оказался неожиданный кусок video/fbcon/SDL_fbvideo.c.
Находится он в функции FB_SetVideoMode() и в оригинале выглядит так:

                if ( !shadow_fb &&
                                ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
                        vinfo.yres_virtual = height;
                        if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
                                SDL_SetError("Couldn't set console screen info");
                                return(NULL);
                        }
                }
Так вот. Если его привести к виду
                if ( !shadow_fb &&
                                ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
                        vinfo.yres_virtual = height;
                        /*if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
                                SDL_SetError("Couldn't set console screen info");
                                return(NULL);
                        }*/
                }
то всё начинает работать без сегфолтов на ванильных свежих ядрах.

Патч: http://saahriktu.org/downloads/patches/make_sdl1.2.15_works_with_framebuffer_...

★★★★★

Последнее исправление: saahriktu (всего исправлений: 1)
Ответ на: комментарий от Deleted

Тогда выкладывай его целиком.

Со всеми хэш-суммами паролей, ага.

с точностью до версий всех библиотек

Это будет сложно описать и имеет мало смысла. Такой квест мало кто будет проходить. У меня же сборка на основе LFS'а, которую я обновляю с 2007-го года. На 9 гигов в системном разделе.

эмуляция fbdev поверх DRM работает одинаково на разных устройствах

Однако, на разных устройствах может работать с разными опциями.

Настройки - это важно.

Тут в первую очередь важен конфиг, например, fceux'а. Вот он: http://saahriktu.org/fceux.cfg

SDL1 собрана с "./configure --prefix=/usr". fceux собран также. Вот config.log SDL1: http://saahriktu.org/config.log .

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от saahriktu

И я даже не знаю о каких опциях речь. Никогда ничего не собирал под виртуальные машины. Только под реальное железо.

make defconfig, затем make kvmconfig, затем (для данного конкретного случая) включить CONFIG_DRM_QXL (виртуальная видеокарта), CONFIG_INPUT_MOUSEDEV (интерфейс мыши), CONFIG_SND_HDA_GENERIC (звук).

Но в нашем случае это никак не поможет, так как ядро могу я и сам собрать.

Может напихать туда kprint'ов, чтобы посмотреть с какими параметрами вызывается FBIOPUT_VSCREENINFO у тебя? Сейчас попробую сделать ещё один патч...

Deleted
()
Ответ на: комментарий от saahriktu

О! Кажись я смог воспроизвести всё в точности как у тебя! Для этого нужны твои настройки fceux (http://saahriktu.org/fceux.cfg), твой fb.modes (http://saahriktu.org/tmp/fb.modes.lzma) и разрешение фреймбуфера 1920x1080. Если что-то из этого убрать, то перестаёт воспроизводиться.

*ушёл ковырять дальше*

Deleted
()
Ответ на: комментарий от Deleted

А я нашёл второй патч для SDL1, который работает для меня (без первого):

diff -ru SDL-1.2.15_orig/src/video/fbcon/SDL_fbvideo.c SDL-1.2.15/src/video/fbcon/SDL_fbvideo.c
--- SDL-1.2.15_orig/src/video/fbcon/SDL_fbvideo.c       2012-01-19 10:30:06.000000000 +0400
+++ SDL-1.2.15/src/video/fbcon/SDL_fbvideo.c    2018-12-27 21:59:42.853402012 +0300
@@ -1044,9 +1044,6 @@
                }
                vinfo.xoffset = 0;
                vinfo.yoffset = 0;
-               vinfo.red.length = vinfo.red.offset = 0;
-               vinfo.green.length = vinfo.green.offset = 0;
-               vinfo.blue.length = vinfo.blue.offset = 0;
                vinfo.transp.length = vinfo.transp.offset = 0;
                if ( ! choose_fbmodes_mode(&vinfo) ) {
                        choose_vesa_mode(&vinfo);
А вот актуальные значения:
vinfo.red.length = 8
vinfo.green.length = 8
vinfo.blue.length = 8
vinfo.red.offset = 16
vinfo.green.offset = 8
vinfo.blue.offset = 0

saahriktu ★★★★★
() автор топика
Последнее исправление: saahriktu (всего исправлений: 1)

Следующая версия патчей на ядро: https://lkml.org/lkml/2018/12/27/273. Там больше инфы на тему того, как это воспроизводить.

Deleted
()
Ответ на: комментарий от saahriktu

Да, проблема там была именно в нулевых значениях вот этих полей. В старых версиях ядра для эмуляции fbdev поверх drm они просто игнорились (точнее, задавались только на основе bpp), но потом это «исправили» =).

По поводу того, что с моими патчами картинка уезжает влево: это происходит из-за того, что второй мой патч (который чинит sdl1 когда нет /etc/fb.modes), делает так, что sdl считает больше видеорежимов поддерживаемыми системой. Это приводит к тому, что он запрашивает видеорежим с наименьшим разрешением, в которое влезает картинка с разрешением, которое запрашивает приложение. А так как эмуляция fbdev через drm вообще не поддерживает изменение разрешения (как минимум для qxl, но скорее всего для всех драйверов), то это по факту приводит к тому, что картинка меньшего разрешения выводится в углу экрана.

Вообще логика выбора видеорежима в sdl1 для fbdev реализована очень криво. Её бы выкинуть и переписать с нуля. А ещё лучше: выкинуть всю поддержку fbdev и запилить бэкэнд для ядерных интерфейсов drm, как это сделано в fbi. В современном ядре это похоже поддерживается гораздо лучше. И, кстати, там поддерживается настоящее переключение видеорежимов.

Deleted
()
Ответ на: удаленный комментарий

Так разве разработчики там что-то не поняли? Они же и пишут, что по их мнению это проблема конкретного окружения, а не библиотеки. И что надо разбираться именно с окружением, а с библиотекой всё в порядке. Потому и закрыли с таким статусом.

saahriktu ★★★★★
() автор топика

saahriktu, можешь помочь? Я создавал баг, но моего английского не хватило, чтобы грамотно его описать. В итоге, его закрыли как Invalid.

Давай мысленно перенесёмся в 2007. Есть 32-битные дистрибутивы Linux, и там в /usr/lib находятся 32-битные либы. А в 64-битных есть нюанс в зависимости от того, на RPM ли пакетах базируется дистр, или на DEB

В Debian и Ubuntu:
/usr/lib32 и /usr/lib
В Fedora Core и openSUSE:
/usr/lib и /usr/lib64
Два разных подхода! В Ubuntu в /usr/lib лежат 64-битные либы, а в Fedora Code в /usr/lib лежат 32-битные!

./configure от SDL это нормально обрабатывает, когда ищет все зависимости: ALSA, ESD, arts, x11. Затем в SDL 1.2 добавили поддержку PulseAudio, и для этой либы не всё работает корректно. Эта библиотека отлично обнаруживается, если в /usr/lib лежат 64-битные либы. А если там 32-битные либы (а система 64-битная) то... тоже отлично обнаруживается, но есть нюанс

./configure всё-таки обнаруживает libpulse, но линкуется с этой либой не при помощи dlopen(), а как обычно... Вот беру я CentOS 6. Теперь, если скомпилировать libSDL без неё, то ldd выглядит так:

	linux-vdso.so.1 (0x00007fff571fe000)
	libm.so.6 => /lib64/libm.so.6 (0x00007fd76e2a6000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fd76e0a1000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd76de85000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fd76dad8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd76e873000)

А если с ней:

        linux-vdso.so.1 =>  (0x00007ffff2990000)
        libm.so.6 => /lib64/libm.so.6 (0x00002b5419bd9000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00002b5419e5c000)
        libpulse-simple.so.0 => /usr/lib64/libpulse-simple.so.0 (0x00002b541a061000)
        libpulse.so.0 => /usr/lib64/libpulse.so.0 (0x00002b541a26e000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b541a4bc000)
        libc.so.6 => /lib64/libc.so.6 (0x00002b541a6d9000)
        /lib64/ld-linux-x86-64.so.2 (0x00000031d0e00000)
        libcap.so.1 => /lib64/libcap.so.1 (0x00002b541aa32000)
        librt.so.1 => /lib64/librt.so.1 (0x00002b541ac36000)
        libSM.so.6 => /usr/lib64/libSM.so.6 (0x00002b541ae40000)
        libICE.so.6 => /usr/lib64/libICE.so.6 (0x00002b541b04a000)
        libX11.so.6 => /usr/lib64/libX11.so.6 (0x00002b541b265000)
        libXau.so.6 => /usr/lib64/libXau.so.6 (0x00002b541b572000)
        libXdmcp.so.6 => /usr/lib64/libXdmcp.so.6 (0x00002b541b774000)

strings libSDL-1.2.so.0 | grep lib даёт понять, что изменилось совсем мало:

libm.so.6
libdl.so.2
libpthread.so.0
libc.so.6
libSDL-1.2.so.0
libasound.so.2
libartsc.so.0
libesd.so.0
libpulse-simple.so.0  !!! New dependency
libX11.so.6
libXext.so.6
libXrender.so.1
libXrandr.so.2
libGL.so.1

Таким образом, libpulse становится комбо-брейкером, ломающим всю динамическую линковку! Причина - в том, что Icculus (один из разработчиков SDL) добавлял поддержку «Пульсы» в поздние 00-е. Icculus в 2005 перешёл со Slackware на Ubuntu. А все остальные зависимости были добавлены в годы, когда Red Hat был популярнее Ubuntu, и поэтому 64-битные зависимости обрабатывались корректно на нём.

Я проверил: в 64-битном CentOS зашёл в /usr/lib (там 32-битные либы) и сделал симлинки libpulse.so и libpulse-simple.so на 64-битные. И тогда вывод ./configure изменился:

Было:

...
-- dynamic libasound -> libasound.so.2
checking for artsc-config... /usr/bin/artsc-config
checking for aRts development environment... yes
-- dynamic libartsc -> libartsc.so.0
checking for esd-config... /usr/bin/esd-config
checking for ESD - version >= 0.2.8... yes
-- dynamic libesd -> libesd.so.0
checking for pkg-config... /usr/bin/pkg-config
checking for PulseAudio 0.9 support... yes
checking audio/audiolib.h usability... no
...

Стало:

...
-- dynamic libasound -> libasound.so.2
checking for artsc-config... /usr/bin/artsc-config
checking for aRts development environment... yes
-- dynamic libartsc -> libartsc.so.0
checking for esd-config... /usr/bin/esd-config
checking for ESD - version >= 0.2.8... yes
-- dynamic libesd -> libesd.so.0
checking for pkg-config... /usr/bin/pkg-config
checking for PulseAudio 0.9 support... yes
-- dynamic libpulse-simple -> libpulse-simple.so.0
checking audio/audiolib.h usability... no
...

Получился бинарник, в котором libpulse тоже стал подгружаться при помощи dlopen()

Можешь посмотреть, и по возможности исправить? Ссылку на страницу бага я давал выше...

ZenitharChampion ★★★★★
()
Последнее исправление: ZenitharChampion (всего исправлений: 2)
Ответ на: комментарий от saahriktu

Я переписал своё сообщение более понятно.

Это не проблема окружения - это проблема «Ubuntu стал популярнее Red Hat». Когда Icculus в поздние 00-е добавлял поддержку libpulse, он считал, что эта библиотека лежит только в /usr/lib, и нигде иначе. В /usr/lib64 она лежать не может (но в итоге всё равно обнаруживается - просто не хочет линковаться при помощи dlopen()). А вот например зависимость libesd добавляли в годы, когда Red Hat был популярнее Ubuntu. Благодаря этому, в CentOS 6 эта зависимость обнаруживается ./configure-ом нормально

ZenitharChampion ★★★★★
()
Последнее исправление: ZenitharChampion (всего исправлений: 1)
Ответ на: комментарий от Deleted

Посмотрел. С первым же патчем всё заработало с оригинальной SDL1. Второй патч только сдвинул картинку из центра к левому краю.

saahriktu ★★★★★
() автор топика
Ответ на: комментарий от saahriktu

Второй патч только сдвинул картинку из центра к левому краю.

А попробуй сделать так:

fbset >/etc/fb.modes

Deleted
()
Ответ на: комментарий от Deleted

Да, команда «fbset > /etc/fb.modes» вернула картинку в центр экрана, а восстановление старого /etc/fb.modes опять сдвинуло её к левому краю.

Вот новый /etc/fb.modes:

# cat /etc/fb.modes

mode "1920x1080"
    geometry 1920 1080 1920 1080 32
    timings 0 0 0 0 0 0 0
    accel true
    rgba 8/16,8/8,8/0,0/0
endmode

#

saahriktu ★★★★★
() автор топика

ChangeLog-4.20.4 / 4.19.17 / 4.14.95 / 4.9.152

Author: Ivan Mironov <mironov.ivan@gmail.com>
Date:   Tue Jan 8 12:23:53 2019 +0500

    drm/fb-helper: Ignore the value of fb_var_screeninfo.pixclock
    commit 66a8d5bfb518f9f12d47e1d2dce1732279f9451e upstream.
    Strict requirement of pixclock to be zero breaks support of SDL 1.2
    ...
Неужели починили )

arson ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.