วิธีสร้าง distro Linux แบบกำหนดเองที่รันเพียงโปรแกรมเดียวและไม่มีอะไรอื่น?


12

ฉันอาจจะไปเกี่ยวกับการสร้างของฉัน "กำหนดเอง" ของตัวเอง Linux distro ที่จะทำงานเพียงแค่โปรแกรมหนึ่งสวยมากตรงทางเดียวกับXBMCbuntu


ยินดีต้อนรับใน U&L โปรดใช้ไกด์นำเที่ยวและใช้เวลาในการเรียนรู้วิธีถามคำถามคุณต้องการทำอะไร เพราะคำจำกัดความของแอพพลิเคชั่นค่อนข้างคลุมเครือและไม่ได้มีความหมายอะไรเลยเพราะคำแนะนำของฉันจะใช้busyboxแต่นั่นอาจไม่ใช่สิ่งที่คุณต้องการ โปรดใช้เวลาที่จำเป็นในการแสดงความต้องการของคุณและเราอาจช่วยคุณได้ อย่าลังเลที่จะแก้ไขคำถามของคุณเพื่อเพิ่มองค์ประกอบที่เกี่ยวข้องในนั้น
Kiwy

1
ดูเหมือนว่าสวยใสกับฉัน ...
Goldilocks

@ TAFKA'goldilocks 'ไม่ดีเพราะฉันพนันได้เลยว่าคุณยังคงสามารถเข้าถึงเทอร์มินัลหรือสิ่งที่คล้ายกันใน XBMCubuntu ในขณะที่ดูเหมือนว่ามีแอปเดียวที่ทำงานแบบกราฟิก แต่มีเพียงแอปเดียวที่ทำงานอยู่ ฉันทำ distro เล็ก ๆ ครั้งเดียวตั้งแต่เริ่มต้นด้วยเคอร์เนลและ busybox เท่านั้นในกรณีนี้แม้ว่าจะมีบริการที่เปิดใช้งานโดยเคอร์เนลคุณสามารถพูดได้ว่า busybox เป็นแอปเดียวของคุณ
Kiwy

@ กีวีนั่นเป็นคำตอบที่ดีแล้ว (ดีกว่า LFS) โปรดทราบ: 1) คำถามนี้อาจเป็นประโยชน์กับคนอื่นที่มีจุดประสงค์ทั่วไปเหมือนกันดังนั้นคำตอบที่หลากหลายก็ดี 2) ในขณะที่มีวิธีแก้ไขที่เป็นไปได้มากมายเช่นTIMTOWTDIและบางคนอาจจะ เหมาะสมกับเป้าหมายที่เฉพาะเจาะจงมากกว่าคนอื่น ๆ ฉันค่อนข้างมั่นใจว่าพวกเขาจะทำงานและประเด็นสำคัญในการตัดสินใจเกี่ยวกับการแก้ปัญหาจะเป็นเรื่องส่วนตัว (เช่นเนื่องจากความรู้และประสบการณ์ก่อนหน้าของ OP ไม่ใช่ธรรมชาติของงาน) .
goldilocks

คำตอบ:


6

ฉันจะไม่เริ่มยุ่งกับ LFS นั่นคือเส้นทางสวนที่นำไปสู่ป่ามืด

เริ่มต้นด้วย distro ที่คุณสามารถควบคุมการติดตั้งเริ่มต้นจำนวนมากเช่น Arch หรือรุ่นที่ไม่มีส่วนหัวเช่นเซิร์ฟเวอร์ Ubuntu ประเด็นนี้ไม่มากที่จะประหยัดพื้นที่ในการจำกัดความซับซ้อนของการกำหนดค่าเริ่มต้น เริ่มจากหัวขาดหากแอปพลิเคชันที่คุณต้องการเรียกใช้ต้องใช้ GUI คุณสามารถเพิ่มสิ่งที่จำเป็นสำหรับสิ่งนั้นโดยไม่ต้องจบลงด้วยการเข้าสู่ระบบ GUI (aka. ตัวจัดการการแสดงผลหรือ DM) ที่เริ่มต้นโดย init และเดสก์ท็อปแบบเต็ม สภาพแวดล้อมที่จะไปกับมัน

