Подключение монитора в OpenWrt

Displaylink в OpenWrt

Подключать монитор будем, используя USB видео-адаптер displaylink. Текущая версия OpenWrt не имеет полноценной поддержки для displaylink, поэтому могут возникать трудности на различных этапах, которые мы попытаемся преодолеть.

Перед тем, как начать, хочу дать одну ссылку, которая мне помогла. Возможно, в следующих версиях OpenWrt она уже будет не так актуальна, но на данный момент, склонировав репозитарий отсюда http://projects.qi-hardware.com/index.php/p/openwrt-packages/, можно получить очень много дополнительных приложений для OpenWrt. Для добавления нового приложения в состав OpenWrt просто скопируйте его в директорию OpenWrt/package, и при следующем запуске make menuconfig оно уже будет в составе пакета.

Ладно, начнем. Я не знаю, как грамотно изложить информацию, чтобы это было понятно всем. Попытаюсь рассказать основные моменты.

В линуксе работа с видео-изображением осуществляется с помощью фрэйм-буфера (frame buffer). Что это такое, очень толково написано в документации на опцию CONFIG_FB в ядре Linux.

Для того, чтобы устройство displaylink могло работать с фрейм-буфером, нам нужно включить поддержку этой опции в самом ядре (FB_UDL).

Для того, чтобы мы смогли увидеть что-то на экране, нужно включить в ядре поддержку виртуально консоли. Что это такое, опять же можно почитать в Help для опции CONFIG_VT. Также должна быть поддержка консоли на виртуальном терминале и опционально поддержка возможности binding and unbinding console drivers.

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

Теперь всё это резюмируем конкретными опциями ядра. Выполняем команду «make kernel_menuconfig»
Device Drivers:
USB Support:
<*> Support for Host-side USB
Graphics support:
<*> Support for frame buffer devices:
<*> Enable firmware EDID
<*> Framebuffer foreign endianness support
<*> Enable Video Mode Handling Helpers
<*> Enable Tile Blitting Support
Staging drivers:
<*> Displaylink USB Framebuffer support
Character devices:
<*> Virtual terminal
<*> Enable character translations in console
<*> Support for console on virtual terminal
<*> Support for binding and unbinding console drivers
Graphics support:
Bootup logo:
<*> Standard 224-color Linux logo
Console display driver support:
<*> Framebuffer Console support
<*> Map the console to the primary display device
<*> Framebuffer Console Rotation
<*> Select compiled-in fonts
<*> VGA 8x16 font

Собираем, прошиваем, запускаем.

Подключаем displaylink. В принципе, того, что мы сделали, должно хватить, и на экране монитора вы должны увидеть радующую глаз заставку с пингвином:

Но лично я увидел у себя на мониторе надпись «Out of range. Dvi digital. 53.5kHz/85Hz».

Давайте посмотрим вывод dmesg:

usb 1-1.4.2: dlfb: allocated 4 65024 byte urbs
usb 1-1.4.2: dlfb: Unable to get valid EDID from device/display
usb 1-1.4.2: dlfb: set_par mode 800x600
usb 1-1.4.2: dlfb: open /dev/fb0 user=0 fb_info=c1e8bc00 count=1
usb 1-1.4.2: dlfb: set_par mode 800x600
Console: switching to colour frame buffer device 100x37
usb 1-1.4.2: dlfb: set_par mode 800x600
usb 1-1.4.2: dlfb: DisplayLink USB device /dev/fb0 attached. 800x600 resolution. Using 1875K framebuffer memory

Теперь понятна причина. Насколько я понимаю, «Unable to get valid EDID from device/display » говорит о том, что не удалось получить какие-то данные, чтобы сконфигурировать адаптер под корректный режим работы монитора. И он выставил какой-то режим по умолчанию.

Выставим режим самостоятельно. Для этого есть утилита fbset. Эта утилита входит в состав busybox OpenWrt, но использовать её по назначению не удалось, поскольку она урезана. Поэтому скачиваем исходники fbset с официального сайта и собираем самостоятельно, не забывая, что нужно использовать кросс-компилятор при сборке.

Для запуска команды fbset нужен файл fb.modes. Можете скачать его с нашего сайта.

Итак, применяем команду:

root@OpenWrt:/# /home/fbset -fb /dev/fb0 -db /etc/fb.modes 800x600-75
usb 1-1.4.2: dlfb: open /dev/fb0 user=1 fb_info=c1da3000 count=2
usb 1-1.4.2: dlfb: set_par mode 800x600
usb 1-1.4.2: dlfb: release /dev/fb0 user=1 count=1

Поскольку клавиатуру мы уже подключили, то нажимаем кнопку ENTER. Должны увидеть примерно следующее:

За окном 2011 год, но у меня это событие всё равно вызвало счастливую улыбку на лице.

Запустим родной midnight commander.

Кто бы мог подумать, что так всё легко?

В качестве PS — нужно всегда использовать самые последние версии исходников ).

