Jak stworzyć niestandardową dystrybucję Linuksa, która uruchamia tylko jeden program i nic więcej?


12

Jak mogłem stworzyć własną „niestandardową” dystrybucję Linuksa, która będzie uruchamiała tylko jeden program, dokładnie tak samo jak XBMCbuntu .


Witamy na stronie U&L, wybierz się na wycieczkę z przewodnikiem i poświęć czas, aby dowiedzieć się, jak zadać pytanie, co chcesz zrobić? ponieważ definicja aplikacji jest dość niejasna i w ogóle nic nie znaczy, ponieważ moim zaleceniem byłoby użycie, busyboxale prawdopodobnie nie tego chcesz. więc poświęć niezbędną ilość czasu na wyrażenie swojej potrzeby, a możemy być w stanie Ci pomóc. Nie wahaj się edytować swojego pytania, aby dodać do niego odpowiedni element.
Kiwy,

1
Wydaje mi się dość jasne ...
goldilocks

@ TAFKA'Goldilocks 'no nie, bo założę się, że nadal możesz mieć dostęp do terminala lub czegoś podobnego na XBMCubuntu, podczas gdy wydaje się, że tylko jedna aplikacja działa graficznie, ale nie tylko jedna aplikacja działa. Zrobiłem małą dystrybucję raz od zera, używając tylko jądra i busyboksa, w takim przypadku, nawet jeśli istnieją usługi uruchamiane przez jądro, można powiedzieć, że busybox jest twoją jedyną aplikacją.
Kiwy,

@Kiwi To dobra odpowiedź (lepsza niż LFS). Pamiętaj: 1) To pytanie może być przydatne dla innych osób, których ogólny cel jest taki sam, więc zakres odpowiedzi jest dobry, 2) Chociaż istnieje tutaj szereg możliwych rozwiązań - np. TIMTOWTDI - a niektóre mogą być lepiej dostosowane do niektórych bardziej szczegółowych celów niż inne, jestem prawie pewien, że wszystkie one będą działać, a istotny aspekt decydowania o rozwiązaniu będzie subiektywny (np. ze względu na wcześniejszą wiedzę i doświadczenie PO, a nie obiektywny charakter zadania) .
złotowłosa

Odpowiedzi:


6

Nie zaczynam bałagać się z LFS, czyli ogrodową ścieżką prowadzącą do ciemnego lasu.

Zacznij od dystrybucji, w której masz dużą kontrolę nad początkową instalacją, taką jak Arch, lub edycję bezgłową, taką jak serwer Ubuntu. Chodzi nie tyle o oszczędność miejsca, ile o ograniczenie złożoności konfiguracji init; zaczynając od dystrybucji bezgłowej, jeśli aplikacja, którą chcesz uruchomić, wymaga GUI, możesz dodać to, co jest do tego wymagane, bez konieczności logowania się do GUI (inaczej menedżera wyświetlania lub DM) uruchomionego przez init i pełnego pulpitu środowisko, aby iść z tym.

