想要构建只有内核和一个二进制文件的裸Linux系统

Syn*_*tix 3 c linux hardware kernel linux-kernel

我想构建一个只运行一个二进制程序的专用Linux系统.该程序通过OpenGL驱动程序控制屏幕并显示模式.还需要键盘输入来配置模式.由于运行这一个程序将是机器的唯一目的,我不需要任何GUI,网络等.此外,我可能不需要在内核中进行任何进程调度,因为只有一个进程将运行.

有可能用我自己的二进制文件替换/ sbin/init来实现这个目的吗?在内核加载之后,它会立即执行我自己的二进制文件,这将在机器运行的整个时间内运行.基本上,我想模仿微控制器的工作方式,但能够使用具有不同硬件设备和驱动程序的x86 CPU.

Bas*_*tch 5

可能有可能/sbin/init 由您的程序替换,但您应该知道进程1有一些特定的职责.所以我认为不宜更换它.

请记住,Linux内核也可以神奇地启动某些进程,而不是通常fork来自init进程继承的进程.我正在考虑像/sbin/modprobe/sbin/hotplug 等等.

此外,udev(或systemd)有一些特殊的角色.在某些系统上,风扇控制与这些事情有关(我真的忘记了细节).如果运气不好,如果风扇运行不正常,你可以烧掉你的硬件(但AFAIK在最近的硬件上并不是这样).

通过与寻求stringvmlinux 在最近的3.15.3内核,我发现它知道:

  • /斌/ INIT
  • / bin/sh的
  • / sbin目录/请求密钥
  • / sbin目录/知世-INIT
  • / sbin目录/ modprobe的
  • / sbin目录/关机
  • / sbin目录/热插拔

我建议改为保留一些现有的init程序,并将其配置为仅运行程序.


Cir*_*四事件 5

最小的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
Run Code Online (Sandbox Code Playgroud)

我们不能使用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"
Run Code Online (Sandbox Code Playgroud)

这将创建一个带有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"
Run Code Online (Sandbox Code Playgroud)

你应该看到一条线:

FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR
Run Code Online (Sandbox Code Playgroud)

在模拟器屏幕上!请注意,它不是最后一行,因此您需要进一步了解.

如果您静态链接它们,也可以使用C程序:

#include <stdio.h>
#include <unistd.h>

int main() {
    printf("FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR FOOBAR\n");
    sleep(0xFFFFFFFF);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有:

gcc -static init.c -o init
Run Code Online (Sandbox Code Playgroud)

您可以在USB上运行真实硬件,/dev/sdX并且:

make isoimage FDINITRD="$ROOTFS_PATH"
sudo dd if=arch/x86/boot/image.iso of=/dev/sdX
Run Code Online (Sandbox Code Playgroud)

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

下一步:设置BusyBox,以便您可以通过shell与系统进行交互.Buildroot是一个很好的方法.

在Ubuntu 16.10,QEMU 2.6.1上测试.