Как создать собственный дистрибутив Linux, который запускает только одну программу и ничего больше?

12

Как я мог создать свой собственный «пользовательский» дистрибутив Linux, который будет запускать только одну программу, почти так же, как XBMCbuntu .

user3462992
источник
Добро пожаловать на U & L, пожалуйста, совершите экскурсию и найдите время, чтобы узнать, как задать вопрос, что вы хотите сделать? потому что определение приложения довольно расплывчато и совсем ничего не значит, потому что мой совет будет использовать, busyboxно это, вероятно, не то, что вы хотите. поэтому, пожалуйста, уделите необходимое время, чтобы высказать свои пожелания, и мы сможем вам помочь. Не стесняйтесь редактировать свой вопрос, чтобы добавить любой соответствующий элемент в нем.
Kiwy
1
Мне кажется довольно ясным ...
Златовласка
@ TAFKA'goldilocks 'ну, нет, потому что, держу пари, у вас все еще может быть доступ к терминалу или чему-то подобному в XBMCubuntu, хотя кажется, что графически работает только одно приложение, но работает не только одно. Я создал небольшой дистрибутив с нуля только с ядром и busybox, в этом случае, даже если есть службы, запускаемые ядром, вы можете сказать, что busybox - ваше единственное приложение.
Kiwy
@Kiwi Это хороший ответ (лучше, чем LFS). Имейте в виду: 1) Этот вопрос может быть полезен для других людей, чьи общие цели одинаковы, поэтому диапазон ответов хорош, 2) Хотя здесь есть ряд возможных решений - например, TIMTOWTDI - и некоторые могут быть лучше подходит для какой-то более конкретной цели, чем другие, я уверен, что все они будут работать, и значительный аспект принятия решения будет субъективным (например, из-за предшествующего знания и опыта ОП, а не объективного характера задачи) ,
Златовласка

Ответы:

6

Я бы не стал возиться с LFS, это садовая дорожка, ведущая к темному лесу.

Начните с дистрибутива, где у вас есть большой контроль над первоначальной установкой, такой как Arch, или безголовый выпуск, такой как сервер Ubuntu. Смысл этого не столько в экономии места, сколько в том, чтобы ограничить сложность конфигурации init; начиная с безголового дистрибутива, если приложение, которое вы хотите запустить, требует графического интерфейса, вы можете добавить то, что для этого требуется, без необходимости входа в систему с графическим интерфейсом пользователя (он же диспетчера отображения или DM), запускаемого init, и полнофункционального рабочего стола среда, чтобы пойти с этим.

Затем вы захотите узнать, как настроить систему init для ваших целей - обратите внимание, что вы не можете обойтись без init, и это может быть лучшим средством для достижения вашей цели. Существует три варианта init, обычно используемых в linux (но есть и другие ):

  • Debian использует вариант классического инициала Unix SysV . На момент jessieвыпуска Debian также переключился на systemd( https://wiki.debian.org/systemd )

  • Ubuntu и его производные используют upstart .

  • Fedora, Arch и производные используют systemd .

Если вы еще ничего не знаете ни о одном из них, ни один из них не является особенно сложным в использовании, чем любой другой. Если вы пойдете с одним из последних двух, они предоставляют некоторые механизмы для обратной совместимости с SysV, но не беспокойтесь об этом , это НЕ немного проще. 1

Суть в том, чтобы минимизировать то, что init делает при загрузке, и именно так вы можете создать систему, которая будет запускать минимальное количество программного обеспечения для поддержки приложения, на котором вы хотите сосредоточиться - это, по сути, то, как настроен сервер, Кстати, это обычная задача (обратите внимание, что вы не можете буквально запустить «только один» пользовательский процесс, по крайней мере, бесполезно).

Если приложение, которое вы хотите запустить, является программой с графическим интерфейсом (хороший пример того, почему вы не можете буквально просто запустить одно приложение, поскольку приложения с графическим интерфейсом требуют X-сервер), вы можете иметь такой ~/.xinitrcвид;

#!/bin/sh

myprogram

Когда вы потом startx, ваша программа будет единственной запущенной, и будет невозможно изменить рабочие столы или запустить что-то еще, частично потому, что нет оконного менеджера или рабочего стола (следовательно, не будет ни оконной рамки, ни заголовка окна).

1. Чтобы немного пояснить суть: когда вы исследуете это, вы можете найти некоторые жалобы на systemd и upstart от людей, которые ранее были знакомы с SysV, утверждая, например, что они слишком сложные. Однако объективно они не более сложны, чем SysV (IMO systemd на самом деле проще в использовании), но большинство собак, так сказать, предпочитают свои старые приемы. Этот захват начинает ослабевать, теперь обе системы уже некоторое время используются.

лютик золотистый
источник
1
Вы не можете обойтись без , initно , конечно , вы можете обойтись без upstart, systemd,или sysv. initпросто какой - то исполняемый файл с именем , initчто ваше ядро вызывает , когда он подключает initramfs.В большинстве случаев эти другие три не даже , initно они на самом деле execэд в на init,который обычноbusybox.
mikeserv
@mikeserv Абсолютно (и я прямо упомянул, что это не единственные три варианта). Обратите внимание также, что я намеренно исключен, busyboxпотому что это заслуживает отдельного рассмотрения в отдельном ответе, но не мной.
Златовласка
Как мило с вашей стороны предложить! Но, черт возьми, нет.
mikeserv
Было бы интересно узнать, работает ли этот подход на практике. Кто-нибудь на самом деле пробовал это?
Фахим Митха
@FaheemMitha Если вы имеете в виду то, что я рекомендую здесь (настроить конфигурацию init), конечно, это так - вот как система уже работает, вы просто создадите урезанную и упрощенную версию (я уверен, что это что такое XBMCbutu). Если вы имеете в виду, заменяя init на более специализированный исполняемый файл ala busybox, это, вероятно, больше проблем, чем стоит, если вы не должны делать это таким образом - главное назначение busybox - использование в крошечных встроенных средах (например, с несколькими МБ ОЗУ).
Златовласка
18

Минимальная начальная программа Hello World, шаг за шагом

введите описание изображения здесь

Скомпилируйте привет мир без каких-либо зависимостей, который заканчивается бесконечным циклом. init.S:

.global _start
_start:
    mov $1, %rax
    mov $1, %rdi
    mov $message, %rsi
    mov $message_len, %rdx
    syscall
    jmp .
    message: .ascii "FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n"
    .equ message_len, . - message

Мы не можем использовать системный вызов exit, иначе ядро ​​паникует.

Затем:

mkdir d
as --64 -o init.o init.S # assemble
ld -o d/init init.o      # link
cd d
find . | cpio -o -H newc | gzip > ../rootfs.cpio.gz
ROOTFS_PATH="$(pwd)/../rootfs.cpio.gz"

Это создает файловую систему с нашим hello world at /init, которая является первой пользовательской программой, которую будет запускать ядро. Мы могли бы также добавить больше файлов, d/и они были бы доступны из /initпрограммы при запуске ядра.

Затем cdв дерево ядра Linux, сборка, как обычно, и запустить его в QEMU:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
git checkout v4.9
make mrproper
make defconfig
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd "$ROOTFS_PATH"

И вы должны увидеть строку:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

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

Вы также можете использовать программы на C, если статически связываете их:

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
    sleep(0xFFFFFFFF);
    return 0;
}

