--- description: 'FreeBSD обеспечивает двоичную совместимость с Linux, позволяя пользователям устанавливать и запускать большинство двоичных исполняемых файлов Linux в системе FreeBSD без необходимости предварительного изменения двоичного файла' next: books/handbook/wine params: path: /books/handbook/linuxemu/ part: 'Часть II. Стандартные задачи' prev: books/handbook/printing showBookMenu: 'true' tags: ["linux", "linuxulator", "emulation", "binary", "compatibility"] title: 'Глава 12. Двоичная совместимость с Linux' weight: 15 --- [[linuxemu]] = Двоичная совместимость с Linux :doctype: book :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :sectnumoffset: 12 :partnums: :source-highlighter: rouge :experimental: :images-path: books/handbook/linuxemu/ ifdef::env-beastie[] ifdef::backend-html5[] :imagesdir: ../../../../images/{images-path} endif::[] ifndef::book[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] toc::[] endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] toc::[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [[linuxemu-synopsis]] == Обзор FreeBSD предоставляет *опциональную* двоичную совместимость с Linux(R), часто называемую Linuxulator, что позволяет пользователям устанавливать и запускать неизменённые Linux-бинарники. Это доступно для архитектур x86 (как 32, так и 64 бит) и AArch64. Некоторые специфичные для Linux функции операционной системы пока не поддерживаются; в основном это касается функциональности, связанной с оборудованием или управлением системой, такой как cgroups или пространства имён. Прежде чем читать эту главу, необходимо: * Знать, как установить crossref:ports[ports,дополнительное стороннее программное обеспечение]. Прочтите эту главу, чтобы узнать: * Как включить двоичную совместимость с Linux в системе FreeBSD. * Как установить дополнительные общие библиотеки Linux. * Как установить Linux-приложения в системе FreeBSD. * Как реализована совместимость с Linux в FreeBSD. [[linuxemu-lbc-install]] == Настройка бинарной совместимости с Linux По умолчанию бинарная совместимость с man:linux[4] не включена. Чтобы включить ABI Linux при загрузке, выполните следующую команду: [.programlisting] .... # sysrc linux_enable="YES" .... После включения его можно запустить без перезагрузки, выполнив следующую команду: [source, shell] .... # service linux start .... Этого достаточно для работы статически связанных Linux-библиотек. Сервис Linux загрузит необходимые модули ядра и смонтирует файловые системы, ожидаемые Linux-приложениями, в [.filename]#/compat/linux#. Их можно запускать так же, как и родные FreeBSD-приложения; они ведут себя почти так же, как родные процессы, и их можно трассировать и отлаживать обычными способами. Текущее содержимое [.filename]#/compat/linux# можно проверить, выполнив следующую команду: [source, shell] .... # ls -l /compat/linux/ .... Вывод должен быть похож на следующий: [.programlisting] .... total 1 dr-xr-xr-x 13 root wheel 512 Apr 11 19:12 dev dr-xr-xr-x 1 root wheel 0 Apr 11 21:03 proc dr-xr-xr-x 1 root wheel 0 Apr 11 21:03 sys .... [[linux-userlands]] == Пользовательские окружения Linux Программное обеспечение Linux требует не только ABI для работы. Для запуска программ Linux необходимо сначала установить пользовательское пространство Linux. [TIP] ==== Если требуется только запустить какое-либо программное обеспечение, уже включённое в дерево портов, его можно установить через менеджер пакетов, и man:pkg[8] автоматически настроит необходимую пользовательскую среду Linux. Например, чтобы установить Sublime Text 4 вместе со всеми необходимыми библиотеками Linux, выполните следующую команду: [source, shell] .... # pkg install linux-sublime-text4 .... ==== [[linuxemu-rockylinux]] === Базовая система Rocky Linux из пакетов FreeBSD Для установки пользовательской среды Rocky Linux 9 выполните следующую команду: [source, shell] .... # pkg install linux_base-rl9 .... Пакет package:emulators/linux_base-rl9[] разместит базовую систему, основанную на Rocky Linux 9, в [.filename]#/compat/linux#. После установки пакета содержимое [.filename]#/compat/linux# можно проверить, выполнив следующую команду, чтобы убедиться, что пользовательская среда Rocky Linux установлена: [source, shell] .... # ls -l /compat/linux/ .... Вывод должен быть похож на следующий: [.programlisting] .... total 36 drwxr-xr-x 2 root wheel 512 Oct 9 17:28 afs lrwxr-xr-x 1 root wheel 7 May 16 2022 bin -> usr/bin drwxr-xr-x 3 root wheel 512 Oct 9 17:28 dev drwxr-xr-x 24 root wheel 1536 Oct 9 17:28 etc lrwxr-xr-x 1 root wheel 7 May 16 2022 lib -> usr/lib lrwxr-xr-x 1 root wheel 9 May 16 2022 lib64 -> usr/lib64 drwxr-xr-x 2 root wheel 512 Oct 9 17:28 opt drwxr-xr-x 2 root wheel 512 Oct 9 17:28 proc lrwxr-xr-x 1 root wheel 8 Oct 1 03:11 run -> /var/run lrwxr-xr-x 1 root wheel 8 May 16 2022 sbin -> usr/sbin drwxr-xr-x 2 root wheel 512 Oct 9 17:28 srv drwxr-xr-x 2 root wheel 512 Oct 9 17:28 sys drwxr-xr-x 8 root wheel 512 Oct 9 17:28 usr drwxr-xr-x 16 root wheel 512 Oct 9 17:28 var .... [[linuxemu-centos]] === Базовая система CentOS из пакетов FreeBSD [WARNING] ==== Пакет package:emulators/linux_base-c7[] устарел после прекращения поддержки вышестоящего проекта. Это означает, что package:emulators/linux_base-c7[] больше не будет получать обновления безопасности. Рекомендуется использовать crossref:linuxemu[linuxemu-rockylinux, базовую систему Rocky Linux], если не требуется совместимость с 32-битными системами. ==== Для установки пользовательской среды CentOS выполните следующую команду: [source, shell] .... # pkg install linux_base-c7 .... Пакет package:emulators/linux_base-c7[] разместит базовую систему, основанную на CentOS 7, в каталоге `[.filename]#/compat/linux#`. После установки пакета содержимое [.filename]#/compat/linux# можно проверить, выполнив следующую команду, чтобы убедиться, что пользовательская среда CentOS установлена: [source, shell] .... # ls -l /compat/linux/ .... Вывод должен быть похож на следующий: [.programlisting] .... total 30 lrwxr-xr-x 1 root wheel 7 Apr 11 2018 bin -> usr/bin drwxr-xr-x 13 root wheel 512 Apr 11 21:10 dev drwxr-xr-x 25 root wheel 64 Apr 11 21:10 etc lrwxr-xr-x 1 root wheel 7 Apr 11 2018 lib -> usr/lib lrwxr-xr-x 1 root wheel 9 Apr 11 2018 lib64 -> usr/lib64 drwxr-xr-x 2 root wheel 2 Apr 11 21:10 opt dr-xr-xr-x 1 root wheel 0 Apr 11 21:25 proc lrwxr-xr-x 1 root wheel 8 Feb 18 02:10 run -> /var/run lrwxr-xr-x 1 root wheel 8 Apr 11 2018 sbin -> usr/sbin drwxr-xr-x 2 root wheel 2 Apr 11 21:10 srv dr-xr-xr-x 1 root wheel 0 Apr 11 21:25 sys drwxr-xr-x 8 root wheel 9 Apr 11 21:10 usr drwxr-xr-x 16 root wheel 17 Apr 11 21:10 var .... [[linuxemu-debootstrap]] === Debian / Ubuntu Базовая система с debootstrap Альтернативный способ предоставления общих библиотек Linux — использование package:sysutils/debootstrap[]. Это имеет преимущество в виде предоставления полного дистрибутива Debian или Ubuntu. Чтобы установить debootstrap, выполните следующую команду: [source, shell] .... # pkg install debootstrap .... Для работы man:debootstrap[8] требуется включённый man:linux[4] ABI. После его активации выполните следующую команду для установки Ubuntu или Debian в [.filename]#/compat/ubuntu#: [source, shell] .... # debootstrap focal /compat/ubuntu .... [NOTE] ==== Хотя технически возможно установить в [.filename]#/compat/linux#, это не рекомендуется из-за возможных конфликтов с пакетами на основе CentOS. Вместо этого используйте имя каталога, производное от названия дистрибутива или версии, например, [.filename]#/compat/ubuntu#. ==== Вывод должен быть похож на следующий: [.programlisting] .... I: Retrieving InRelease I: Checking Release signature I: Valid Release signature (key id F6ECB3762474EDA9D21B7022871920D1991BC93C) I: Retrieving Packages I: Validating Packages I: Resolving dependencies of required packages... I: Resolving dependencies of base packages... I: Checking component main on http://archive.ubuntu.com/ubuntu... [...] I: Configuring console-setup... I: Configuring kbd... I: Configuring ubuntu-minimal... I: Configuring libc-bin... I: Configuring ca-certificates... I: Base system installed successfully. .... Затем настройте точки монтирования в [.filename]#/etc/fstab#. [TIP] ==== Если содержимое домашнего каталога должно быть общим и необходимо иметь возможность запускать приложения X11, [.filename]#/home# и [.filename]#/tmp# следует подключить в области совместимости linux с использованием man:nullfs[5] для loopback (обратной петли). Следующий пример можно добавить в [.filename]#/etc/fstab#: [.programlisting] .... # Device Mountpoint FStype Options Dump Pass# devfs /compat/ubuntu/dev devfs rw,late 0 0 tmpfs /compat/ubuntu/dev/shm tmpfs rw,late,size=1g,mode=1777 0 0 fdescfs /compat/ubuntu/dev/fd fdescfs rw,late,linrdlnk 0 0 linprocfs /compat/ubuntu/proc linprocfs rw,late 0 0 linsysfs /compat/ubuntu/sys linsysfs rw,late 0 0 /tmp /compat/ubuntu/tmp nullfs rw,late 0 0 /home /compat/ubuntu/home nullfs rw,late 0 0 .... Затем выполните man:mount[8]: [source, shell] .... # mount -al .... ==== Для доступа к системе с использованием man:chroot[8] выполните следующую команду: [source, shell] .... # chroot /compat/ubuntu /bin/bash .... Тогда можно выполнить man:uname[1], чтобы проверить окружение Linux: [source, shell] .... # uname -s -r -m .... Вывод должен быть похож на следующий: [.programlisting] .... Linux 5.15.0 x86_64 .... Оказавшись в chroot, система ведёт себя как при обычной установке Ubuntu. Хотя systemd не работает, команда man:service[8] функционирует в обычном режиме. [TIP] ==== Чтобы добавить отсутствующие репозитории пакетов по умолчанию, отредактируйте файл [.filename]#/compat/ubuntu/etc/apt/sources.list#. Для amd64 можно использовать следующий пример: [.programlisting] .... deb http://archive.ubuntu.com/ubuntu jammy main universe restricted multiverse deb http://security.ubuntu.com/ubuntu/ jammy-security universe multiverse restricted main deb http://archive.ubuntu.com/ubuntu jammy-backports universe multiverse restricted main deb http://archive.ubuntu.com/ubuntu jammy-updates universe multiverse restricted main .... Для arm64 можно использовать следующий пример: [.programlisting] .... deb http://ports.ubuntu.com/ubuntu-ports bionic main universe restricted multiverse .... ==== [[linuxemu-advanced]] == Сложные темы Список всех параметров man:sysctl[8], связанных с Linux, можно найти в man:linux[4]. Некоторые приложения требуют подключения определённых файловых систем. Обычно это обрабатывается скриптом [.filename]#/etc/rc.d/linux#, но можно отключить при загрузке, выполнив следующую команду: [.programlisting] .... sysrc linux_mounts_enable="NO" .... Файловые системы, смонтированные скриптом rc, не будут работать для Linux-процессов внутри chroot или клетки. При необходимости настройте их в [.filename]#/etc/fstab#: [.programlisting] .... devfs /compat/linux/dev devfs rw,late 0 0 tmpfs /compat/linux/dev/shm tmpfs rw,late,size=1g,mode=1777 0 0 fdescfs /compat/linux/dev/fd fdescfs rw,late,linrdlnk 0 0 linprocfs /compat/linux/proc linprocfs rw,late 0 0 linsysfs /compat/linux/sys linsysfs rw,late 0 0 .... Поскольку уровень двоичной совместимости с Linux получил поддержку выполнения как 32-, так и 64-битных бинарных файлов Linux, стало невозможно статически линковать функциональность эмуляции в пользовательское ядро. [[linuxemu-libs-manually]] === Установка дополнительных библиотек вручную [NOTE] ==== Для подкаталогов базовой системы, созданных с помощью man:debootstrap[8], используйте приведённые выше инструкции. ==== Если приложение Linux жалуется на отсутствие общих библиотек после настройки совместимости с двоичными файлами Linux, определите, какие общие библиотеки нужны двоичному файлу Linux, и установите их вручную. С системы Linux с той же архитектурой CPU можно использовать `ldd` для определения того, какие разделяемые библиотеки необходимы приложению. Например, чтобы проверить, какие разделяемые библиотеки требуются для `linuxdoom`, выполните следующую команду в системе Linux, где установлен Doom: [source, shell] .... % ldd linuxdoom .... Вывод должен быть похож на следующий: [.programlisting] .... libXt.so.3 (DLL Jump 3.1) => /usr/X11/lib/libXt.so.3.1.0 libX11.so.3 (DLL Jump 3.1) => /usr/X11/lib/libX11.so.3.1.0 libc.so.4 (DLL Jump 4.5pl26) => /lib/libc.so.4.6.29 .... Затем скопируйте все файлы из последнего столбца вывода с системы Linux в [.filename]#/compat/linux# на системе FreeBSD. После копирования создайте символические ссылки на имена из первого столбца. Этот пример приведёт к следующим файлам в системе FreeBSD: [.programlisting] .... /compat/linux/usr/X11/lib/libXt.so.3.1.0 /compat/linux/usr/X11/lib/libXt.so.3 -> libXt.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3.1.0 /compat/linux/usr/X11/lib/libX11.so.3 -> libX11.so.3.1.0 /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29 .... Если уже существует общая библиотека Linux с соответствующим номером старшей версии (первый столбец вывода `ldd`), её не нужно копировать в файл, указанный в последнем столбце, так как существующая библиотека должна работать. Однако рекомендуется скопировать общую библиотеку, если она является более новой версией. Старую версию можно удалить, при условии что символическая ссылка указывает на новую. Например, эти библиотеки уже существуют в системе FreeBSD: [.programlisting] .... /compat/linux/lib/libc.so.4.6.27 /compat/linux/lib/libc.so.4 -> libc.so.4.6.27 .... и `ldd` показывает, что для бинарного файла требуется более новая версия: [.programlisting] .... libc.so.4 (DLL Jump 4.5pl26) -> libc.so.4.6.29 .... Поскольку существующая библиотека устарела всего на одну или две версии в последней цифре, программа должна по-прежнему работать с немного более старой версией. Однако можно безопасно заменить существующий [.filename]#libc.so# на более новую версию: [.programlisting] .... /compat/linux/lib/libc.so.4.6.29 /compat/linux/lib/libc.so.4 -> libc.so.4.6.29 .... Как правило, необходимость искать разделяемые библиотеки, от которых зависят Linux-бинарники, возникает только в первые несколько раз при установке Linux-программ на FreeBSD. Через некоторое время в системе накопится достаточный набор разделяемых библиотек Linux, что позволит запускать вновь устанавливаемые Linux-бинарники без дополнительных усилий. === Маркировка ELF-бинарников Linux Ядро FreeBSD использует несколько методов для определения, является ли запускаемый двоичный файл Linux-программой: оно проверяет бренд в заголовке ELF-файла, ищет известные пути к ELF-интерпретаторам и проверяет ELF-заметки; наконец, по умолчанию небрендированные ELF-исполняемые файлы в любом случае считаются Linux-программами. Если все эти методы не сработают, попытка выполнить двоичный файл может привести к сообщению об ошибке: [source, shell] .... % ./my-linux-elf-binary .... Вывод должен быть похож на следующий: [.programlisting] .... ELF binary type not known Abort .... Чтобы помочь ядру FreeBSD отличить ELF-программу FreeBSD от Linux-программы, используйте man:brandelf[1]: [source, shell] .... % brandelf -t Linux my-linux-elf-binary .... === Установка приложения на основе Linux RPM Для установки приложения на основе RPM в Linux сначала установите пакет package:archivers/rpm4[] или порт. После установки пользователь `root` может использовать следующую команду для установки файла [.filename]#.rpm#: [source, shell] .... # cd /compat/linux # rpm2cpio < /path/to/linux.archive.rpm | cpio -id .... При необходимости выполните `brandelf` для установленных ELF-бинарников. Заметим, что это сделает невозможной чистую деинсталляцию. === Настройка преобразователя имён хостов Если DNS не работает или появляется эта ошибка: [.programlisting] .... resolv+: "bind" is an invalid keyword resolv+: "hosts" is an invalid keyword .... Настройте файл [.filename]#/compat/linux/etc/host.conf# следующим образом: [.programlisting] .... order hosts, bind multi on .... Это указывает, что сначала выполняется поиск в [.filename]#/etc/hosts#, а затем в DNS. Если [.filename]#/compat/linux/etc/host.conf# отсутствует, Linux-приложения используют [.filename]#/etc/host.conf# основной системы, но выдают ошибку, так как этот файл отсутствует в FreeBSD. Удалите `bind`, если сервер имён не настроен в [.filename]#/etc/resolv.conf#. [[linuxemu-misc]] === Разное Дополнительная информация о работе двоичной совместимости с Linux(R) доступна в статье link:{linux-emulation}[Эмуляция Linux в FreeBSD].