Apa saja aplikasi sistem file root minimum yang diperlukan untuk mem-boot linux sepenuhnya?

17

Ini pertanyaan tentang aplikasi ruang pengguna, tapi dengarkan aku!

Tiga "aplikasi", demikian, diperlukan untuk mem-boot distribusi fungsional Linux:

  1. Bootloader - Untuk tertanam biasanya U-Boot, meskipun bukan persyaratan sulit.

  2. Kernel - Cukup mudah.

  3. Root Filesystem - Tidak dapat boot ke shell tanpa itu. Berisi sistem berkas tempat boot kernel, dan di mana initdisebut form.

Pertanyaan saya berkaitan dengan # 3. Jika seseorang ingin membangun rootfs yang sangat minimal (untuk pertanyaan ini katakanlah tidak ada GUI, hanya shell), file / program apa yang diperlukan untuk boot ke shell?

MDMoore313
sumber
Tentukan minimal. Anda dapat menggunakan hanya satu yang dapat dieksekusi dengan tidak ada yang lain seperti yang dijelaskan di: superuser.com/a/991733/128124 Hanya saja itu tidak dapat setiap keluar atau panik, sehingga Anda memerlukan loop tak terbatas atau tidur panjang. Pertanyaan serupa: unix.stackexchange.com/questions/17122/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Jawaban:

32

Itu sepenuhnya tergantung pada layanan apa yang ingin Anda miliki di perangkat Anda.

Program

Anda dapat membuat Linux boot langsung ke shell . Ini tidak terlalu berguna dalam produksi - yang hanya ingin memiliki shell yang duduk di sana - tetapi itu berguna sebagai mekanisme intervensi ketika Anda memiliki bootloader interaktif: lulus init=/bin/shke baris perintah kernel. Semua sistem Linux (dan semua sistem unix) memiliki shell Bourne / POSIX-style /bin/sh.

Anda membutuhkan seperangkat utilitas shell . BusyBox adalah pilihan yang sangat umum; mengandung shell dan utilitas umum untuk berkas dan manipulasi teks ( cp, grep, ...), setup jaringan ( ping, ifconfig, ...), proses manipulasi ( ps, nice, ...), dan berbagai alat sistem lainnya ( fdisk, mount, syslogd, ...). BusyBox sangat dapat dikonfigurasi: Anda dapat memilih alat mana yang Anda inginkan dan bahkan fitur individual pada waktu kompilasi, untuk mendapatkan kompromi ukuran / fungsionalitas yang tepat untuk aplikasi Anda. Selain sh, minimal bahwa Anda tidak bisa benar-benar melakukan apa-apa tanpa adalah mount, umountdan halt, tetapi akan atipikal untuk tidak memiliki juga cat, cp, mv, rm,mkdir, rmdir, ps, syncDan beberapa lagi. BusyBox menginstal sebagai biner tunggal yang disebut busybox, dengan tautan simbolik untuk setiap utilitas.

Proses pertama pada sistem unix normal disebut init. Tugasnya adalah memulai layanan lain. BusyBox berisi sistem init. Selain initbiner (biasanya terletak di /sbin), Anda akan memerlukan file konfigurasinya (biasanya disebut /etc/inittab- beberapa pengganti init modern menghapuskan file itu tetapi Anda tidak akan menemukannya pada sistem tertanam kecil) yang menunjukkan layanan apa yang harus dimulai dan kapan. Untuk BusyBox, /etc/inittabbersifat opsional; jika tidak ada, Anda mendapatkan root shell di konsol dan skrip /etc/init.d/rcS(lokasi default) dieksekusi saat boot.

Itu yang Anda butuhkan, tentu saja program yang membuat perangkat Anda melakukan sesuatu yang bermanfaat. Sebagai contoh, pada router rumah saya menjalankan varian OpenWrt , satu-satunya program adalah BusyBox, nvram(untuk membaca dan mengubah pengaturan dalam NVRAM), dan utilitas jaringan.

Kecuali jika semua executable Anda terhubung secara statis, Anda akan memerlukan loader dinamis ( ld.so, yang dapat dipanggil dengan nama yang berbeda tergantung pada pilihan libc dan pada arsitektur prosesor) dan semua perpustakaan dinamis ( /lib/lib*.so, mungkin beberapa di antaranya /usr/lib) diperlukan oleh executable ini.

