簡體   English   中英

想要構建只有內核和一個二進制文件的裸Linux系統

[英]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
  • / bin / sh的
  • / sbin目錄/請求密鑰
  • / sbin目錄/知世-INIT
  • / sbin目錄/ modprobe的
  • / sbin目錄/關機
  • / sbin目錄/熱插拔

我建議改為保留一些現有的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

關於這個主題的很好的來源: httpgen_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,由內核用來啟動用戶空間,作為一些特定的職責,比如收獲兒童期刊來清理僵屍。 聽起來你甚至都不需要那樣。

您應該知道的Linux Boot參數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM