- Регистрация
- 23 Август 2023
- Сообщения
- 3 016
- Лучшие ответы
- 0
- Реакции
- 0
- Баллы
- 51
Offline
		
		
	В модульных Linux дистрибутивах, таких как Puppy/Slax/Porteus, корневая файловая система собирается из многих слоев с помощью aufs либо overlayfs. Слои представляют из себя squashfs файлы, смонтированные через loopback.
Проприетарные драйвера NVIDIA для Linux по умолчанию не предполагают возможности соседства нескольких версий в одной файловой системе в классических дистрибутивах. Но эта проблема может быть легко решена в модульных дистрибутивах путем создания отдельных squashfs модулей с разными версиями NVIDIA драйверов.
PocketHandyBox компактный портативный Linux дистрибутив на базе Debian (и Devuan) с поддержкой NVIDIA "из коробки", предназначенный для тестирования, обслуживания ПК, ноутбуков.
В PocketHandyBox squashfs модули с драйверами NVIDIA находятся в папке live/nvidia. При этом модули для ядра Linux выделены в отдельные squashfs файлы. Файлы с расширением .kmodsfs содержат в названии uname -r (kernel release) ядра для которого они собраны.
Определение видеокарты по PCI ID и загрузка модуля с соответствующей версией драйвера реализована в initrd в скрипте linuxrc. Используются только команды из состава busybox.
# Detect nvidia video cards on pcie bus
if [ "$NVIDIA" = detect ]; then
echo "${i}detecting nvidia GPU"
nvlist=`lspci | grep -i "030.: 10de:" | cut -d":" -f4`
if [ -n "$nvlist" ]; then
for nv in $nvlist
do
echo "${i}$nv chip found, checking which nvidia driver supports it"
if grep -sqi 10de$nv /usr/share/nvidia/nvidia.ids; then NVIDIA=nvidia; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvopen.ids; then NVIDIA=nvopen; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvidia-tesla-470.ids; then NVIDIA=nv470; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvidia-legacy-390xx.ids; then NVIDIA=nv390; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvidia-legacy-340xx.ids; then NVIDIA=nv340; break
else echo "${i}$nv chip is not supported by nvidia driver"
fi
done
else echo "${i}could not find any nVidia GPU on this PC"
fi
fi
# Find nvidia modules
if [ "$NVIDIA" ] && [ "$NVIDIA" != detect ]; then
echo "${i}$NVIDIA NVIDIA driver will be activated"
find $DATADIR/nvidia -name "$NVIDIA*.kmodsfs" 2>/dev/null | grep $KERNEL >>/tmp/modules
find $DATADIR/nvidia -name "$NVIDIA*.squashfs" 2>/dev/null | grep -v gsp | egrep -ve "$NOLOAD" >>/tmp/modules
[ "$NVIDIA" = nvopen ] && find $DATADIR/nvidia -name "nvidia*.squashfs" 2>/dev/null | egrep -ve "$NOLOAD" >>/tmp/modules
NOLOAD="$NOLOAD|mesa-vulkan-drivers"
fi
В системе установлен пакет nvidia-detect который в /usr/share/nvidia/ содержит текстовые файлы .ids со списками PCI ID видеокарт, поддерживаемых определенной версией драйвера. При создании initrd1.xz для каждого ядра Linux скрипт mkinitrd копирует их внутрь cpio архива.
В загрузчиках по умолчанию прописан cmdline nvidia=detect. При загрузке если в выводе lspci есть видеокарты NVIDIA - последовательно производится поиск найденных PCI ID в файлах .ids из /usr/share/nvidia/. Если совпадение найдено то переменной NVIDIA присваивается значение с префиксом для поиска модулей соответствующей версии драйвера.
Имена найденных файлов модулей .squashfs и .kmodsfs добавляются в файл /tmp/modules. Далее при вызове функции IncludeModules они будут смонтированы в /memory/images/ и затем в overlayfs.
В конце, когда новый корень собран - linuxrc передает управление /usr/sbin/init либо systemd. Происходит штатный запуск сервисов, в том числе udev. При этом подхватываются настройки из /etc/modprobe.d и /etc/modules-load.d (в том числе blacklist nouveau) которые содержатся в подключенных squashfs модулях.
Таким образом получаем рабочий драйвер NVIDIA сразу после запуска и без дополнительных манипуляций.
	
	
		
		
	
	
		
			
		
		 
	
GTX 1070
Дополнительная сложность добавилась с выходом NVIDIA драйвера для RTX 5000 серии. Дело в том что Blackwell не поддерживается классическими закрытыми модулями ядра. При этом перейти полностью на открытые модули тоже нельзя так как они не поддерживают Maxwell и Pascal.
Поэтому в PocketHandyBox собраны оба варианта модулей ядра. Во избежание дублирования squashfs модули с userspace библиотеками и утилитами у них общие. А также сформированы два списка nvidia.ids (все начиная с Maxwell и не включая Blackwell) и nvopen.ids (все начиная с Turing, включая Blackwell). Доработана логика в linuxrc. При выборе nvopen - загружаются и nvidia*.squashfs модули, в том числе squashfs с файлами GSP прошивок.
	
	
		
		
	
	
		
			
		
		 
	
