我该如何创建自己的“自定义” Linux发行版,该发行版仅运行一个程序,几乎与XBMCbuntu完全相同。
我该如何创建自己的“自定义” Linux发行版,该发行版仅运行一个程序,几乎与XBMCbuntu完全相同。
Answers:
我不会把LFS弄得一团糟,那是一条通往一些黑暗树林的花园小路。
从发行版开始,在发行版中,您可以对初始安装(如Arch)或无头版本(如Ubuntu服务器)进行大量控制。这样做的目的不是要节省空间而是要限制init配置的复杂性。从无头发行版开始,如果要运行的应用程序需要GUI,则可以添加所需的功能,而不必以init启动的GUI登录(也称为显示管理器或DM)和一个功能齐全的桌面为结尾与之相配的环境。
然后,您想学习如何根据自己的目的配置init系统 -请注意,没有init就无法做,这可能是实现目标的最佳方法。在Linux上常用的init有三种变体(但还有其他一些变体):
Debian在经典的Unix SysV样式init上使用了变体。从jessie
发行版开始,Debian也已切换到systemd
(https://wiki.debian.org/systemd)
Ubuntu和衍生产品使用新贵。
Fedora,Arch和派生工具使用systemd。
如果您还不了解其中任何一个,那么它们中的任何一个都不比其他任何一个更难使用。如果您选择后两者之一,则它们提供了一些与SysV向后兼容的机制,但是您不必担心,这并不简单。1个
这里的重点是最小化启动时的初始化,这就是您如何创建一个系统,该系统将运行最少数量的软件来支持您要关注的应用程序-本质上就是服务器的设置方式,顺便说一句,这是一项常见的任务(请注意,您实际上无法运行“仅一个”用户域进程,至少没有用处)。
如果您要运行的应用程序是GUI程序(这是一个很好的示例,说明为什么您不能只运行一个应用程序,因为GUI应用程序需要X服务器),您可以拥有一个~/.xinitrc
类似于以下内容的应用程序;
#!/bin/sh
myprogram
然后startx
,您的程序将是唯一运行的程序,并且将无法更改桌面或启动其他任何操作,部分原因是没有窗口管理器或桌面环境(因此,也将没有窗口框架或标题栏)。
1.稍微弄清楚这一点:在研究此问题时,您可能会从以前熟悉SysV的人那里发现对systemd和新贵的一些困扰,例如,他们太复杂了。但是,从客观上讲,它们并没有比SysV复杂(事实上,IMO systemd使用起来更简单),但是可以说,大多数狗更喜欢它们的老花样。现在这两种系统已经使用了一段时间,这种困扰开始消失了。
init
但可以确定,upstart, systemd,
或者可以说sysv. init
是init
内核挂载时调用的一个可执行文件,initramfs.
在大多数情况下,这三个文件甚至都没有,init
但实际上它们通常是exec
由init,
哪个人编入的busybox.
busybox
因为在单独的答案中应单独对待,而不是我本人。
最小的init hello world程序逐步
编译一个没有任何依赖以无限循环结尾的依赖的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
我们不能使用退出系统调用,否则将无法使用内核崩溃。
然后:
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
,这是内核将运行的第一个用户级程序。我们还可以向其中添加更多文件,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
动态链接将需要设置一个动态链接器可执行文件,其中最常见的是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 shell,可让您更轻松地进行交互式系统实验。
就个人而言,在这一点上,我更喜欢仅依靠Buildroot,这是一组了不起的脚本,可自动从源代码构建所有内容并制作根文件系统。
我在以下位置上传了一个非常详细且自动化的帮助程序:https : //github.com/cirosantilli/linux-kernel-module-cheat
如果您只需要一点编程,并且想从头开始创建它,则可以使用LFS,即Scratch的Linux http://www.linuxfromscratch.org/
如果要自定义ubutnu,则可以使用ubunt-builder;如果要基于rpm,则可以使用SUsE-Studio,Suse studio将允许您自定义suse linux
干杯
它更多地涉及您的“一个程序”的要求。
您仍然可以通过构建LFS(又称“ Linux From Scratch ”)来了解如何将它们组合在一起。然后,您将添加程序所需的内容或进行完整分发,因为在LFS上构建沉重的子系统(如Gnome或KDE)可能是真正的难题。
当然,起初向后走可能会比较容易,但是从完整的发行版中删除内容可能很麻烦:在VM中执行此操作,并在每个步骤中复制此VM。
(我的2美分)
编辑:
正如SecurityBeast指出的那样,您可以从构建完整的分发工具开始,而不是像CentOS或Ubuntu那样从完整的分发开始:
您需要问的是您的“一个程序”需要什么以及您拥有什么资源。
如果它需要多种选择的库和支持二进制文件,则最好使用“常规” Linux发行版(Debian或类似版本),并稍微弄乱引导过程。
如果它需要选择的支持内容比较狭窄,但仍然需要网络或使用不同的内核模块或用户级支持位来支持各种硬件的内容,并且您不希望常规发行版的磁盘空间开销,那么我建议您看一下嵌入式发行版(buildroot或类似版本),或者是从头开始使用linux的方法(尽管这可能会给维护带来麻烦)
如果您只需要一个非模块化内核可以提供的功能,而无需其他任何东西,那么直接在内核上运行自己的二进制文件可能会起作用,并且是最简单的解决方案。
busybox
但这可能不是您想要的。因此,请花一些必要的时间来表达您的需求,我们可能会为您提供帮助。请随时编辑您的问题以在其中添加任何相关元素。