Обновился до последней версии OpenWrt, и проблема с ошибкой «Out of range» исчезла. Вывод dmesg теперь выглядит следующим образом:

usb 1-1.4.2: new full speed USB device using ohci_hcd and address 6
usb 1-1.4.2: not running at top speed; connect to a high speed hub
udlfb: DisplayLink SUNWEIT USB Display - serial #500457
udlfb: vid_17e9&pid_024c&rev_0003 driver's dlfb_data struct at 81a5c800
udlfb: console enable=1
udlfb: fb_defio enable=1
udlfb: vendor descriptor length:e0 data:00 00 00 0000 00 00 00 00 00 00
udlfb: Unrecognized vendor firmware descriptor
udlfb: allocated 4 65024 byte urbs
udlfb: Unable to get valid EDID from device/display
udlfb: 640x350 valid mode
udlfb: 640x400 valid mode
udlfb: 721x400 valid mode
udlfb: 640x480 valid mode
udlfb: 640x480 valid mode
udlfb: 640x480 valid mode
udlfb: 640x480 valid mode
udlfb: 800x600 valid mode
udlfb: 800x600 valid mode
udlfb: 800x600 valid mode
udlfb: 800x600 valid mode
udlfb: 800x600 valid mode
udlfb: 1024x768 valid mode
udlfb: 1024x768 valid mode
udlfb: 1024x768 valid mode
udlfb: 1024x768 valid mode
udlfb: 1024x768 valid mode
udlfb: 1152x864 valid mode
udlfb: 1280x960 valid mode
udlfb: 1280x960 valid mode
udlfb: 1280x1024 valid mode
udlfb: 1280x1024 valid mode
udlfb: 1280x1024 valid mode
udlfb: 1600x1200 valid mode
udlfb: 1600x1200 valid mode
udlfb: 1600x1200 valid mode
udlfb: 1600x1200 valid mode
udlfb: 1600x1200 valid mode
udlfb: 1792x1344 beyond chip capabilities
udlfb: 1792x1344 beyond chip capabilities
udlfb: 1856x1392 beyond chip capabilities
udlfb: 1856x1392 beyond chip capabilities
udlfb: 1920x1440 beyond chip capabilities
udlfb: 1920x1440 beyond chip capabilities
udlfb: Reallocating framebuffer. Addresses will change!
udlfb: 800x600 valid mode
udlfb: set_par mode 800x600
udlfb: open /dev/fb0 user=0 fb_info=80d93c00 count=1
udlfb: set_par mode 800x600
Console: switching to colour frame buffer device 100x37
udlfb: set_par mode 800x600
udlfb: DisplayLink USB device /dev/fb0 attached. 800x600 resolution. Using 1880K framebuffer memory

Информативность вывода гораздо увеличилась. Но проблема с «Unable to get valid EDID» так и не решена. Но, видимо, исправлена дефолтная конфигурация, которую получает адаптер в случае не обнаружения EDID.

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

Зеленый экран на мониторе при подключении displaylink означает, что адаптер корректно проинициализировался и опознался в системе. Осознав это, нужно тогда понять, почему же не запустилась консоль.

Давайте посмотрим следующую информацию.

Проверим наличие устройства fb в директоии /dev:

root@OpenWrt:/# ls /dev/fb*
/dev/fb0

Проверим, создалась ли виртуальная консоль фрэйм-буфера:

root@OpenWrt:/# ls /sys/class/vtconsole/vtcon*
/sys/class/vtconsole/vtcon0:
bind name subsystem uevent

/sys/class/vtconsole/vtcon1:
bind name subsystem uevent

Консоль создалась. Проверим, что она принадлежит именно фрэйм-буферу:

root@OpenWrt:/# cat /sys/class/vtconsole/vtcon1/name
(M) frame buffer device

Проверим, что она прибиндена:

root@OpenWrt:/# cat /sys/class/vtconsole/vtcon1/bind
1

И тут всё ок. Тогда откроем текстовый файл с описанием драйвера:
/trunk/build_dir/linux-brcm47xx/linux-2.6.37/drivers/staging/udlfb/udlfb.txt.

Следующие строки всё проясняют: «Allow fbcon to attach to udlfb provided framebuffers. This is disabled by default because fbcon will aggressively consume the first framebuffer it finds, which isn't usually what the user wants in the case of USB displays»

Пробуем применить решение, которое предложено:

root@OpenWrt:/# modprobe udlfb defio=1 console=1

Лично мне оно не помогло )). Может быть из-за того, что modprobe опять не полноценный. Поэтому легче открыть исходный файл udlfb.c и прямо в нём задать дефолтные значения для этих двух переменных:
/* module options */
static int console=1; /* Optionally allow fbcon to consume first framebuffer */
static int fb_defio=1; /* Optionally enable experimental fb_defio mmap support */

PPS: Тестирование быстродействия системы необходимо, конечно же, проводить не на mc. Запустив mc, система даже это не почувствовала.

USB2VGA Displaylink адаптер