如何创建运行单个应用程序的Linux系统?


12

我正在尝试运行一个Linux应用程序,而我想要运行的只是这个应用程序没有启动。我需要网络,这就是全部(没有显示器,外围设备等)。我不希望其他应用程序运行,以便我运行的应用程序具有100%的CPU。这可能吗?


由于您的操作系统仍需要一些资源,因此无法抓住100%的CPU。
n0pe

@MaxMackie显然,但我希望操作系统只能代表应用程序接管(例如用于网络)。
dschatz

1
你意识到即使加载了桌面环境,但坐在那里闲置,它也没有使用任何CPU时间吗?如果其他应用程序需要它,它正在使用的ram可能会被换掉。
psusi

@dschatz如果您在问题中包含更多详细信息,这将有所帮助。就像告诉我们更多关于你想要运行什么应用程序,你希望它如何执行以及你正在使用什么类型的硬件。
N.N.

如果可能的话,我想知道您为什么要这样做。根据我的理解,你想要删除 一切 从操作系统(包括控制台)只是为了运行你的应用程序。性能提升将是微不足道的,那么所有这些工作的重点是什么?
nmat

Answers:


8

最小的initrd CPIO hello world程序一步一步

enter image description here

编译一个没有任何以无限循环结束的依赖关系的hello世界。 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

我们不能用 sys_exit,否则内核恐慌。

然后:

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"

这创建了一个带有我们的hello world的文件系统 /init,这是内核将运行的第一个userland程序。我们还可以添加更多文件 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

您可以使用USB打开真实硬件 /dev/sdX 和:

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

这个主题的重要来源: http://landley.net/writing/rootfs-howto.html 它还解释了如何使用 gen_initramfs_list.sh,这是来自Linux内核源代码树的脚本,用于帮助自动化该过程。

下一步:设置BusyBox,以便您可以与系统进行交互: https://unix.stackexchange.com/questions/2692/what-is-the-smallest-possible-linux-implementation/203902#203902

在Ubuntu 16.10,QEMU 2.6.1上测试。


3

听起来你正试图建立一个 。互联网上的大多数指南都集中在像Firefox这样的Web浏览器上,作为运行的单个应用程序。看一眼 本指南 为了想法。


2
嗯,我真的只是想用网络运行一个应用程序。我不希望任何X和尽可能少的其他应用程序运行。我没有看到这如何限制所有不必要的守护进程运行。
dschatz

应用程序可以运行没有X虽然?
Journeyman Geek

3

你可以启动内核 init=/path/to/myapp 引导加载程序中定义的参数。


2
这是一个相当极端的解决方案。使用用户应用程序替换启动脚本将使应用程序在没有网络的情况下运行,除了挂载rootfs之外没有任何文件系统(没有sysfs或proc或tmpfs),并且可能不会创建某些设备节点。
sawdust

2
@sawdust:完全同意。但问题也有点极端...... :-)
Michał Šrajer

2

在启动内核后,您当然可以只运行一个用户应用程序。但它不会有100%的CPU,因为必须存在一些其他与内核相关的进程。这通常在嵌入式Linux设备中完成,例如,无线路由器。我还拥有为多线程应用程序执行此操作的第一手经验。

内核启动后,将运行初始化或启动脚本。阅读Linux 运行级别 和init进程。有各种启动方案正在使用中,因此不可能具体。但Linux将允许您准确配置哪些应用程序和守护程序将根据您的情况执行。除了root用户的启动文件外,还需要修改的文件 /等等 特别是 /etc/init.d中

顺便说一句,除非你是超级程序员的某些人,或者在你运行远程GDB服务器之前,你需要为你的应用程序提供一些调试控制台(PC控制台或串口)。这将允许您收到seg故障,总线错误和断言失败的通知。所以除了“网络”之外,还要计划拥有一些“外围”。


2

如果您真的只想要Linux内核,网络和应用程序,那么唯一的方法是:

  • 您需要将应用程序作为内核模块 - 确保它已经过调试和测试。这个内核模块必须初始化通常通过用户空间完成的事情,例如设置接口IP地址和所有好东西。
  • 您需要下载和配置( make menuconfig )您自己的自定义内核,并删除与运行系统和网络无关的所有功能。您将要禁用阻止层,我不知道如何在最近的内核上执行此操作 make menuconfig
  • 然后,您需要将模块包含在内核中,以便将其作为内核的一部分包含在内,而不是可加载的模块。您可能会在上面的步骤中禁用可加载模块。如果您了解足够的C / C ++来创建内核模块,那么这应该很容易。
  • 您需要修改内核的任何部分,如果发生恐慌 init 没有做到这一点,或准备好与一个额外的用户空间进程一起生活。

我知道内核模块可以创建进程 - 这很简单 ps aux 会在一个典型的系统上显示很多(它们都在括号中)。您可能希望模块创建内核进程。要除掉你的所有内核创建的进程,你需要禁用线程[ kthreadd ], 能源管理 [ pm ],事件层[ events ], 和别的。


如果您想要更实用的内核+ 1用户空间进程设置,那是可能的。

Linux有一个名为的内核命令行选项 init= - 这是内核在加载完成后启动的内容。该程序必须位于指定的根设备上 root= 或者在initrd中(由引导加载程序加载)。

如果这个程序退出,Linux将会出现恐慌,所以请确保它不会退出。

Linux的许多现代发行版都设置了它 init initrd中的程序在启动之前会执行一些额外的用户空间初始化 /sbin/init 要么 /sbin/systemd。你必须找出你的发行版在这里做什么(Debian的信息是 这里 并找到你可以在哪里指定最终的“切换”程序,并从那里你可以告诉它启动你的应用程序而不是 init 要么 systemd

systemd 管理很多基本功能,比如建设 /dev,设置主机名和其他东西,所以如果你很灵活,你可能想要考虑配置 systemd 生成单个进程,如果失败则可选择重新启动它。如果我没有弄错,它基本上是为单用户或恢复模式做的 - 它启动一个shell。

你将有2个进程在运行( systemd 如果你的程序退出或崩溃,系统不会出现恐慌。

还要考虑简单的Debian轻量级安装 - “netinst”安装除了内核,shell和一些服务之外没有太多运行 - 或者考虑OpenWRT / LEDE - 它有一个默认运行的Luci网络服务器和一个结合其他服务,但很容易被禁用。


1

有些系统应用程序必须运行,除此之外,当然,您可以将其余的计算机资源专用于该应用程序。为了获得最低限度,您可以查看像TinyCore Linux等非常小的Linux发行版。

此外,它还取决于应用程序本身,除网络之外还需要哪些服务等。

我想如果你能提供更具体的信息,你会得到更详细的回复。

喜欢什么样的应用等


我的应用程序使用pthread库来运行一些多线程工作负载(算术运算),并可以指示根据tcp / ip的输入执行不同的计算。看看TinyCore Linux,它会引导到一个我不想要的完整桌面环境。
dschatz

TinyCore有一个叫做MicroCore的小兄弟。没有GUI,请查看。
n0pe

1
@MaxMackie我实际上想要在tcp / ip堆栈之外的机器上没有接口。应用程序可以阻塞端口,并可以通过发送到该端口的tcp数据包进行控制。
dschatz

1
我建议一个运行很少服务的环境(检查一下) linuxhelp.blogspot.com/2006/04/... )除了你的应用程序和安装的依赖项之外几乎没有任何东西。
n0pe

1
@dschatz好吧,然后你需要破解内核,删除其他所有内容并将你的应用程序编译进去。没有bash没有别的。只是你的app..lol。
bakytn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.