Текущая страница: ГлавнаяРазное → Видеокарта Nvidia в Ubuntu - эксперименты с драйверами

Видеокарта Nvidia в Ubuntu — эксперименты с драйверами

Как-то, после очередного обновления и перезагрузки я лишился драйвера видеокарты, на домашнем ноуте обновляюсь я нерегулярно, перегружаюсь еще реже, так что в какой именно момент и в результате какого обновления драйвера приказали долго жить — не знаю.
По факту проблем оказалось несколько — во-первых не определялся внешний монитор, во-вторых проблема с драйверами nvidia, в третьих проблема с dkms. В процессе восстановления было получено много новых интересных ошибок, борьба с которыми заняла в сумме несколько часов. Здесь я изложу некоторые решения полученные в результате этого.
Смотрим, что за видеокарта у нас установлена:

lspci -k | egrep 'VGA|3D' -A2

В моем случае видим 2 видеокарты — Intel и Ndidia

00:02.0 VGA compatible controller: Intel Corporation 3rd Gen Core processor Graphics Controller (rev 09)
Subsystem: ASUSTeK Computer Inc. Device 10ac
Kernel driver in use: i915
--
01:00.0 VGA compatible controller: NVIDIA Corporation GF119M [GeForce 610M] (rev a1)
Subsystem: ASUSTeK Computer Inc. GeForce GT 610M

Это означает, что мы имеем дело с технологией NVIDIA Optimus.
Сразу обращаем внимание на строку
Kernel driver in use: i915
при этом для драйвера nvidia аналогичной строки нет.
Это означает, что драйвер nvidia не загрузился.
Работаем с модулями ядра - в данном случае с модулями драйверов nvidia.
Смотрим, что вообще из драйверов относящихся к nvidia у нас в системе доступно:

modprobe -l | egrep '(nvidia|nouveau)'

Видим:

kernel/drivers/video/nvidia/nvidiafb.ko
kernel/drivers/gpu/drm/nouveau/nouveau.ko
kernel/drivers/net/ethernet/nvidia/forcedeth.ko
updates/dkms/nvidia.ko
updates/dkms/nvidia-uvm.ko

nvidia*.ko - проприетарные драйвера nvidia
nouveau.ko - Свободный драйвер nvidia
Смотрим какие драйвера загружены.

lsmod | egrep '(nvidia|nouveau)'

Видим только nouveau
Смотрим более детальную информацию по драйверам

modinfo nvidia

Видим, версия 304.123
Загружаем драйвер:

modprobe -i -v nvidia

Ругается...загружаеться не хочет, смотрим подробности в логе командой dmesg
Видим:

Unknown symbol acpi_os_wait_events_complete (err 0)

Пробуем другой драйвер:

modprobe -i -v nvidiafb

Загружается нормально, смотрим лог dmesg

[ 8103.157377] nvidiafb: Device ID: 10de1058 
[ 8103.157380] nvidiafb: unknown NV_ARCH

Проверяем его в списке загруженных модулей:

lsmod | grep nvidiafb

Видим, что он там есть...Выгружаем модуль

modprobe -r nvidiafb

или так

rmmod nvidiafb

Хорошо конечно, но хотелось бы проприетарный драйвер....
Вариант первый - ставим драйвера из пакета Ubuntu
Ставим драйвера из пакета:

aptitude install nvidia-304-updates

При этом происходит следующее...
Исходники драйверов загрузятся сюда (у вас последние цифры могут отличаться): /usr/src/nvidia-304-updates-304-116
Как видно из сообщений которые появляются при установке, исходники конфигурируются, компилируются, запускается DKMS и прописывает модуль в автозагрузку
Проверяем грузится ли модуль драйвера.
Если по прежнему выдает аналогичную ошибку - патчим файл nv-acpi.c
Пересобираем и устанавливаем пропатченный модуль:

dpkg-reconfigure nvidia-304-updates
Запрещаем его update:
aptitude nvidia-304-updates hold

Как и зачем патчить nv-acpi.c?
В недрах интернета я откопал для какой-то из версий Linux такой патч:

