busybox 初始化脚本。未找到装载
busybox init script. Mount not found
我 运行 似乎有点奇怪。
基础机器是 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
来解决这个问题,但如果不需要的话我真的宁愿不这样做!
您必须符号链接所有您想要的小程序,例如ln -s /bin/busybox /bin/mount
。见 USAGE in the busybox docs:
USAGE
BusyBox is a multi-call binary. A multi-call binary is an
executable program that performs the same job as more than one utility
program. That means there is just a single BusyBox binary, but that
single binary acts like a large number of utilities. This allows
BusyBox to be smaller since all the built-in utility programs (we call
them applets) can share code for many common operations.
You can also invoke BusyBox by issuing a command as an argument on the
command line. For example, entering
/bin/busybox ls
will also cause BusyBox to behave as 'ls'.
Of course, adding '/bin/busybox' into every command would be painful.
So most people will invoke BusyBox using links to the BusyBox binary.
For example, entering
ln -s /bin/busybox ls
./ls
will cause BusyBox to behave as 'ls' (if the 'ls' command has been compiled into BusyBox). Generally speaking, you should never
need to make all these links yourself, as the BusyBox build system
will do this for you when you run the 'make install' command.
If you invoke BusyBox with no arguments, it will provide you with a
list of the applets that have been compiled into your BusyBox binary.
在没有它的情况下碰巧工作的命令是作为 fork-free 实现的命令,因此可以作为内置命令调用。
我 运行 似乎有点奇怪。
基础机器是 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
来解决这个问题,但如果不需要的话我真的宁愿不这样做!
您必须符号链接所有您想要的小程序,例如ln -s /bin/busybox /bin/mount
。见 USAGE in the busybox docs:
USAGE
BusyBox is a multi-call binary. A multi-call binary is an executable program that performs the same job as more than one utility program. That means there is just a single BusyBox binary, but that single binary acts like a large number of utilities. This allows BusyBox to be smaller since all the built-in utility programs (we call them applets) can share code for many common operations.
You can also invoke BusyBox by issuing a command as an argument on the command line. For example, entering
/bin/busybox ls
will also cause BusyBox to behave as 'ls'.
Of course, adding '/bin/busybox' into every command would be painful. So most people will invoke BusyBox using links to the BusyBox binary.
For example, entering
ln -s /bin/busybox ls ./ls
will cause BusyBox to behave as 'ls' (if the 'ls' command has been compiled into BusyBox). Generally speaking, you should never need to make all these links yourself, as the BusyBox build system will do this for you when you run the 'make install' command.
If you invoke BusyBox with no arguments, it will provide you with a list of the applets that have been compiled into your BusyBox binary.
在没有它的情况下碰巧工作的命令是作为 fork-free 实现的命令,因此可以作为内置命令调用。