我遇到了一个奇怪的地方。
基本计算机是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 shell。
[ 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
.
./test
./sys
./bin
./bin/busybox
./lib
./mnt
./mnt/root
./lib64
./etc
./init
./sbin
./proc
./root
./dev
./dev/tty
./dev/null
./dev/sda1
./dev/console
我可以通过在初始化文件中的每个命令前面加上/bin/busybox
来解决此问题,但是如果不需要,我宁愿不这样做!
答案 0 :(得分:1)
您必须符号链接所需的所有小程序,例如ln -s /bin/busybox /bin/mount
。参见USAGE in the busybox docs:
用法
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二进制文件中的小程序列表。
没有它的情况下可以正常运行的命令是无fork实现的,因此可以作为内置函数调用。