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

我想build立一个只运行一个二进制程序的专用Linux系统。 该程序通过OpenGL驱动程序控制屏幕并显示模式。 还需要键盘input以configuration模式。 由于运行这个程序将是机器的唯一目的,我不需要任何GUI,networking等。另外,我可能不需要在内核中进行任何进程调度,因为只有一个进程会运行。

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

你可以用你的程序替换/sbin/init ,但你应该知道进程1有一些特定的职责。 所以我认为不可取代它。

请记住,Linux内核也可以神奇地启动一些进程,而不是从init进程继承的进程的通常fork之外。 我正在考虑像/sbin/modprobe/sbin/hotplug

此外, udev (或systemd )还有一些特殊的角色。 在一些系统上,风扇控制与这些事情有关(我真的忘了细节)。 如果不幸的话,如果风扇运行不正常,可能会烧毁硬件(但是在最近的硬件上,AFAIK并不是这样)。

通过在最近的3.15.3内核中寻找string vmlinux ,我发现它知道:

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

我会建议,而不是保留一些现有的init程序,并配置它只运行你的程序。

最小的初始化你好世界程序一步一步

在这里输入图像描述

编译一个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 

我们不能使用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" 

这将在/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 

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

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

关于这个主题的很好的源代码: http : gen_initramfs_list.sh它还解释了如何使用gen_initramfs_list.sh ,它是Linux内核源代码树中的一个脚本来帮助自动化进程。

下一步:安装BusyBox,以便您可以与系统进行交互: https : //github.com/cirosantilli/runlinux

测试Ubuntu 16.10,QEMU 2.6.1。

你可以把你的程序放到initrd中 ,然后从initrd的init中运行它。

只需使用一个启动参数例如) init=/bin/bash

init是进程1,由内核用来启动用户空间,这就像收获儿童周期性清理僵尸一样具体的任务。 听起来你甚至不需要这个。

Linux引导参数你应该知道