[英]Want to build bare Linux system that has only a kernel and one binary
我想構建一個只運行一個二進制程序的專用Linux系統。 該程序通過OpenGL驅動程序控制屏幕並顯示模式。 還需要鍵盤輸入來配置模式。 由於運行這一個程序將是機器的唯一目的,我不需要任何GUI,網絡等。此外,我可能不需要在內核中進行任何進程調度,因為只有一個進程將運行。
有可能用我自己的二進制文件替換/ sbin / init來實現這個目的嗎? 在內核加載之后,它會立即執行我自己的二進制文件,這將在機器運行的整個時間內運行。 基本上,我想模仿微控制器的工作方式,但能夠使用具有不同硬件設備和驅動程序的x86 CPU。
可能有可能用你的程序替換/sbin/init
,但你應該知道進程1有一些特定的職責。 所以我認為不宜更換它。
請記住,Linux內核也可以在init進程繼承的進程的通常fork
之外神奇地啟動某些進程。 我在/sbin/modprobe
或/sbin/hotplug
等。
此外, udev
(或systemd
)也有一些特殊的角色。 在某些系統上,風扇控制與這些事情有關(我真的忘記了細節)。 如果運氣不好,如果風扇運行不正常,你可以燒掉你的硬件(但AFAIK在最近的硬件上並不是這樣)。
通過在最近的3.15.3內核中使用string
查找vmlinux
,我發現它知道:
我建議改為保留一些現有的init程序,並將其配置為僅運行程序。
最小的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
我們不能使用sys_exit
,否則內核會發生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的文件系統,這是內核將運行的第一個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
您可以在/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,以便您可以通過shell與系統進行交互。 Buildroot是一個很好的方法 。
在Ubuntu 16.10,QEMU 2.6.1上測試。
您可以將程序放到initrd ,然后從initrd的init運行它。
只需使用啟動參數,例如init=/bin/bash
init是進程1,由內核用來啟動用戶空間,作為一些特定的職責,比如收獲兒童期刊來清理僵屍。 聽起來你甚至都不需要那樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.