--- a/kernel/nv-acpi.c
+++ b/kernel/nv-acpi.c
@@ -15,6 +15,10 @@
#include "nv-linux.h"
#include "nv-reg.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) && defined(ACPI_HANDLE)
+#define DEVICE_ACPI_HANDLE(a) ACPI_HANDLE(a)
+#endif
+
#if defined(NV_LINUX_ACPI_EVENTS_SUPPORTED)
static int         nv_acpi_add             (struct acpi_device *);
@@ -299,7 +299,10 @@ static int nv_acpi_remove(struct acpi_de
     if (pNvAcpiObject->notify_handler_installed)
     {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+ /* beginning with 3.13, acpi_remove_notify_handler() waits for events to finish */
         NV_ACPI_OS_WAIT_EVENTS_COMPLETE();
+#endif
         // remove event notifier
         status = acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, nv_acpi_event);

Что из него видно? После директив

 #include "nv-linux.h"
 #include "nv-reg.h"

Добавляется это:

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) && defined(ACPI_HANDLE)
#define DEVICE_ACPI_HANDLE(a) ACPI_HANDLE(a)
#endif

Перед вызовом acpi_remove_notify_handler добавляется это:

#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
/* beginning with 3.13, acpi_remove_notify_handler() waits for events to finish */
NV_ACPI_OS_WAIT_EVENTS_COMPLETE();
#endif

Таким образом видно, что проблема появляется начиная с ядер 3.13.0 и по идее решается этим патчем. Не спешите патчить - дочитайте статью до конца! Как выяснилось не все так хорошо...
Вариант второй - ставим драйвера с официального сайта
Идем на сайт nvidia
Cмотрим страницу UNIX драйверы.
Смотрим разрядность и архитектуру своей системы выполнив uname -m.
Архитектура (в моем случае) - Linux x86/IA32
Видим на сайте:
Последняя версия для существующих GPU (304.xx series)
Версия: 304.1230 Опубликовано: 2014.7.10
Скачиваем файл NVIDIA-Linux-x86-304-123.run
Ставим драйвер:
Для начала блокируем загрузку всевозможных драйверов nvidia, которые нам не нужны

sudo gedit /etc/modprobe.d/blacklist.conf
Добавляем:
blacklist vga16fb
blacklist nouveau
blacklist rivafb
blacklist nvidiafb
blacklist rivatv

Замечание: при установке драйверов с использованием DKMS, драйвера будут загружаться до чтения системой данного списка, поэтому запретить загрузку nouveau таким образом не получится. Если драйвер nvidia не сможет загрузиться - загрузится nouveau
Выключаем X сервер:

service lightdm stop

Переключитесь на консоль командой Ctrl-Alt-F1 и войдите в систему под обычным пользователем
Запускаем установщик nvidia:

sudo chmod +x  NVIDIA-Linux-x86-304-123
sudo sh  ./NVIDIA-Linux-x86-304-123

Опции запуска установщика nvidia

sudo sh ./NVIDIA-Linux-x86-304-123 --help
--update Соединяется с FTP и тянет последнюю версию драйвера:NVIDIA-Linux-x86-YYY
--dkms Установит драйвер используя DKMS
--extract-only Просто распакует данные, без установки
--disable-nouveau
--uninstall

Если надо пропатчить исходники делаем так:

./NVIDIA-Linux-x86-304-123 --extract-only

Распакуется в каталог NVIDIA-Linux-x86-304-123
Интересующий нас файл:

NVIDIA-Linux-x86-304-123/kernel/nv-acpi.c

Патчим и запускаем установщик:

NVIDIA-Linux-x86-304-123/nvidia-installer

Проверяем:

modinfo nvidia
Видим - Версия 304.123

Загружаем драйвер, если он еще на загружен:

modprobe -i -v nvidia

Загружается нормально, смотрим лог dmesg

[11682.449830] [drm] Initialized nvidia-drm 0.0.0 20130102 for 0000:01:00.0 on minor 1
[11682.449841] NVRM: loading NVIDIA UNIX x86 Kernel Module  304.123  Tue Aug  5 20:09:46 PDT 2014

Стартуем иксы:

service lightdm start

