Это вопрос о приложениях пользовательского пространства, но выслушайте меня!
Для загрузки функционального дистрибутива Linux необходимы, так сказать, три «приложения»:
Bootloader - для встраиваемых систем обычно это U-Boot, хотя это и не является жестким требованием
Ядро - это довольно просто.
Корневая файловая система - без нее загрузка невозможна. Содержит файловую систему, в которую загружается ядро, и где
init
она называется form.
Мой вопрос касается № 3. Если кто-то хотел создать крайне минимальный rootfs (для этого вопроса, скажем, без графического интерфейса, только оболочка), какие файлы / программы требуются для загрузки в оболочку?
linux
embedded
startup
architecture
root-filesystem
MDMoore313
источник
источник
Ответы:
Это полностью зависит от того, какие услуги вы хотите иметь на своем устройстве.
программы
Вы можете заставить Linux загружаться прямо в оболочку . Это не очень полезно в производстве - кому бы просто хотелось, чтобы там была оболочка - но это полезно в качестве механизма вмешательства, когда у вас есть интерактивный загрузчик: переход
init=/bin/sh
к командной строке ядра. Все системы Linux (и все системы Unix) имеют оболочку в стиле Bourne / POSIX/bin/sh
.Вам понадобится набор утилит оболочки . BusyBox - очень распространенный выбор; она содержит оболочку и общие утилиты для файла и обработки текста (
cp
,grep
, ...), сетевые настройки (ping
,ifconfig
, ...), манипуляции с процессом (ps
,nice
, ...), а также различные другие инструменты системы (fdisk
,mount
,syslogd
...). BusyBox является чрезвычайно настраиваемым: вы можете выбрать, какие инструменты вы хотите, и даже отдельные функции во время компиляции, чтобы получить правильный размер / компромисс функциональности для вашего приложения. Помимоsh
, голый минимум , который вы не можете сделать ничего не естьmount
,umount
иhalt
, но было бы нетипичной не имеют такжеcat
,cp
,mv
,rm
,mkdir
,rmdir
,ps
,sync
И еще несколько. BusyBox устанавливается как один двоичный файлbusybox
с символической ссылкой для каждой утилиты.Первый процесс в нормальной системе Unix называется
init
. Его работа - запускать другие сервисы. BusyBox содержит систему инициализации. В дополнение кinit
двоичному/sbin
файлу (обычно расположенному в ) вам понадобятся его конфигурационные файлы (обычно называемые/etc/inittab
- некоторые современные замены init покончили с этим файлом, но вы не найдете их в небольшой встроенной системе), которые указывают, какие службы нужно запускать и когда. Для BusyBox/etc/inittab
необязательно; если он отсутствует, вы получаете корневую оболочку на консоли и скрипт/etc/init.d/rcS
(расположение по умолчанию) выполняется во время загрузки.Это все, что вам нужно, кроме программ, которые заставляют ваше устройство делать что-то полезное. Например, на моем домашнем маршрутизаторе, использующем вариант OpenWrt , единственными программами являются BusyBox
nvram
(для чтения и изменения настроек в NVRAM) и сетевые утилиты.Если все ваши исполняемые файлы статически не связаны, вам потребуется динамический загрузчик (
ld.so
который может вызываться разными именами в зависимости от выбора libc и архитектуры процессора) и все динамические библиотеки (/lib/lib*.so
возможно, некоторые из них/usr/lib
), необходимые для эти исполняемые файлы.Структура каталогов
Filesystem Hierarchy Standard описывает общую структуру каталогов системы Linux. Он ориентирован на установку на настольных компьютерах и серверах: многие из них могут быть опущены во встроенной системе. Вот типичный минимум.
/bin
: исполняемые программы (некоторые могут быть/usr/bin
вместо)./dev
: узлы устройства (см. ниже)/etc
: файлы конфигурации/lib
: общие библиотеки, включая динамический загрузчик (если все исполняемые файлы статически не связаны)/proc
: точка монтирования для файловой системы proc/sbin
: исполняемые программы. Различие с тем/bin
, что/sbin
это для программ, которые полезны только для системного администратора, но это различие не имеет смысла на встроенных устройствах. Вы можете сделать/sbin
символическую ссылку на/bin
./mnt
: удобно иметь в корневых файловых системах только для чтения в качестве точки монтирования во время обслуживания/sys
: точка монтирования для файловой системы sysfs/tmp
: расположение для временных файлов (частоtmpfs
монтирование)/usr
: Содержит подкаталогиbin
,lib
иsbin
./usr
существует для дополнительных файлов, которые не находятся в корневой файловой системе. Если у вас его нет, вы можете сделать/usr
символическую ссылку на корневой каталог.Файлы устройства
Вот несколько типичных записей в минимуме
/dev
:console
full
(запись в него всегда сообщает «на устройстве не осталось места»)log
(сокет, который программы используют для отправки записей журнала), если у вас естьsyslogd
демон (например, BusyBox), читающий из негоnull
(действует как файл, который всегда пуст)ptmx
иpts
каталог , если вы хотите использовать псевдо-терминалы (то есть любой терминал, отличный от консоли) - например, если устройство подключено к сети, и вы хотите подключиться через telnet или sshrandom
(возвращает случайные байты, блокирует риски)tty
(всегда обозначает терминал программы)urandom
(возвращает случайные байты, никогда не блокирует, но может быть неслучайным на недавно загруженном устройстве)zero
(содержит бесконечную последовательность нулевых байтов)Помимо этого вам понадобятся записи для вашего оборудования (кроме сетевых интерфейсов, в которые они не попадают
/dev
): последовательные порты, хранилище и т. Д.Для встроенных устройств вы обычно создаете записи устройства непосредственно в корневой файловой системе. В высокопроизводительных системах есть сценарий, который вызывается
MAKEDEV
для создания/dev
записей, но во встроенной системе этот сценарий часто не входит в образ. Если какое-либо оборудование может быть подключено в горячем режиме (например, если устройство имеет хост-порт USB), тогда им/dev
должно управлять udev (у вас может быть минимальный набор в корневой файловой системе).Действия при загрузке
Помимо корневой файловой системы, вам нужно смонтировать еще несколько для нормальной работы:
/proc
(в значительной степени незаменимый)/sys
(в значительной степени незаменимый)tmpfs
файловая система включена/tmp
(чтобы позволить программам создавать временные файлы, которые будут в ОЗУ, а не в корневой файловой системе, которая может быть во флэш-памяти или только для чтения)/dev
если они динамические (см. udev в разделе «Файлы устройств» выше)/dev/pts
если вы хотите использовать [псевдо-терминалы (см. замечаниеpts
выше)Вы можете сделать
/etc/fstab
файл и позвонитьmount -a
, или запуститьmount
вручную.Запустите демон syslog (а также
klogd
для журналов ядра, еслиsyslogd
программа об этом не позаботится), если у вас есть место для записи журналов.После этого устройство готово к запуску специфичных для приложения сервисов.
Как сделать корневую файловую систему
Это длинная и разнообразная история, поэтому все, что я здесь сделаю, - это несколько советов.
Корневая файловая система может храниться в ОЗУ (загружаться из (обычно сжатого) образа в ПЗУ или флэш-памяти) или в файловой системе на диске (храниться в ПЗУ или во флэш-памяти) или загружаться из сети (часто через TFTP ), если применимо , Если корневая файловая система находится в ОЗУ, сделайте ее initramfs - файловой системой ОЗУ, содержимое которой создается во время загрузки.
Существует множество платформ для сборки корневых образов для встроенных систем. В FAQ BusyBox есть несколько указателей . Buildroot является популярным, позволяя вам создать целый корневой образ с настройкой, аналогичной ядру Linux и BusyBox. OpenEmbedded - еще один такой фреймворк.
В Википедии есть (неполный) список популярных дистрибутивов встроенного Linux . Примером встроенного Linux, который вы можете иметь рядом с вами, является семейство операционных систем OpenWrt для сетевых устройств (популярное на домашних маршрутизаторах тинкеров). Если вы хотите учиться на собственном опыте, вы можете попробовать Linux с нуля , но он ориентирован на настольных систем для любителей, а не на встраиваемые устройства.
Примечание по Linux против ядра Linux
Единственное поведение, которое запекается в ядре Linux, заключается в том, что первая программа запускается во время загрузки. (Я не буду вдаваться в тонкости initrd и initramfs .) Эта программа, традиционно называемая init , имеет идентификатор процесса 1 и имеет определенные привилегии (невосприимчивость к сигналам KILL ) и обязанности (пожинает сирот ). Вы можете запустить систему с ядром Linux и запустить все, что захотите, в качестве первого процесса, но тогда у вас будет операционная система, основанная на ядре Linux, а не то, что обычно называется «Linux» - Linux , в обычном смысле слова термина, Unix- подобная операционная система, ядро которой является ядром Linux, Например, Android - это операционная система, которая не похожа на Unix, но основана на ядре Linux.
источник
Все, что вам нужно, это один статически связанный исполняемый файл, размещенный в файловой системе изолированно. Вам не нужны никакие другие файлы. Этот исполняемый файл является процессом init. Это может быть busybox. Это дает вам оболочку и множество других утилит, все само по себе. Вы можете перейти к полностью работающей системе, просто выполнив команды вручную в busybox, чтобы смонтировать корневую файловую систему для чтения-записи, создания узлов / dev, exec real init и т. Д.
источник
Если вам не нужны никакие утилиты оболочки,
mksh
подойдет статически связанный двоичный файл (например, для klibc - 130K в Linux / i386). Вам нужен сценарий/linuxrc
or/init
или,/sbin/init
который просто вызываетmksh -l -T!/dev/tty1
цикл:Эта
-T!$tty
опция является недавним дополнением,mksh
которое говорит ей, чтобы она вызывала новую оболочку на данном терминале и ждала его. (До этого был только-T-
в dæmonise программка и-T$tty
на икру на терминал , но не ждать. Это было не так красиво) . В-l
опции просто говорит ему , чтобы запустить оболочку входа в систему (которая читает/etc/profile
,~/.profile
а~/.mkshrc
).Это предполагает, что ваш терминал является
/dev/tty1
заменой. (С большей магией, терминал может быть автоматически обнаружен./dev/console
Не даст вам полный контроль над работой.)Вам нужно несколько файлов
/dev
для этого:Загрузка с опцией ядра
devtmpfs.mount=1
устраняет необходимость в заполненном/dev
, просто пусть это будет пустой каталог (подходящий для использования в качестве точки монтирования).Вы обычно захотите иметь некоторые утилиты (из klibc, busybox, beastiebox, toybox или toolbox), но они на самом деле не нужны.
Возможно, вы захотите добавить
~/.mkshrc
файл, который устанавливает $ PS1 и некоторые базовые псевдонимы и функции оболочки.Однажды я сделал initrd сжатый 171K (371K несжатый) для Linux / m68k, используя только mksh (и его пример файла mkshrc) и klibc-utils. (Это было до того, как -T! Был добавлен в оболочку, однако,
/dev/tty2
вместо этого он вызвал оболочку входа в систему и вывел на консоль сообщение, сообщающее пользователю о необходимости переключения терминалов.) Он работает нормально.Это действительно минимальная настройка. Другие ответы дают отличный совет относительно более функциональных систем. Это настоящая особая вещь.
Отказ от ответственности: я разработчик MKSH.
источник
mksh
.Минимальная начальная программа Hello World, шаг за шагом
Скомпилируйте привет мир без каких-либо зависимостей, который заканчивается бесконечным циклом.
init.S
:Мы не можем использовать
sys_exit
, иначе ядро паникует.Потом:
Это создает файловую систему с нашим hello world at
/init
, которая является первой пользовательской программой, которую будет запускать ядро. Мы могли бы также добавить больше файлов,d/
и они были бы доступны из/init
программы при запуске ядра.Затем
cd
в дерево ядра Linux, сборка, как обычно, и запустить его в QEMU:И вы должны увидеть строку:
на экране эмулятора! Обратите внимание, что это не последняя строка, поэтому вам нужно посмотреть немного дальше.
Вы также можете использовать программы на C, если статически связываете их:
с:
Вы можете работать на реальном оборудовании с включенным USB
/dev/sdX
и:Отличный источник на эту тему: http://landley.net/writing/rootfs-howto.html Также объясняется, как использовать
gen_initramfs_list.sh
, это скрипт из дерева исходных текстов ядра Linux, помогающий автоматизировать процесс.Следующий шаг: настройте BusyBox, чтобы вы могли взаимодействовать с системой: https://github.com/cirosantilli/runlinux
Протестировано на Ubuntu 16.10, QEMU 2.6.1.
источник