จากนั้นคุณต้องการเรียนรู้วิธีกำหนดค่าระบบเริ่มต้นให้เป็นไปตามวัตถุประสงค์ของคุณ - โปรดทราบว่าคุณไม่สามารถทำได้หากไม่มี init และอาจเป็นวิธีที่ดีที่สุดในการบรรลุเป้าหมายของคุณ มีสามรูปแบบที่เริ่มต้นที่ใช้กันทั่วไปใน linux (แต่มีคนอื่น ๆ ):

  • Debian ใช้รูปแบบบนยูนิกซ์คลาสสิกinit SysV สไตล์ ในฐานะของjessieรุ่น Debian ได้เปลี่ยนไปที่systemd( https://wiki.debian.org/systemd )

  • อูบุนตูและอนุพันธ์ใช้พุ่งพรวด

  • Fedora, Arch และอนุพันธ์ใช้systemd

หากคุณยังไม่รู้อะไรเลยเกี่ยวกับสิ่งเหล่านี้ก็ยังไม่มีใครใช้มันได้ยากกว่าคนอื่น ๆ หากคุณไปกับหนึ่งในสองภายหลังพวกเขามีกลไกบางอย่างสำหรับความเข้ากันได้ย้อนหลังกับ SysV แต่ไม่ต้องกังวลกับสิ่งนั้นมันไม่ใช่เรื่องง่าย 1

จุดนี้คือการลดสิ่งที่ init ทำตอนบูตและนั่นคือวิธีที่คุณสามารถสร้างระบบที่จะรันซอฟต์แวร์จำนวนน้อยที่สุดเพื่อรองรับแอปพลิเคชันที่คุณต้องการมุ่งเน้น - นี่คือการตั้งค่าเซิร์ฟเวอร์เป็นหลัก BTW ดังนั้นจึงเป็นงานทั่วไป (โปรดทราบว่าคุณไม่สามารถเรียกใช้กระบวนการผู้ใช้ "เพียงหนึ่ง" อย่างน้อยก็ไม่เป็นประโยชน์)

หากแอปพลิเคชันที่คุณต้องการเรียกใช้เป็นโปรแกรม GUI (ตัวอย่างที่ดีว่าทำไมคุณไม่สามารถเรียกใช้แอปพลิเคชั่นเดียวได้เนื่องจากแอพ GUI ต้องใช้เซิร์ฟเวอร์ X) คุณสามารถมีแอปพลิเคชัน~/.xinitrcนี้

#!/bin/sh

myprogram

เมื่อคุณแล้วstartxโปรแกรมของคุณจะเป็นสิ่งเดียวที่ทำงานและเป็นไปไม่ได้ที่จะเปลี่ยนเดสก์ท็อปหรือเริ่มต้นสิ่งอื่นบางส่วนเนื่องจากไม่มีตัวจัดการหน้าต่างหรือสภาพแวดล้อมเดสก์ท็อป (ดังนั้นจะไม่มีกรอบหน้าต่างหรือแถบหัวเรื่อง

1. เพื่อให้เข้าใจจุดเล็กน้อย: เมื่อคุณค้นคว้าสิ่งนี้คุณอาจพบว่ามีบางอย่างเกี่ยวกับ systemd และการพุ่งพรวดจากผู้ที่คุ้นเคยกับการอ้างสิทธิ์ SysV มาก่อนเช่นพวกเขาซับซ้อนเกินไป อย่างไรก็ตามความจริงแล้วมันไม่ซับซ้อนกว่า SysV (IMO systemd นั้นใช้งานง่ายกว่า) แต่สุนัขส่วนใหญ่ชอบกลอุบายเก่า ๆ การยึดเกาะนี้เริ่มต้นที่จะพังทลายลงตอนนี้ทั้งสองระบบใช้งานมาระยะหนึ่งแล้ว


1
คุณไม่สามารถทำได้โดยไม่ต้องinitแต่แน่นอนคุณสามารถทำได้โดยไม่ต้องupstart, systemd,หรือsysv. initเป็นเพียงบางแฟ้มที่ปฏิบัติการได้รับการตั้งชื่อinitที่จะเรียกเคอร์เนลของคุณเมื่อมันเมาท์initramfs.ในกรณีส่วนใหญ่ทั้งสามอื่น ๆ ไม่ได้initแต่พวกเขากำลังจริงexeced เข้าไปโดยinit,ที่เป็นที่นิยมbusybox.
mikeserv

@ mikeserv อย่างแน่นอน (และฉันได้พูดถึงอย่างชัดเจนว่าสิ่งเหล่านี้ไม่ใช่ตัวเลือกสามตัวเลือกเท่านั้น) โปรดทราบว่าฉันได้ยกเว้นอย่างจงใจbusyboxเพราะนั่นควรได้รับการรักษาแยกต่างหากในคำตอบที่แยกต่างหาก แต่ไม่ใช่โดยฉัน
goldilocks

คุณมีความยินดีมากเพียงใด! แต่ไม่มีทางเถอะ
mikeserv

มันจะน่าสนใจที่จะรู้ว่าวิธีนี้ใช้งานได้จริงในทางปฏิบัติ ใครลองดูบ้าง
Faheem Mitha

@FaheemMitha หากคุณหมายถึงสิ่งที่ฉันแนะนำที่นี่ (ปรับแต่งการกำหนดค่าเริ่มต้น) แน่นอนมันทำ - นั่นเป็นวิธีที่ระบบใช้งานได้แล้วคุณจะต้องสร้างเวอร์ชั่นที่เรียบง่ายและเรียบง่าย (ฉันแน่ใจว่านี่คือ XBMCbutu คืออะไร) หากคุณหมายถึงการแทนที่ init ด้วยบางกรณีที่ไม่ได้ใช้งาน Ala busybox อาจเป็นปัญหามากกว่าที่ควรจะเป็นเว้นแต่คุณจะต้องทำเช่นนั้น - วัตถุประสงค์หลักของ busybox นั้นมีไว้สำหรับใช้ในสภาพแวดล้อมแบบฝังตัวเล็ก ๆ เมกะไบต์ RAM)
goldilocks

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

เราไม่สามารถใช้การเรียกของระบบทางออกมิฉะนั้นเคอร์เนลตกใจ

แล้ว:

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 ของเรา/initซึ่งเป็นโปรแกรม userland แรกที่เคอร์เนลจะทำงาน เราสามารถเพิ่มไฟล์เพิ่มเติมd/และพวกเขาจะสามารถเข้าถึงได้จาก/initโปรแกรมเมื่อเคอร์เนลทำงาน

จากนั้นcdเข้าไปในเคอร์เนลลินุกซ์สร้างเป็นปกติและเรียกใช้ใน 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


4
นี่อาจเป็นคำตอบที่ถูกประเมินมากที่สุดที่นี่: D ! น่ากลัว
msouth

1
@msouth น้อยกว่าดังนั้นตอนนี้ :-)
Ciro Santilli 冠状病毒审查六四事件法轮功

