我想构建一个只运行一个二进制程序的专用 Linux 系统。该程序通过 OpenGL 驱动程序控制屏幕并显示图案。还需要键盘输入来配置模式。由于运行这个程序将是机器的唯一目的,我不需要任何 GUI、网络等。此外,我可能不需要在内核中进行任何进程调度,因为只会运行一个进程。
是否可以用我自己的二进制文件替换/sbin/init 来实现这一点?内核加载后,它会立即执行我自己的二进制文件,并且会在机器开启的整个过程中运行。基本上,我想模拟微 Controller 的工作方式,但好处是能够将 x86 CPU 与不同的硬件设备和驱动程序一起使用。
最佳答案
最小的 init 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
我们不能使用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
您可以在带有 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,以便您可以通过 shell 与系统交互。 Buildroot is a great way to do it .
在 Ubuntu 16.10、QEMU 2.6.1 上测试。
关于c - 想要构建只有一个内核和一个二进制文件的裸 Linux 系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24583614/