Struktur direktori

The Filesystem Hierarchy Standard menggambarkan struktur direktori umum dari sistem Linux. Itu diarahkan untuk instalasi desktop dan server: banyak yang bisa dihilangkan pada sistem tertanam. Ini adalah minimum tipikal.

  • /bin: program yang dapat dieksekusi (beberapa mungkin ada di /usr/bingantinya).
  • /dev: node perangkat (lihat di bawah)
  • /etc: file konfigurasi
  • /lib: pustaka bersama, termasuk pemuat dinamis (kecuali jika semua yang dapat dieksekusi terkait secara statis)
  • /proc: mount point untuk sistem file proc
  • /sbin: program yang dapat dieksekusi. Perbedaan dengan /binyaitu yang /sbinmerupakan program yang hanya berguna untuk administrator sistem, tetapi perbedaan ini tidak bermakna pada perangkat embedded. Anda dapat membuat /sbintautan simbolis ke /bin.
  • /mnt: berguna untuk menggunakan sistem file root read-only sebagai titik awal pemasangan selama pemeliharaan
  • /sys: mount point untuk sistem file sysfs
  • /tmp: lokasi untuk file sementara (sering kali tmpfsmount)
  • /usr: berisi subdirektori bin, libdan sbin. /usrada untuk file tambahan yang tidak ada di sistem file root. Jika tidak memilikinya, Anda dapat membuat /usrtautan simbolis ke direktori root.

File perangkat

