1つのプログラムだけを実行し、それ以外は何も実行しないカスタムLinuxディストリビューションを作成する方法は?


12

どのように私はLinuxはそれがただ一つのプログラムとして、ほとんど全く同じように実行されますディストリビュー自分の「カスタム」の作成に取り掛かることができXBMCbuntuを


U&Lへようこそ。ガイド付きツアーに参加し、時間をかけて質問をする方法を学び何をしたいですか?アプリケーションの定義はかなりあいまいで、まったく意味がないためです。私のアドバイスは使用することですbusyboxが、それはおそらくあなたが望むものではないからです。必要な時間をとって、必要なことを伝えてください。サポートさせていただく場合があります。質問を編集して、関連する要素を追加してください。
Kiwy 14

1
私にはかなりはっきりしているようです...
goldilocks 14

@ TAFKA'goldilocks 'よくありません。XBMCubuntuでは、1つのアプリだけがグラフィカルに実行されているように見えますが、1つのアプリだけが実行されているわけではないように見えますが、ターミナルや同様のものにアクセスできます。カーネルとbusyboxのみを使用して、最初から小さなディストリビューションを作成しました。その場合、カーネルによって起動されるサービスがあっても、busyboxが唯一のアプリであると言えます。
Kiwy 14

@Kiwiそれは良い答えです(LFSより優れています)。覚えておいてください:1)可能なソリューションの範囲がここにありますが、この質問は)その汎用同じなので、答えの範囲が良い、2で他の人に有用である可能性がある-すなわちTIMTOWTDI -といくつかのことが可能他の特定の目標よりも特定の目標に適していますが、それらはすべて機能し、ソリューションを決定する重要な側面は主観的です(たとえば、OPの事前の知識と経験のため、タスクの客観的な性質ではありません)。 。
goldilocks 2014

回答:


6

私はLFSをいじり始めません、それはいくつかの暗い森に通じる庭の道です。

Archなどの初期インストールやUbuntuサーバーなどのヘッドレスエディションを細かく制御できるディストリビューションから始めます。これの目的は、init構成の複雑さを区切るほどスペースを節約することではありません。ヘッドレスディストリビューションから始めて、実行するアプリケーションにGUIが必要な場合は、initによって開始されたGUIログイン(別名:ディスプレイマネージャーまたはDM)と本格的なデスクトップを必要とせずに、必要なものを追加できます。それと一緒に行く環境。

次に、目的に合わせてinitシステムを構成する方法を学びたいと思います-initなしでは実行できないことに注意してください。これは、目標を達成するための最良の方法かもしれません。Linuxで一般的に使用されるinitには3つのバリエーションがあります(にもいくつかあります)。

  • Debianは、古典的なUnix SysVスタイルのinitのバリエーションを使用していますjessieリリースの時点で、Debianもsystemdhttps://wiki.debian.org/systemd)に切り替えました

  • Ubuntuと派生物はupstartを使用します。

  • Fedora、Arch、および派生物はsystemdを使用ます。

これらのいずれかについてまだ何も知らない場合、それらのどれも、他のどれよりも使用するのが特に難しいことはありません。後の2つのうちの1つを使用する場合、それらはSysVとの下位互換性のためのいくつかのメカニズムを提供します、それを気にしないでください。それは単純ではありません。1

ここでのポイントは、起動時にinitが行うことを最小限に抑えることであり、これにより、焦点を当てたいアプリケーションをサポートするための最小限のソフトウェアを実行するシステムを作成できます-これは基本的にサーバーのセットアップ方法です、ところで、これは一般的なタスクです(文字通り「1つだけ」のユーザーランドプロセスを実行することはできません。少なくとも役に立たないことに注意してください)。

実行するアプリケーションがGUIプログラムである場合(GUIアプリケーションはXサーバーを必要とするため、文字通り1つのアプリケーションを実行できない理由の良い例)、~/.xinitrc次のようなを使用できます。

#!/bin/sh

myprogram

すると、実行中のstartxプログラムはプログラムだけになり、ウィンドウマネージャーやデスクトップ環境がないため(つまり、ウィンドウフレームやタイトルバーもないため)、デスクトップを変更したり何かを開始したりすることができなくなります。

1.要点を少し注意する:これを研究していると、以前はSysVに精通していた人たちから、systemdや新興企業が複雑すぎるなどの不満を感じるかもしれません。ただし、客観的にはそれらはSysVよりも複雑ではありません(実際には、IMO systemdの方が使用が簡単です)。しかし、ほとんどの犬は、いわば古いトリックを好みます。このグリップは衰退し始めており、両方のシステムがしばらく使用されています。


