Хорошо, в общем, я пытаюсь загрузить Gentoo способом, похожим на WUBI; У меня есть установка на файл loopback в формате ext4, BURG установлен под загрузчиком Windows и ядро /initramfs, доступные для загрузки. У загрузки все еще есть некоторые проблемы (те, которые, я думаю, я могу решить, они в основном из-за небольших проблем с самими программами), но у меня есть основная идея:
- Настройте busybox и получайте устройства с mdev
- Разберите параметры командной строки, определите, запрашиваете ли вы настоящий root или loop root
- Если настоящий root, подключите его к
/root
и переключите root, выполните/sbin/init
. - Если корень цикла, смонтировать раздел хоста в
/host
. - Смонтировать loopback (
/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, очевидно, не согласен с реализацией busybox для mount
и прочего (он почему-то добавляет параметр -i, а ntfs-3g
вырубается), поэтому я подумываю просто скопировать реализацию coreutils
или что-то еще. Это, и мне нужно проверить, что нужно для монтирования петлевых разделов (при попытке монтирования петлевого ввода вручную появляется ошибка типа "Файл не найден"). Тем не менее, я думаю, что это достаточно легко понять самостоятельно.
Тем не менее, то, о чем я как бы удивляюсь - это отключение. После завершения switch_root
в системе останется файл, смонтированный в /
loopback, и /dev/sda2
(это установка для Windows 7) на /host
. Теперь нет способа размонтировать /host
, так как он используется. Однако нельзя размонтировать /
пока корень имеет файловые системы, смонтированные в подкаталоге. Установки Ubuntu на основе WUBI должны сталкиваться с той же дилеммой. Как преодолеть эту проблему? Это проблема курицы и яйца, и это меня очень раздражает.
Я рассматривал что-то вроде загрузочного скрипта, который содержит временный кеш файлов для базового базового корня (например, initramfs, но наоборот). Он запускался последним, копируя файлы в tmpfs, поворачивая корень, возможно, возвращая его к исходной компоновке initramfs. По сути, я бы делал это:
- Смонтируйте
tmpfs
в/tmp/shutdown/
или что-то еще. - Скопируйте файлы завершения работы (возможно,
/usr/share/shutdown/
или что-то еще) pivot_root
чтобы переместить корень в/loop
и выполнить chroot в tmpfs.mount --move
/loop/host
to/host
- Размонтировать
/loop
- Размонтировать
/host
- Отключите чисто, так как все разделы были размонтированы.
Тем не менее, я никогда не изменял Gentoo так сильно. Это возможно с initscript? Я не хочу, чтобы это было перезаписано какими-либо обновлениями baselayout или любого другого ebuild, так как это оставило бы меня с нарушенной функциональностью завершения работы (и я действительно не хочу терять раздел хоста). Существует также проблема выяснения, поддерживает ли система инициализации Gentoo что-то подобное. Это кажется достаточно чистым (если немного хакерским), но я не слишком уверен в этом. Я хочу знать, если 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, чтобы смонтировать tmpfs в /boot /shutdownfs и скопировать туда некоторые файлы initramfs, повернуть корневой каталог, а затем выполнить chroot в него, вызвав либо /down, либо /restart.
- Эти два сценария по сути выполняют быструю и грязную настройку /proc и /sys, перемещают /root /host в /host, а затем выполняют ленивое размонтирование. Я не мог заставить работать регулярные размонтирования (файловая система все еще была бы занята), но, по крайней мере, это, кажется, мешает файловым системам полностью рвать.
Это решение все еще не отвечает требованиям, поэтому любая помощь будет принята с благодарностью.