Berikut adalah beberapa entri khas dalam minimal /dev:

  • console
  • full (menulis padanya selalu melaporkan "tidak ada ruang yang tersisa di perangkat")
  • log(soket yang digunakan program untuk mengirim entri log), jika Anda memiliki syslogddaemon (seperti BusyBox's) yang membacanya
  • null (bertindak seperti file yang selalu kosong)
  • ptmxdan ptsdirektori , jika Anda ingin menggunakan pseudo-terminal (yaitu terminal apa pun selain konsol) - mis. jika perangkat terhubung ke jaringan dan Anda ingin telnet atau ssh in
  • random (mengembalikan byte acak, risiko diblokir)
  • tty (selalu menunjuk terminal program)
  • urandom (mengembalikan byte acak, tidak pernah memblokir tetapi mungkin non-acak pada perangkat yang baru saja di-boot)
  • zero (berisi urutan tak terhingga dari byte nol)

Di luar itu Anda akan memerlukan entri untuk perangkat keras Anda (kecuali antarmuka jaringan, ini tidak mendapatkan entri /dev): port serial, penyimpanan, dll.

Untuk perangkat yang disematkan, Anda biasanya akan membuat entri perangkat langsung di sistem file root. Sistem kelas atas memiliki skrip yang dipanggil MAKEDEVuntuk membuat /deventri, tetapi pada sistem yang disematkan skrip sering tidak digabungkan ke dalam gambar. Jika beberapa perangkat keras dapat dicolokkan (mis. Jika perangkat memiliki port host USB), maka /devharus dikelola oleh udev (Anda mungkin masih memiliki set minimal pada sistem file root).

Tindakan waktu boot

Di luar sistem file root, Anda perlu me-mount beberapa lagi untuk operasi normal:

  • procfs on /proc(cukup banyak sangat diperlukan)
  • sysfs on /sys(cukup banyak sangat diperlukan)
  • tmpfssistem file aktif /tmp(untuk memungkinkan program membuat file sementara yang akan berada dalam RAM, bukan pada sistem file root yang mungkin dalam flash atau hanya-baca)
  • tmpfs, devfs atau devtmpfs on /devif dynamic (lihat udev di “File perangkat” di atas)
  • devpts on /dev/ptsjika Anda ingin menggunakan [pseudo-terminal (lihat komentar di ptsatas)

Anda dapat membuat /etc/fstabfile dan panggilan mount -a, atau menjalankan mountsecara manual.

Mulai daemon syslog (dan juga klogduntuk log kernel, jika syslogdprogram tidak menanganinya), jika Anda punya tempat untuk menulis log.

Setelah ini, perangkat siap untuk memulai layanan khusus aplikasi.

Cara membuat sistem file root

Ini adalah cerita yang panjang dan beragam, jadi yang akan saya lakukan di sini adalah memberikan beberapa petunjuk.

Sistem file root dapat disimpan dalam RAM (dimuat dari gambar (biasanya dikompresi) dalam ROM atau flash), atau pada sistem file berbasis disk (disimpan dalam ROM atau flash), atau dimuat dari jaringan (sering melalui TFTP ) jika berlaku . Jika sistem file root di RAM, jadikan initramfs - sistem file RAM yang isinya dibuat saat boot.

Ada banyak kerangka kerja untuk merakit gambar root untuk sistem tertanam. Ada beberapa petunjuk dalam FAQ BusyBox . Buildroot adalah yang populer, memungkinkan Anda untuk membangun image root secara keseluruhan dengan setup yang mirip dengan kernel Linux dan BusyBox. OpenEmbedded adalah kerangka kerja lain.

Wikipedia memiliki daftar (tidak lengkap) dari distribusi Linux tertanam yang populer . Contoh embedded Linux yang mungkin Anda miliki di dekat Anda adalah keluarga OpenWrt dari sistem operasi untuk peralatan jaringan (populer di router rumah tinker '). Jika Anda ingin belajar berdasarkan pengalaman, Anda dapat mencoba Linux dari Scratch , tetapi diarahkan ke sistem desktop untuk penggemar daripada ke perangkat yang tertanam.

Catatan tentang Linux vs kernel Linux

Satu-satunya perilaku yang dimasukkan ke dalam kernel Linux adalah program pertama yang diluncurkan saat boot. (Saya tidak akan membahas subtitle initrd dan initramfs di sini.) Program ini, secara tradisional disebut init , memiliki ID proses 1 dan memiliki hak istimewa tertentu (kekebalan terhadap sinyal KILL ) dan tanggung jawab (menuai anak yatim ). Anda dapat menjalankan sistem dengan kernel Linux dan memulai apa pun yang Anda inginkan sebagai proses pertama, tetapi kemudian yang Anda miliki adalah sistem operasi yang didasarkan pada kernel Linux, dan bukan apa yang biasanya disebut "Linux" -  Linux , dalam pengertian umum istilahnya, adalah sistem operasi mirip Unix yang kernelnya adalah kernel Linux. Sebagai contoh, Android adalah sistem operasi yang tidak seperti Unix tetapi didasarkan pada kernel Linux.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Jawaban yang sangat bagus. Saya hanya menyebutkan mem-boot ke Linux dalam judul b / c yang kemungkinan besar akan dicari, begitu banyak tambahan tentang Linux vs Linux Kernel, yang perlu pengetahuan yang lebih luas.
MDMoore313
@BigHomie Ingat, Free Software Foundation meminta kita semua menyebutnya GNU / Linux, karena pada sebagian besar (semua?) "Linux distro" perangkat lunaknya adalah GNU, meskipun kernelnya adalah Linux (karenanya GNU / Linux).
BenjiWiebe
Meh, tidak ada yang punya waktu untuk itu. Maka distro saya harus disebut Busybox / Linux ?? Saya tahu saya tahu, itu bukan Anda Stallworth, hanya ventilasi;)
MDMoore313
1
@BenjiWiebe Atau GNU / X11 / Apache / Linux / TeX / Perl / Python / FreeCiv . Selain RMS, semua orang menyebutnya "Linux".
Gilles 'SO- stop being evil'
@Gilles Yah, terlepas dari Debian, kurasa. :)
a CVn
5

Yang Anda butuhkan adalah satu executable yang terhubung secara statis, ditempatkan pada sistem file, secara terpisah. Anda tidak memerlukan file lain. Eksekusi itu adalah proses init. Itu bisa kotak sibuk. Itu memberi Anda sebuah shell dan sejumlah utilitas lain, semuanya dengan sendirinya. Anda dapat pergi ke sistem yang berfungsi penuh hanya dengan menjalankan perintah secara manual di busybox untuk me-mount root filesystem read-write, membuat / dev node, exec init nyata, dll.

Pasang kembali Monica
sumber
Ya, saya tahu busybox akan datang. Mari kita lihat jika ada yang muncul.
MDMoore313
4

Jika Anda tidak memerlukan utilitas shell, mkshbiner yang terhubung secara statis (mis. Melawan klibc - 130K di Linux / i386) akan berfungsi. Anda perlu /linuxrcatau /initatau /sbin/initscript yang hanya panggilan mksh -l -T!/dev/tty1dalam satu lingkaran:

#!/bin/mksh
while true; do
    /bin/mksh -l -T!/dev/tty1
done

The -T!$ttypilihan adalah tambahan terbaru untuk mkshyang mengatakan itu untuk menelurkan sebuah shell baru pada terminal yang diberikan dan menunggu untuk itu. (Sebelum itu, hanya ada -T-dmon untuk memprogram dan -T$ttymenelurkan terminal tetapi tidak menunggu untuk itu. Ini tidak begitu baik.) -lPilihan hanya memberitahu untuk menjalankan shell login (yang berbunyi /etc/profile, ~/.profiledan ~/.mkshrc).

Ini mengasumsikan terminal Anda adalah /dev/tty1, pengganti. (Dengan lebih banyak sihir, terminal dapat ditemukan secara otomatis. Tidak /dev/consoleakan memberi Anda kontrol pekerjaan penuh.)

Anda perlu beberapa file /devagar ini berfungsi:

  • / dev / console
  • / dev / null
  • / dev / tty
  • / dev / tty1

Booting dengan opsi kernel devtmpfs.mount=1menghilangkan kebutuhan untuk mengisi /dev, biarkan saja direktori kosong (cocok untuk digunakan sebagai mountpoint).

Anda biasanya ingin memiliki beberapa utilitas (dari klibc, busybox, beastiebox, toybox atau toolbox), tetapi tidak terlalu dibutuhkan.

Anda mungkin ingin menambahkan ~/.mkshrcfile, yang mengatur $ PS1 dan beberapa alias dan fungsi shell dasar.

Saya pernah membuat initrd terkompresi 171K (371K tidak terkompresi) untuk Linux / m68k menggunakan mksh (dan file sampel mkshrc) dan hanya klibc-utils saja. (Ini sebelum -T! Ditambahkan ke shell, jadi itu menelurkan shell login /dev/tty2dan gantinya pesan ke konsol memberitahu pengguna untuk beralih terminal.) Ini berfungsi dengan baik.

Ini adalah pengaturan minimum yang sangat telanjang . Jawaban lain memberikan saran yang sangat baik terhadap sistem yang lebih banyak fitur. Ini adalah kasus khusus nyata.

Penafian: Saya adalah pengembang mksh.

mirabilos
sumber
Ini adalah jawaban yang bagus, terima kasih untuk berbagi dan juga terima kasih untuk mksh.
JoshuaRLi
2

Minimal init hello world program langkah demi langkah

masukkan deskripsi gambar di sini

Kompilasi dunia halo tanpa dependensi yang berakhir pada loop tak terbatas. 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

Kami tidak dapat menggunakan sys_exit, atau panik kernel.

Kemudian:

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

Ini menciptakan sistem file dengan hello world kami di /init, yang merupakan program userland pertama yang dijalankan oleh kernel. Kami juga bisa menambahkan lebih banyak file ke d/dan mereka akan dapat diakses dari /initprogram ketika kernel berjalan.

Kemudian cdke dalam pohon kernel Linux, build seperti biasa, dan jalankan di 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"

Dan Anda akan melihat garis:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR

di layar emulator! Perhatikan bahwa ini bukan baris terakhir, jadi Anda harus melihat lebih jauh.

Anda juga dapat menggunakan program C jika Anda menautkannya secara statis:

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

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

dengan:

gcc -static init.c -o init

Anda dapat menjalankan perangkat keras nyata dengan USB menyala /dev/sdXdan:

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

Sumber hebat tentang hal ini: http://landley.net/writing/rootfs-howto.html Ini juga menjelaskan cara menggunakan gen_initramfs_list.sh, yang merupakan skrip dari pohon kode sumber Linux untuk membantu mengotomatiskan proses.

Langkah selanjutnya: siapkan BusyBox agar Anda dapat berinteraksi dengan sistem: https://github.com/cirosantilli/runlinux

Diuji pada Ubuntu 16.10, QEMU 2.6.1.

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
sumber