Następnie chcesz nauczyć się konfigurować system init do swoich celów - pamiętaj, że nie możesz obejść się bez init i może to być najlepszy sposób na osiągnięcie twojego celu. Istnieją trzy warianty init powszechnie używane na Linuksie (ale są też inne ):

  • Debian korzysta z wariacji na temat klasycznego init w stylu SysV . Od jessiewydania Debian również przeszedł na systemd( https://wiki.debian.org/systemd )

  • Ubuntu i pochodne używają upstart .

  • Fedora, Arch i pochodne używają systemd .

Jeśli jeszcze nic nie wiesz o żadnym z nich, żaden z nich nie jest szczególnie trudny w użyciu niż którykolwiek z nich. Jeśli wybierzesz jedną z dwóch późniejszych wersji, zapewnią one pewne mechanizmy wstecznej kompatybilności z SysV, ale nie przejmuj się tym , to wcale NIE jest prostsze. 1

Chodzi o to, aby zminimalizować to, co init robi podczas rozruchu, i w ten sposób możesz stworzyć system, który będzie uruchamiał minimalną ilość oprogramowania do obsługi aplikacji, na której chcesz się skoncentrować - tak zasadniczo jest skonfigurowany serwer, BTW, więc jest to częste zadanie (pamiętaj, że dosłownie nie możesz mieć uruchomionego „tylko jednego” procesu przestrzeni użytkownika, przynajmniej nie pożytecznie).

Jeśli aplikacja, którą chcesz uruchomić, to program GUI (dobry przykład, dlaczego nie możesz dosłownie uruchomić jednej aplikacji, ponieważ aplikacje GUI wymagają serwera X), możesz mieć taki, ~/.xinitrcktóry wygląda tak;

#!/bin/sh

myprogram

Kiedy to zrobisz startx, twój program będzie działał jedyne i nie będzie można zmienić pulpitów ani uruchomić niczego innego, częściowo dlatego, że nie ma menedżera okien ani środowiska pulpitu (stąd też nie będzie ramki okna ani paska tytułu).

1. Aby nieco omówić tę kwestię: podczas badania tego może być trochę uciążliwe dla systemd i upart od osób, które wcześniej znały SysV, twierdząc na przykład, że są zbyt skomplikowane. Jednak obiektywnie nie są bardziej złożone niż SysV (w rzeczywistości system IMO jest prostszy w użyciu), ale większość psów woli swoje stare sztuczki, że tak powiem. Ta przyczepność zaczyna zanikać, teraz oba systemy były używane przez pewien czas.


1
Nie można tego zrobić bez init, ale z pewnością można to zrobić bez upstart, systemd,lub sysv. inittylko niektóre plik wykonywalny o nazwie init, która swoimi wywołuje jądra gdy wierzchowiec initramfs.W większości przypadków te pozostałe trzy nie są jeszcze initale oni faktycznie execed się przez init,który jest powszechniebusybox.
mikeserv

@ mikeserv Absolutnie (i wyraźnie wspomniałem, że nie są to jedyne trzy opcje). Zauważ też, że celowo wykluczyłem, busyboxponieważ zasługuje na osobne traktowanie w osobnej odpowiedzi, ale nie przeze mnie.
złotowłosa

Jak wdzięczny z twojej strony! Ale nie ma mowy.
mikeserv

Interesujące byłoby wiedzieć, czy takie podejście faktycznie działa w praktyce. Ktoś naprawdę tego próbował?
Faheem Mitha

@FaheemMitha Jeśli masz na myśli to, co polecam tutaj (dostosuj konfigurację init), oczywiście, że tak - tak już działa system, po prostu tworzysz uproszczoną i uproszczoną wersję (jestem pewien, że to jest czym jest XBMCbutu). Jeśli masz na myśli zamianę init na bardziej wyspecjalizowany wykonywalny ala busybox, prawdopodobnie jest to więcej kłopotów niż jest to warte, chyba że musisz to zrobić w ten sposób - głównym celem busyboxa jest używanie go w niewielkich środowiskach osadzonych (np. Tylko z kilkoma MB pamięci RAM).
złotowłosa

18

Minimalny program init hello world program krok po kroku

wprowadź opis zdjęcia tutaj

Skompiluj cześć świata bez żadnych zależności, które kończą się nieskończoną pętlą. 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

Nie możemy użyć wyjściowego wywołania systemowego, inaczej jądro wpadnie w panikę.

Następnie:

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"

Tworzy to system plików z naszym hello world /init, który jest pierwszym programem dla użytkowników, który uruchomi jądro. Moglibyśmy również dodać więcej plików d/i byłyby one dostępne z /initprogramu podczas działania jądra.

Następnie cdw drzewie jądra Linux, kompilacja jest jak zwykle i uruchom ją w 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"

I powinieneś zobaczyć linię:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

na ekranie emulatora! Pamiętaj, że nie jest to ostatni wiersz, więc musisz spojrzeć nieco dalej.

Możesz także użyć programów C, jeśli połączysz je statycznie:

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

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

z:

gcc -static init.c -o init

Łączenie dynamiczne wymagałoby skonfigurowania pliku wykonywalnego łącznika dynamicznego, z których najczęściej są częścią standardowych bibliotek C, takich jak glibc.

Możesz działać na prawdziwym sprzęcie z włączonym USB /dev/sdXi:

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

Świetne źródło na ten temat: Porada techniczna: Jak korzystać z initramfs | landley.net Wyjaśnia również, jak używać gen_initramfs_list.sh, czyli skryptu z drzewa źródeł jądra Linux, aby pomóc zautomatyzować proces.

Testowane na Ubuntu 16.10, QEMU 2.6.1.

Następne kroki

Następną rzeczą, którą chcesz zrobić, to skonfigurować BusyBox .

BusyBox implementuje podstawowe narzędzia CLI POSIX-y, w tym powłokę POSIX-y, które pozwalają na łatwiejsze interaktywne eksperymentowanie z systemem.

Osobiście w tym momencie wolę po prostu polegać na Buildroot , który jest niesamowitym zestawem skryptów, który automatyzuje budowanie wszystkiego ze źródła i tworzenie głównego systemu plików.

Przesłałem do tego bardzo szczegółowy i zautomatyzowany pomocnik: https://github.com/cirosantilli/linux-kernel-module-cheat


4
To prawdopodobnie najbardziej niedoceniana odpowiedź tutaj: D. Niesamowite!
msouth

1
@msouth trochę mniej, więc teraz :-)
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