RTX 5050
Спасибо за внимание!
Если интересно то в следующих статьях могу рассказать как в PocketHandyBox реализовано переключение на дискретную NVIDIA карту для современных драйверов, которые поддерживают PRIME render offload и для legacy версий 340.xx и 390.xx, в которых эта поддержка отсутствует.
								Проприетарные драйвера NVIDIA для Linux по умолчанию не предполагают возможности соседства нескольких версий в одной файловой системе в классических дистрибутивах. Но эта проблема может быть легко решена в модульных дистрибутивах путем создания отдельных squashfs модулей с разными версиями NVIDIA драйверов.
PocketHandyBox компактный портативный Linux дистрибутив на базе Debian (и Devuan) с поддержкой NVIDIA "из коробки", предназначенный для тестирования, обслуживания ПК, ноутбуков.
В PocketHandyBox squashfs модули с драйверами NVIDIA находятся в папке live/nvidia. При этом модули для ядра Linux выделены в отдельные squashfs файлы. Файлы с расширением .kmodsfs содержат в названии uname -r (kernel release) ядра для которого они собраны.
Определение видеокарты по PCI ID и загрузка модуля с соответствующей версией драйвера реализована в initrd в скрипте linuxrc. Используются только команды из состава busybox.
# Detect nvidia video cards on pcie bus
if [ "$NVIDIA" = detect ]; then
echo "${i}detecting nvidia GPU"
nvlist=`lspci | grep -i "030.: 10de:" | cut -d":" -f4`
if [ -n "$nvlist" ]; then
for nv in $nvlist
do
echo "${i}$nv chip found, checking which nvidia driver supports it"
if grep -sqi 10de$nv /usr/share/nvidia/nvidia.ids; then NVIDIA=nvidia; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvopen.ids; then NVIDIA=nvopen; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvidia-tesla-470.ids; then NVIDIA=nv470; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvidia-legacy-390xx.ids; then NVIDIA=nv390; break
elif grep -sqi 10de$nv /usr/share/nvidia/nvidia-legacy-340xx.ids; then NVIDIA=nv340; break
else echo "${i}$nv chip is not supported by nvidia driver"
fi
done
else echo "${i}could not find any nVidia GPU on this PC"
fi
fi
# Find nvidia modules
if [ "$NVIDIA" ] && [ "$NVIDIA" != detect ]; then
echo "${i}$NVIDIA NVIDIA driver will be activated"
find $DATADIR/nvidia -name "$NVIDIA*.kmodsfs" 2>/dev/null | grep $KERNEL >>/tmp/modules
find $DATADIR/nvidia -name "$NVIDIA*.squashfs" 2>/dev/null | grep -v gsp | egrep -ve "$NOLOAD" >>/tmp/modules
[ "$NVIDIA" = nvopen ] && find $DATADIR/nvidia -name "nvidia*.squashfs" 2>/dev/null | egrep -ve "$NOLOAD" >>/tmp/modules
NOLOAD="$NOLOAD|mesa-vulkan-drivers"
fi
В системе установлен пакет nvidia-detect который в /usr/share/nvidia/ содержит текстовые файлы .ids со списками PCI ID видеокарт, поддерживаемых определенной версией драйвера. При создании initrd1.xz для каждого ядра Linux скрипт mkinitrd копирует их внутрь cpio архива.
В загрузчиках по умолчанию прописан cmdline nvidia=detect. При загрузке если в выводе lspci есть видеокарты NVIDIA - последовательно производится поиск найденных PCI ID в файлах .ids из /usr/share/nvidia/. Если совпадение найдено то переменной NVIDIA присваивается значение с префиксом для поиска модулей соответствующей версии драйвера.
Имена найденных файлов модулей .squashfs и .kmodsfs добавляются в файл /tmp/modules. Далее при вызове функции IncludeModules они будут смонтированы в /memory/images/ и затем в overlayfs.
В конце, когда новый корень собран - linuxrc передает управление /usr/sbin/init либо systemd. Происходит штатный запуск сервисов, в том числе udev. При этом подхватываются настройки из /etc/modprobe.d и /etc/modules-load.d (в том числе blacklist nouveau) которые содержатся в подключенных squashfs модулях.
Таким образом получаем рабочий драйвер NVIDIA сразу после запуска и без дополнительных манипуляций.
 
	GTX 1070
Дополнительная сложность добавилась с выходом NVIDIA драйвера для RTX 5000 серии. Дело в том что Blackwell не поддерживается классическими закрытыми модулями ядра. При этом перейти полностью на открытые модули тоже нельзя так как они не поддерживают Maxwell и Pascal.
Поэтому в PocketHandyBox собраны оба варианта модулей ядра. Во избежание дублирования squashfs модули с userspace библиотеками и утилитами у них общие. А также сформированы два списка nvidia.ids (все начиная с Maxwell и не включая Blackwell) и nvopen.ids (все начиная с Turing, включая Blackwell). Доработана логика в linuxrc. При выборе nvopen - загружаются и nvidia*.squashfs модули, в том числе squashfs с файлами GSP прошивок.
 
	RTX 5050
Спасибо за внимание!
Если интересно то в следующих статьях могу рассказать как в PocketHandyBox реализовано переключение на дискретную NVIDIA карту для современных драйверов, которые поддерживают PRIME render offload и для legacy версий 340.xx и 390.xx, в которых эта поддержка отсутствует.
 
				 
       
      

 
		
	