好吧,基本上,我正在尝试以类似于WUBI的方式启动Gentoo。我在ext4格式的回送文件上进行了安装,在Windows Bootloader下安装了BURG,并且可用于启动的内核/ initramfs。引导仍然存在一些问题(我认为我可以解决这些问题,这主要是由于程序本身存在一些小问题),但是我的基本思想是:
- 设置busybox并使用mdev获取设备
- 解析命令行选项,确定是否要求真实根或循环根
- 如果是真实根目录,则将其挂载
/root
并切换到根目录,然后执行/sbin/init
。 - 如果是循环根目录,请在上安装主机分区
/host
。 - 在上安装回送(
/host/${LOOP}
)/root
- 移动主机的安装点(
mount -o move /host /root/host
对于busybox) - 将root切换到
/root
并执行/sbin/init
我在init
这里有脚本:
#!/bin/sh
# Rescue shell in case of error.
rescue_shell() {
echo "Something went wrong. Dropping you to a shell."
exec /bin/sh
}
parse_opt() {
case "$1" in
*\=*)
echo "$1" | cut -d= -f2-
;;
esac
}
# Set up BusyBox...
busybox --install -s
# Mount the /proc and /sys filesystems.
mount -t proc none /proc
mount -t sysfs none /sys
# Populate /dev
echo ":: Populating /dev..."
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
# Get command line options...
for x in ${CMDLINE}
do
case "${x}" in
root\=*)
ROOT=`parse_opt "${x}"`
;;
# Loadloop
loop\=*)
LOOP=`parse_opt "${x}"`
;;
ntfsroot)
NTFSROOT=1
;;
esac
done
if [ "${NTFSROOT}" != 1 ]
then
# Mount the root filesystem, plain and simple.
echo ":: Mounting real root..."
mount -o ro "${ROOT}" /mnt/root || rescue_shell
else
# Load up an NTFS-based root.
echo ":: NTFS Root mount requested. Mounting..."
ntfs-3g "${ROOT}" /host
if [ -f "/host/${LOOP}" ]
then
mount -o loop,ro "/host/${LOOP}" /root || rescue_shell
echo ":: Mounted. Moving host..."
mount -o move /host /root/host || rescue_shell
echo ":: Mounted."
else
"!! ERROR: Invalid/nonexistant loop given!"
rescue_shell
fi
fi
# Clean up.
umount /proc
umount /sys
# Boot the real thing.
echo ":: Switching to root and calling init..."
exec switch_root /root /sbin/init
没什么复杂的,真的。NTFS-3G显然不同意mount
and 的busybox实现(出于某种原因,它添加了参数-i并ntfs-3g
淘汰了),因此我正在考虑仅复制coreutils
实现或其他内容。那,我需要检查安装环回分区所需的内容(当我尝试手动安装环回时,它会给我类似“找不到文件”的错误)。不过,我认为这些很容易自行解决。
但是,我有点想知道的是关机。一旦switch_root
完成后,系统会留下一个/
回送挂载文件/dev/sda2
(这是Windows 7安装)上/host
。现在,没有任何方法可以卸载/host
,因为它正在使用中。但是,/
当根目录在子目录中挂载文件系统时,无法卸载。基于WUBI的Ubuntu安装必须面临同样的难题。如何解决这个问题?这是鸡肉和鸡蛋的问题,这真的让我很烦。
我正在考虑启动脚本的内容,该脚本为基本的基本根目录保存文件的临时缓存(如initramfs,但反之亦然)。它将最后运行,将文件复制到tmpfs,旋转根目录,也许将其放回initramfs的原始布局。我基本上是这样做的:
- 安装
tmpfs
在/tmp/shutdown/
或其他地方。 - 复制关闭文件(可能是
/usr/share/shutdown/
某事) pivot_root
将根目录移动到/loop
chroot并添加到tmpfs中。mount --move
在/loop/host
以/host
- 卸下
/loop
- 卸下
/host
- 由于所有分区均已卸载,因此请干净关闭。
但是,我从未对Gentoo进行过如此多的修改。初始化脚本可能吗?我不希望此内容被对baselayout的任何更新或任何ebuild覆盖,因为那样会使我失去正常的关闭功能(我真的不想丢失主机分区)。还有一个问题就是弄清楚Gentoo的init系统是否甚至支持这样的东西。看起来足够干净(如果有点破旧),但是我不太确定。我想知道Ubuntu是否做不同的事情,如果是这样,怎么做?任何的意见都将会有帮助。
编辑:
我启动了靴子。就像我想的那样,只需使用的coreutils
版本即可mount
。但是,我遇到了关机时预期的错误;由于无法卸载文件系统而出现的错误以及使用环回FS记录日志的错误。我不知道该如何解决。
编辑2:
好吧,好吧,我正在做些事情。我基本上进行了编辑/etc/init.d/{halt.sh,reboot.sh,shutdown.sh}
,并执行以下操作:
- 已添加
/host
到RC_NO_UMOUNTS
变量中,该变量可阻止EXT4模块因日志错误而阻塞 - 添加
-o `pidof ntfs-3g`
到选项中killall5
(以确保它不会杀死ntfs-3g) - 修改了shutdown.sh和restart.sh以在/ boot / shutdownfs上挂载tmpfs,并在其中复制一些initramfs文件,旋转根目录,然后将chroot插入其中,调用/ down或/ restart。
- 这两个脚本实际上执行了一些快速而又肮脏的/ proc和/ sys设置,将/ root / host移至/ host,然后进行了懒惰卸载。我无法正常卸载(文件系统仍然很忙),但是至少这似乎阻止了文件系统完全呕吐。
该解决方案仍不理想,因此将不胜感激。