с:

gcc -static init.c -o init

Динамическое связывание потребовало бы установки исполняемого файла динамического компоновщика, наиболее распространенные из которых являются частью стандартных библиотек C, таких как glibc.

Вы можете работать на реальном оборудовании с включенным USB /dev/sdXи:

make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX

Отличный источник на эту тему: Технический совет: Как использовать initramfs | landley.net Также объясняется, как использовать gen_initramfs_list.shэтот скрипт из дерева исходного кода ядра Linux, чтобы помочь автоматизировать процесс.

Протестировано на Ubuntu 16.10, QEMU 2.6.1.

Следующие шаги

Следующее, что вы хотите сделать, это настроить BusyBox .

BusyBox реализует базовые утилиты POSIX-y CLI, в том числе оболочку POSIX-y, с помощью которой вы можете более легко экспериментировать с системой в интерактивном режиме.

Лично на данный момент я предпочитаю просто полагаться на Buildroot , который представляет собой удивительный набор скриптов, который автоматизирует сборку всего из исходного кода и создание корневой файловой системы.

Я загрузил очень подробный и автоматический помощник для этого по адресу: https://github.com/cirosantilli/linux-kernel-module-cheat

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
источник
4
Это, наверное, самый недооцененный ответ здесь: D. Потрясающие!
MST
1
@ теперь немного меньше :-)
Чиро Сантилли 冠状 病毒 审查 六四 事件 法轮功
1

если вы немного занимаетесь программированием и хотите создать его с нуля, вы можете использовать LFS, то есть Linux с нуля, http://www.linuxfromscratch.org/

если вы хотите настроить ubutnu, вы можете использовать ubunt-builder, и если вы хотите использовать его на базе rpm, вы можете использовать SUsE-Studio, Suse studio позволит вам сделать собственный suse linux.

ура

Зверь безопасности
источник
1

Это больше о том, что требует ваша «одна программа».

Вы все еще можете хорошо начать понимать, как собрать все воедино, создав LFS (« Linux From Scratch ») . Затем вы добавите вещи, необходимые для вашей программы, или пойдете на полный дистрибутив, потому что создание тяжелой подсистемы, такой как Gnome или KDE на LFS, может быть настоящей болью в заднице.

Конечно, поначалу может быть проще вернуться назад, но удаление вещей из полного дистрибутива может быть проблематичным: делайте это на ВМ и копируйте эту ВМ на каждом шагу.

(мои 2 цента)

Редактировать :

Как указывает SecurityBeast, вместо того, чтобы начинать с полного дистрибутива, такого как CentOS или Ubuntu , вы также можете взглянуть на создание инструментов распространения, таких как:

Ouki
источник
1

Вам нужно спросить, что нужно вашей «единой программе» и какие ресурсы у вас есть.

Если вам нужен широкий выбор библиотек и вспомогательных двоичных файлов, вам лучше всего использовать «обычный» дистрибутив linux (Debian или аналогичный) и просто немного поиграться с процессом загрузки.

Если ему требуется более узкий набор вспомогательных средств, но все же требуются такие вещи, как работа в сети или поддержка разнообразного оборудования, использующего различные модули ядра или биты поддержки пользовательского пространства, и вы не хотите, чтобы дисковое пространство занимало обычные дистрибутивы, тогда я бы посоветовал взглянуть на встроенные дистрибутивы (buildroot или аналогичные) или, возможно, Linux с нуля (хотя это может быть головной болью при обслуживании)

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

plugwash
источник