最小限の初期化 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 システム コールを使用することはできません。そうしないと、カーネル パニックが発生します。init から正常に終了する唯一の方法は、reboot
でマシンの電源をオフにすることです。 システムコール。
次に:
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"
これにより、/init
に hello world を持つファイルシステムが作成されます これは、カーネルが実行する最初のユーザーランド プログラムです。 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 標準ライブラリの一部です。
/dev/sdX
の USB を使用して実際のハードウェアで実行できます そして:
make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
この件に関する優れた情報源:Tech Tip:How to use 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 にアップロードしました
暗い森に通じる庭の小道である LFS をいじり始めるつもりはありません。
Arch などの初期インストールを十分に制御できるディストリビューション、または Ubuntu サーバーなどのヘッドレス エディションから始めます。これのポイントは、スペースを節約することではなく、init 構成の複雑さを制限することです。ヘッドレス ディストリビューションから始めて、実行したいアプリケーションに GUI が必要な場合は、init によって開始された GUI ログイン (別名、ディスプレイ マネージャーまたは DM) と本格的なデスクトップで終わることなく、それに必要なものを追加できます。
次に、目的に合わせて init システムを構成する方法を学びたいと思います。init なしではできないことに注意してください。init は、目的を達成するための最良の手段である可能性があります。現在、ほとんどの Linux ディストリビューションで使用されている init システムは systemd です。
ここでのポイントは、起動時に init が行うことを最小限に抑えることです。これが、集中したいアプリケーションをサポートするために最小限のソフトウェアを実行するシステムを作成する方法です。これは、基本的にサーバーのセットアップ方法です。ところで、これは一般的なタスクです (文字通り「1 つだけ」のユーザーランド プロセスを実行することはできないことに注意してください。少なくとも有用ではありません)。
実行したいアプリケーションが GUI プログラムの場合 (GUI アプリケーションには X サーバーが必要なため、文字通り 1 つのアプリケーションだけを実行できない理由の良い例です)、 ~/.xinitrc
を持つことができます。 このように見えます;
#!/bin/sh
myprogram
あなたが startx
、あなたのプログラムだけが実行され、デスクトップを変更したり、他のものを起動したりすることはできません。これは、ウィンドウ マネージャーやデスクトップ環境がないためです (したがって、ウィンドウ フレームやタイトルバーもありません)。
プログラミングに少し慣れていて、ゼロから作成したい場合は、LFS、つまり Linux from Scratch http://www.linuxfromscratch.org/
を使用できます。ubutnu をカスタマイズしたい場合は ubunt-builder を使用でき、rpm ベースでそれを使用したい場合は Suse-Studio を使用できます。Suse studio を使用すると、カスタムの suse linux を作成できます
乾杯