1

ถ้าคุณเป็นคนเขียนโปรแกรมนิดหน่อยและต้องการสร้างมันขึ้นมาใหม่คุณสามารถใช้ LFS เช่น Linux จาก Scratch http://www.linuxfromscratch.org/

ถ้าคุณต้องการปรับแต่ง ubutnu คุณสามารถใช้ ubunt-builder และถ้าคุณต้องการมันบน rpm base คุณสามารถใช้ SUsE-Studio ได้สตูดิโอ Suse จะอนุญาตให้คุณสร้าง suse linux เอง

ไชโย


1

เพิ่มเติมเกี่ยวกับ "โปรแกรมหนึ่ง" ของคุณที่ต้องการ

คุณยังสามารถมีการเริ่มต้นที่ดีของการเข้าใจวิธีการที่จะนำสิ่งเข้าด้วยกันโดยการสร้างLFS (aka " ลินุกซ์ตั้งแต่เริ่มต้น ") จากนั้นคุณจะเพิ่มสิ่งต่าง ๆ ตามที่โปรแกรมของคุณต้องการหรือเพื่อการแจกจ่ายเต็มรูปแบบเพราะการสร้างระบบย่อยหนักเช่นGnomeหรือKDEบน LFS อาจเป็นความเจ็บปวดอย่างแท้จริง

แน่นอนว่าการย้อนกลับอาจทำได้ง่ายกว่าในตอนแรก แต่การลบสิ่งต่าง ๆ จากการกระจายเต็มรูปแบบอาจเป็นปัญหา: ทำสิ่งนี้ใน VM และคัดลอก VM นี้ทุกขั้นตอน

(2 เซ็นต์ของฉัน)

แก้ไข :

ตามที่SecurityBeastชี้ให้เห็นแทนที่จะเริ่มต้นจากการจัดจำหน่ายอย่างเต็มรูปแบบเช่นCentOSหรือUbuntuคุณอาจมองไปที่การสร้างเครื่องมือการแจกจ่ายเช่น:


1

สิ่งที่คุณต้องถามคือ "โปรแกรมหนึ่ง" ของคุณต้องการอะไรและมีทรัพยากรอะไรบ้าง

หากต้องการไลบรารีและไบนารีการสนับสนุนที่หลากหลายคุณอาจใช้ลินุกซ์ "ปกติ" (Debian หรือคล้ายกัน) และใช้ขั้นตอนการบูตเล็กน้อย

ถ้าต้องการตัวเลือกการสนับสนุนที่แคบลง แต่ยังต้องการสิ่งต่าง ๆ เช่นเครือข่ายหรือรองรับฮาร์ดแวร์ที่หลากหลายโดยใช้โมดูลเคอร์เนลที่แตกต่างกันหรือบิตการสนับสนุนของผู้ใช้และคุณไม่ต้องการพื้นที่ดิสก์เหนือหัวปกติฉันขอแนะนำให้ดู distros แบบฝังตัว (buildroot หรือคล้ายกัน) หรืออาจจะเป็น linux จากวิธีการลบ (แม้ว่าจะเป็นอาการปวดหัวบำรุงรักษา)

หากคุณต้องการสิ่งที่เคอร์เนลที่ไม่ใช่โมดูลาร์สามารถให้บริการและไม่มีอะไรอื่นแล้วใช้ไบนารีของคุณเองตรงบนเคอร์เนลอาจทำงานและเป็นทางออกที่เบาที่สุด ..

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.