Це повністю залежить від того, які послуги ви хочете мати на своєму пристрої.
Програми
Ви можете зробити завантаження 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. На додаток до 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
каталог , якщо ви хочете використовувати псевдо-термінали (тобто будь-який термінал, окрім консолі) - наприклад, якщо пристрій підключений до мережі та ви хочете передати телнет або ssh в
random
(повертає випадкові байти, ризикує блокувати)
tty
(завжди позначає термінал програми)
urandom
(повертає випадкові байти, ніколи не блокується, але може бути невипадковим на щойно завантаженому пристрої)
zero
(містить нескінченну послідовність нульових байтів)
Крім цього вам знадобляться записи для вашого обладнання (крім мережевих інтерфейсів, вони не отримують записи /dev
): послідовних портів, сховища тощо.
Для вбудованих пристроїв зазвичай можна створювати записи пристрою безпосередньо в кореневій файловій системі. Системи високого класу мають сценарій, який викликається MAKEDEV
для створення /dev
записів, але у вбудованій системі сценарій часто не вбудовується в зображення. Якщо деяке обладнання може бути підключено гарячою підключенням (наприклад, якщо у пристрою є хост-порт USB), то ним /dev
слід керувати udev (у вас все одно можливий мінімальний набір у кореневій файловій системі).
Дії під час завантаження
Крім кореневої файлової системи, для нормальної роботи потрібно встановити ще кілька:
- profs on
/proc
(досить незамінний)
- sysfs on
/sys
(майже незамінний)
tmpfs
увімкнено файлову систему /tmp
(щоб дозволити програмам створювати тимчасові файли, які будуть знаходитися в оперативній пам'яті, а не в кореневій файловій системі, яка може бути в режимі flash або лише для читання)
- tmpfs, devfs або devtmpfs увімкнено,
/dev
якщо вони динамічні (див. udev у " Файлах пристроїв" вище)
- devpts on,
/dev/pts
якщо ви хочете використовувати [псевдотермінали (див. зауваження про pts
вище)
Ви можете зробити /etc/fstab
файл і зателефонувати mount -a
або запустити mount
вручну.
Запустіть демон- syslog (як і klogd
для журналів ядра, якщо syslogd
програма не піклується про нього), якщо у вас є куди писати журнали.
Після цього пристрій готовий запустити послуги, що стосуються додатків.
Як зробити кореневу файлову систему
Це довга і різноманітна історія, тому все, що я тут роблю, - це дати кілька покажчиків.
Коренева файлова система може зберігатися в оперативній пам’яті (завантажується з (зазвичай стисненого) зображення в ПЗУ або спалаху), або в файловій системі на основі диска (зберігається в ПЗУ або флеш), або завантажується з мережі (часто через TFTP ), якщо це застосовується . Якщо коренева файлова система знаходиться в оперативній пам'яті, зробіть її initramfs - файловою системою ОЗУ, вміст якої створюється під час завантаження.
Існує багато фреймворків для складання кореневих зображень для вбудованих систем. У FAQ щодо BusyBox є кілька покажчиків . Buildroot - популярний, що дозволяє будувати ціле зображення кореня із налаштуваннями, подібними до ядра Linux та BusyBox. OpenEmbedded - це ще одна така структура.
У Вікіпедії є (неповний) список популярних вбудованих дистрибутивів Linux . Прикладом вбудованого Linux, який ви можете мати поруч, є сімейство операційних систем OpenWrt для мережевих приладів (популярне на домашніх маршрутизаторах tinkerers). Якщо ви хочете дізнатися на досвіді, ви можете спробувати Linux від Scratch , але він орієнтований на настільні системи для любителів, а не на вбудовані пристрої.
Примітка про ядро Linux проти Linux
Єдине поведінка, яке вкладається в ядро Linux, - це те, що перша програма, яка запускається під час завантаження. (Тут я не вникатиму в тонкощі initrd та initramfs .) Ця програма, яку традиційно називають init , має ID 1 процесу та має певні привілеї (несприйнятливість до сигналів KILL ) та обов'язки (пожинання сиріт ). Ви можете запустити систему з ядром Linux і почати все, що ви хочете, як перший процес, але тоді у вас є операційна система, заснована на ядрі Linux, а не те, що зазвичай називається "Linux" - Linux , у загальному розумінні терміна - це операційна система, схожа на Unix , ядром якої є ядро Linux. Наприклад, Android - це операційна система, яка не схожа на Unix, але заснована на ядрі Linux.