Замечание:
Скачанный на офф. сайте драйвер при попытке загрузки тоже выдавал ошибку - пришлось патчить и его.
Замечание:
Достаточно часто выгрузить драйвер на лету с помощью rmmod и rmmod -f не получается - выдается сообщение что он уже используется. Перезагружайтесь.
Замечание:
Для конфигурирования X-сервера попробуйте nvidia-xconfig. Но вообще она должна запускаться автоматически при установке драйверов и сама создавать конфиг.
Важное амечание:
При первой установке драйверов nvidia инсталлер попытался выгрузить nouveau, тот забился в предсмертной агонии, засрал всю консоль паническими воплями, потом к нему присоединился kworker...в общем пришлось сделать reset
После этого система загрузилась в режиме failsafe, драйвера nvidia вроде бы стояли и вроде бы работали, но как-то не так....видимо что-то не доустановилось.
Пришлось заходить в консоль, убивать иксы и переустанавливать драйвера nvidia.
Если не хотете искать в процессах иксы, выберете в меню которое вылезает сразу после загрузки иксов в failsafe пункт exit to console (точно название не помню, но exit и console там были точно)
На этот раз драйвера nouveau уже не было, установка прошла успешно и после перезагрузки все заработало. Нормальный вид окна nvidia-settings стал таким:
nvidia-settings-2
Однако спустя 5-6 минут после перезагрузки пошли баги - изображение на экране шло с артефактами, окно обновлялись не полностью и так далее...
В целом это лечится переключением Ctrl-Alt-F1 и обратно по Alt-F7, но как-то это не нормально....
Попробовал поставить свежий драйвер - NVIDIA-Linux-x86-342-22.run
Провел при установке все вышеперечисленные манипуляции включая патч драйвера - картина такая же.
Зависания изображения и возможность рисовать на экране мышкой белыми квадратиками происходили буквально с периодом в 3-4 минуты...
Насторожило, что после перезагрузки через некоторое время произошел сбой в программе
xserver-xorg-lts-saucy
Начинаем игрища с Xorg.....
Далее делаю Ctrl-Alt-F1 переключаясь в терминал.
(на всякий случай напоминаю - выход из терминала обратно в графический режим - Alt-F7)
Меняю конфиг...потом
sudo service ligthdm restart
и все начинается с начала...
В конечном итоге пакеты xserver-xorg-XXX-saucy сносятся и ставятся последние из доступных
xserver-xorg-XXX-trusty
После чего на всякий случай перегрузился...Сидим без глюков уже 20-ю минуту...пока полет нормальный....
Скриншоты nvidia-settings:
nvidia-settings-3
nvidia-settings-4
Пойдем дальше...
В результате для 2 видеокарт загружено 2 рабочих драйвера, один из которых, условно рабочий драйвер nvidia
Как выяснить какая видеокарта активная и как их переключать?
Начиная с ядра 2.6.34 есть модуль vga_switcheroo.

sudo cat /sys/kernel/debug/vgaswitcheroo/switch

Получаем что-то вроде этого:

0:IGD:+:Pwr:0000:00:02.0
1:DIS: :DynPwr:0000:01:00.0

Вспоминая вывод lspci в начале статьи видим, что:
00:02.0 - видеокарта Intel - активная, включена - питание подается.
01:00.0 - видеокарта Nvidia - не активная, включена - питание подается при необходимости.
DIS — дискретная видеокарта
IGD — интегрированная видеокарта
Доступные операции:

sudo echo команда > /sys/kernel/debug/vgaswitcheroo/switch

DIS -немедленное переключение на дискретную видеокарту
DDIS -отложенное переключение на дискретную видеокарту
IGD -немедленное переключение на интегрированную видеокарту
DIGD -отложенное переключение на интегрированную видеокарту
ON -включить неиспользуемую видеокарту
OFF -выключить неиспользуемую видеокарту
Замечание:
Немедленное переключение не сработало.
Отложенное переключение произошло после выхода из системы - если после этого экран потух -перегрузитесь, видимо драйвер nvidia активировался и заработал как-то криво....
Технология NVIDIA Optimus.
Есть 3 пути практического использования этой технологии.
1. Bumblebee
Позволяет запускать приложения с использованием дискретной видеокарты.
2. nvidia-prime
Пакет nvidia-prime предоставляющий официальную поддержку технологии Nvidia Optimus от Ubuntu.
3. PRIME
Неофициальный пакет, позволяющий запускать приложения с использованием дискретной видеокарты.