1

jeśli jesteś trochę programistą i chcesz go stworzyć od zera, możesz skorzystać z LFS, czyli Linuxa od zera http://www.linuxfromscratch.org/

jeśli chcesz dostosować ubutnu, możesz użyć Ubunt-Buildera, a jeśli chcesz to na bazie rpm, możesz użyć SUsE-Studio, Suse Studio pozwoli ci stworzyć niestandardowy suse Linux

Twoje zdrowie


1

Chodzi bardziej o to, czego wymaga Twój „jeden program”.

Nadal możesz dobrze zacząć rozumieć, jak poskładać wszystko, budując LFS (inaczej „ Linux From Scratch ”) . Następnie dodasz rzeczy wymagane przez program lub przejdziesz do pełnej dystrybucji, ponieważ budowanie ciężkiego podsystemu, takiego jak Gnome lub KDE na LFS, może być prawdziwym kłopotem.

Oczywiście cofanie się może być na początku łatwiejsze, ale usunięcie rzeczy z pełnej dystrybucji może być kłopotliwe: zrób to na maszynie wirtualnej i wykonaj kopię tej maszyny wirtualnej na każdym kroku.

(moje 2 centy)

Edytuj :

Jak wskazał SecurityBeast, zamiast zaczynać od pełnej dystrybucji, takiej jak CentOS lub Ubuntu , możesz także przyjrzeć się tworzeniu narzędzi do dystrybucji, takich jak:


1

Musisz zapytać, czego potrzebuje Twój „jeden program” i jakie masz zasoby.

Jeśli potrzebuje szerokiego wyboru bibliotek i binariów pomocniczych, najlepiej jest użyć „zwykłej” dystrybucji Linuksa (Debian lub podobnej) i po prostu trochę zepsuć proces uruchamiania.

Jeśli wymaga ono węższego wyboru elementów obsługi, ale nadal wymaga takich elementów, jak praca w sieci lub obsługa różnych urządzeń przy użyciu różnych modułów jądra lub bitów obsługi użytkowników, a nie chcesz, aby przestrzeń dyskowa była narzutem w przypadku zwykłej dystrybucji, sugerowałbym, aby spojrzeć na osadzone dystrybucje (buildroot lub podobne) lub może Linux od zera (choć może to być ból głowy utrzymania)

Jeśli potrzebujesz tylko tego, co może dostarczyć niemodularne jądro i nic więcej, uruchomienie własnego pliku binarnego bezpośrednio na jądrze może działać i być najlżejszym rozwiązaniem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.