-1

我遇到了一个看起来有点奇怪的东西。

基础机器是 Ubuntu 18.04。我正在尝试创建一个自定义 initramfs + init 脚本,以用于与 qemu 实例一起使用的自定义编译内核。

从我用作 initramfs 基础的目录中:

[~/initramfs] $ find .
.
./proc
./root
./dev
./dev/console
./dev/sda1
./dev/null
./dev/tty
./sbin
./init
./etc
./lib64
./mnt
./mnt/root
./lib
./bin
./bin/busybox
./sys

只是现在需要的基础知识。busybox 二进制文件来自busybox-static 包,我已经确认它是静态编译的:

[~/initramfs]$ ldd bin/busybox
        not a dynamic executable

在初始化脚本中,我有:

#!/bin/busybox sh

mount -t proc none /proc
mount -t sysfs none /sys

echo "Hi there"

umount /sys
umount /proc

poweroff

从那里,创建一个 initramfs.gz:

find . -print0 | cpio --null --create --verbose --format=newc | pigz --best > ~/initramfs.gz

当我将其设置为 qemu 的目标 initrd 时,内核按预期启动,然后:

[    0.777443] Run /init as init process
/init: line 3: mount: not found
/init: line 4: mount: not found
Hi there
/init: line 8: umount: not found
/init: line 9: umount: not found
/init: line 11: poweroff: not found

mount 是busybox 的一部分。所以这很奇怪。

如果我修改 init 脚本并将/bin/busybox sh其作为要执行的第一个命令输入,那么我会如您所愿地进入一个 busybox 外壳。

[    0.789949] Run /init as init process


BusyBox v1.27.2 (Ubuntu 1:1.27.2-2ubuntu3.2) built-in shell (ash)
Enter 'help' for a list of built-in commands.

sh: can't access tty; job control turned off
/ # [    1.364618] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input3
[    1.386482] tsc: Refined TSC clocksource calibration: 3392.105 MHz
[    1.388387] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x30e52cb7a6c, max_idle_ns: 440795310382 ns
[    1.391965] clocksource: Switched to clocksource tsc

/ #

然后帮助显示:

/ # help
Built-in commands:
------------------
        . : [ [[ alias bg break cd chdir command continue echo eval exec[   71.772009] random: fast init done

        exit export false fg getopts hash help history jobs kill let
        local printf pwd read readonly return set shift source test times
        trap true type ulimit umask unalias unset wait [ [[ acpid adjtimex
        ar arp arping ash awk basename blkdiscard blockdev brctl bunzip2
        bzcat bzip2 cal cat chgrp chmod chown chpasswd chroot chvt clear
        cmp cp cpio crond crontab cttyhack cut date dc dd deallocvt depmod
        devmem df diff dirname dmesg dnsdomainname dos2unix dpkg dpkg-deb
        du dumpkmap dumpleases echo ed egrep env expand expr factor fallocate
        false fatattr fdisk fgrep find fold free freeramdisk fsfreeze
        fstrim ftpget ftpput getopt getty grep groups gunzip gzip halt
        head hexdump hostid hostname httpd hwclock i2cdetect i2cdump
        i2cget i2cset id ifconfig ifdown ifup init insmod ionice ip ipcalc
        ipneigh kill killall klogd last less link linux32 linux64 linuxrc
        ln loadfont loadkmap logger login logname logread losetup ls
        lsmod lsscsi lzcat lzma lzop md5sum mdev microcom mkdir mkdosfs
        mke2fs mkfifo mknod mkpasswd mkswap mktemp modinfo modprobe more
        mount mt mv nameif nc netstat nl nproc nsenter nslookup od openvt
        partprobe passwd paste patch pidof ping ping6 pivot_root poweroff
        printf ps pwd rdate readlink realpath reboot renice reset rev
        rm rmdir rmmod route rpm rpm2cpio run-parts sed seq setkeycodes
        setpriv setsid sh sha1sum sha256sum sha512sum shred shuf sleep
        sort ssl_client start-stop-daemon stat static-sh strings stty
        su sulogin svc swapoff swapon switch_root sync sysctl syslogd
        tac tail tar taskset tee telnet telnetd test tftp time timeout
        top touch tr traceroute traceroute6 true truncate tty tunctl
        ubirename udhcpc udhcpd uevent umount uname uncompress unexpand
        uniq unix2dos unlink unlzma unshare unxz unzip uptime usleep
        uudecode uuencode vconfig vi w watch watchdog wc wget which who
        whoami xargs xxd xz xzcat yes zcat

所以我去寻找坐骑,发现也没有找到。哦,但如果我在它前面加上 /bin/busybox 直接调用它,它就可以工作......:

/ # type mount
mount is mount
/ # which mount
sh: which: not found
/ # /bin/busybox which mount
/ #

如果我将 /bin/busybox 添加到它们,我可以成功执行命令:

/ # /bin/busybox mount -t proc none /proc
/ #

似乎真的随机​​,什么可以从busybox工作,什么不能工作,什么可以找到,什么不可以找到,例如find很好:

/ # find
.
./test
./sys
./bin
./bin/busybox
./lib
./mnt
./mnt/root
./lib64
./etc
./init
./sbin
./proc
./root
./dev
./dev/tty
./dev/null
./dev/sda1
./dev/console

我可以通过在 init 文件中的每个命令前面加上 来解决这个问题/bin/busybox,但如果我不必这样做,我真的宁愿不这样做!

4

1 回答 1

1

您必须对所有想要的小程序进行符号链接,例如ln -s /bin/busybox /bin/mount. 请参阅busybox 文档中的用法

用法

BusyBox 是一个多调用二进制文件。多调用二进制文件是一种可执行程序,它与多个实用程序执行相同的工作。这意味着只有一个 BusyBox 二进制文件,但这个二进制文件就像大量实用程序一样。这使得 BusyBox 变得更小,因为所有内置实用程序(我们称它们为小程序)可以共享许多常见操作的代码。

您还可以通过在命令行上发出命令作为参数来调用 BusyBox。例如,输入

    /bin/busybox ls 

也会导致 BusyBox 表现得像 'ls'。

当然,在每个命令中添加 '/bin/busybox' 会很痛苦。所以大多数人会使用 BusyBox 二进制文件的链接来调用 BusyBox。

例如,输入

    ln -s /bin/busybox ls
    ./ls

将导致 BusyBox 表现为 'ls'(如果 'ls' 命令已编译到 BusyBox 中)。一般来说,您永远不需要自己创建所有这些链接,因为 BusyBox 构建系统会在您运行“make install”命令时为您完成这些。

如果您在没有参数的情况下调用 BusyBox,它将为您提供已编译到您的 BusyBox 二进制文件中的小程序列表。

碰巧在没有它的情况下工作的命令是实现为无分叉的命令,因此可以作为内置调用。

于 2019-06-22T05:18:31.053 回答