Фактически все 3 пакета предоставляют механизмы переключения видеокарт и НЕ СОВМЕСТИМЫ между собой.

Смотрим какие пакеты у нас стоят в системе:

dpkg -l | egrep '(nvidia|bumblebee)'

Замечание:
Драйвер поставленный из исходников с официального сайта в списке пакетов нигде не фигурирует - это не пакет ))))
Рассмотрим второй вариант nvidia-prime
На всякий случай перед продолжением экспериментов я все снес:

sudo apt-get purge 'nvidia*'
sudo apt-get purge 'bumblebee*'
sudo apt-get --purge autoremove

Замечание:
Будьте аккуратны с purge - при этом удаляются и конфиги пакетов, так, если вы патчили исходники видеодрайвера установленного из пакета - все это будет удалено )))
Попутно удалится и ubuntu-desktop. Его можно поставить отдельно.

apt-get install ubuntu-desktop

При этом зависимостью он потянет пакет nvidia-common и xorg....
Устанавливаем nvidia-settings:

apt-get install nvidia-settings

Запустим, и посмотрим что это за зверь такой....

sudo nvidia-settings

Как все выглядит - показано на скриншотах выше.
Видим сообщения

** (nvidia-settings:6598): WARNING **: PRIME: Не удалось выполнить процесс-потомок «/usr/bin/prime-supported» (Нет такого файла или каталога)
** Message: PRIME: is it supported? no

Ставим nvidia-prime:

sudo apt-get install nvidia-prime

Замечание:
Смотрите за сообщения при установке пакета - если этот пакет видит, что в системе нет пакетов с драйверами nvidia, он тянет за собой драйвер nouveau, запускает конфигурирование DKMS и при перезагрузке проприетарный драйвер собранный из исходников скачанных с сайта может быть подменен на nouveau.
Запускаем nvidia-settings и видим что появилась возможность переключать видеокарты.
Пробуем переключить и видим эпическую картину...

epic-fail-1
Отмечу, что этот скриншот был сделан хронологически чуть ранее, чем скриншоты выше, однако картина ошибки одинаковая. Такое ощущение, что разработчик хотел описать какую-то ОЧЕНЬ ВАЖНУЮ ОШИБКУ и даже влепил для нее иконку известную автолюбителям как знак Кирпич, но потом отвлекся на легкий перекус и вернувшись забыл что делал, занявшись другими делами.....
Вообще приличные программы так себя не ведут - они честно пишут в чем ошибка, дают ее код и описание, а в случае дебага описывают каждый свой чих давая возможность найти баг...
Первая мысль - может быть тут торчат уши какой-нибудь левой программы, вроде SELinux или apparmor, которые как Zorro выскакивают из-за угла, блокируют что-нибудь и молча скрываются в системных прериях, хотя даже они должны были бы пискнуть в лог.....
В любом случае проверка не выявила этой блокировки, но переключение видеокарт на лету не срабатывает, напомню что модулю vga_switcheroo это тоже не удалось, хотя отложенное переключение срабатывало....по крайней мере пыталось.
Пытаемся разрешить проблему....

aptitude install nvidia-settings-331 nvidia-updates-331

После чего переключение видеокарт в утилите nvidia-settings стало работать нормально.
nvidia-settings-5
nvidia-settings-6
Переключение заработало, но на скриншоте видим рабочую версию драйвера 331.38.....
При перезагрузке систему раскорячило, пришлось ставить последнюю версию драйверов с сайта и патчить, поскольку так просто они не встали. Перезагрузка прошла успешно и мы вернулись к нашим баранам, хотя стало безусловно получше - дефекты в отрисовке экрана и артефакты стали проявляться изредка. Похоже улучшение - заслуга пакетов xserver-xorg-XXX-trusty....
Попробую обновить систему до 14.01 LTS, пора уже видимо ))
Потом установка последней версии драйвера, на этот раз из репозитария:

sudo apt-add-repository ppa:xorg-edgers/ppa
sudo apt-get update
sudo apt-get install nvidia-XXX nvidia-settings-XXX
sudo apt-add-repository -r ppa:xorg-edgers/ppa

Добавить комментарий