1
あなたはなしで行うことはできませんinitが、確かにあなたがすることなく行うことができますupstart, systemd,またはsysv. init名前のちょうどいくつかの実行可能ファイルであるinitカーネル呼び出すこと、それはマウント時にinitramfs.ほとんどの場合、これらの他の3つはさえないですinitが、彼らが実際にしているexecことでにエドinit,一般的であるbusybox.
mikeserv

@mikeserv絶対に(そして私はこれらが唯一の3つの選択肢ではないことを明示的に述べました)。また、私が意図的に除外したbusyboxことにも注意してください。これは、個別の回答で個別の扱いに値するためですが、私自身によるものではありません。
goldilocks 14

なんと優雅なあなたを提供するか!しかし、いまいましい方法はありません。
mikeserv 14

このアプローチが実際に機能するかどうかを知ることは興味深いでしょう。誰か実際に試してみましたか?
Faheem Mitha 14

@FaheemMithaもし私がここで推奨していることを意味しているなら(init構成をカスタマイズしてください)、もちろんそれはそうです-それはシステムがすでに機能している方法です、あなたは単純に簡略化されたバージョンを作成しているでしょう(これは確かです) XBMCbutuとは)。つまり、initをより専門的な実行可能なala busyboxで置き換える場合、その方法で実行する必要がない限り、おそらくそれよりも問題が多くなります。busyboxの主な目的は、小さな組み込み環境(たとえば、 MBのRAM)。
goldilocks 14

18

最小限のinit hello worldプログラムのステップバイステップ

ここに画像の説明を入力してください

無限ループで終了する依存関係のない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

exitシステムコール、またはカーネルパニックを使用できません。

次に:

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。これは、カーネルが実行する最初のユーザーランドプログラムです。さらにファイルを追加することもでき、カーネルの実行時にプログラムd/からアクセスできます/init

次にcd、Linuxカーネルツリーにビルドを通常どおり実行し、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

動的リンクには、動的リンカー実行可能ファイルをセットアップする必要があります。その最も一般的なものは、glibcなどのC標準ライブラリの一部です。

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シェルを含む基本的なPOSIX-y CLIユーティリティを実装しています。これを使用すると、システムをインタラクティブに簡単に試すことができます。

個人的には、この時点では、ソースからすべてのビルドとルートファイルシステムの作成を自動化する驚くべきスクリプトセットであるBuildrootのみに依存することを好みます。

そのための非常に詳細で自動化されたヘルパーをhttps://github.com/cirosantilli/linux-kernel-module-cheatにアップロードしました


4
これはおそらくここで最も過小評価されている答えです:D。驚くばかり!
msouth 2017

1
@msouthは少し少ないので今:-)
Ciro Santilli冠状病毒病六四事件法轮功


1

それはあなたの「1つのプログラム」が必要とするものについての詳細です。

LFS(別名「Linux From Scratch」)を構築することで、物事を組み立てる方法を理解するための良いスタートを切ることができます。次に、プログラムに必要なものを追加するか、フルディストリビューションを行います。LFSでGnomeKDEのような重いサブシステムを構築するのは実に簡単なことです。

もちろん、最初は後戻りする方が簡単かもしれませんが、完全なディストリビューションから削除するのは面倒な場合があります。VMでこれを実行し、すべてのステップでこのVMのコピーを実行します。

(2セント)

編集

CentOSUbuntuのような完全なディストリビューションから始めるのではなく、SecurityBeastによって指摘されたように、次のようなディストリビューションツールの構築についても確認することができます。


1

質問する必要があるのは、「1つのプログラム」に何が必要で、どのようなリソースを持っているかです。

幅広いライブラリとサポートバイナリが必要な場合は、「通常の」Linuxディストリビューション(Debianまたは類似)を使用して、ブートプロセスを少しいじるのが最善の方法です。

それはサポートのもののより狭い選択を必要としますが、異なるカーネルモジュールまたはユーザーランドサポートビットを使用するさまざまなハードウェアのネットワークまたはサポートのようなものがまだ必要であり、通常のディストリビューションのディスクスペースオーバーヘッドが必要ない場合は、組み込みディストリビューション(buildrootまたは類似)または多分Linuxのゼロからのアプローチ(ただし、メンテナンスの問題になる可能性があります)

非モジュールカーネルが提供できるものだけが必要な場合は、カーネルで独自のバイナリを直接実行することで機能し、最も軽量なソリューションになる可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.