GoldRenard

Метод реализации мультибута почти на любом Android устройстве.

В этой теме 75 сообщений

Данная статья рассчитана на Ромоделов и продвинутых пользователей. Автор не несет никакой ответственности за порчу вашего оборудования. Вы должны понимать, что вы делаете.



Все мы используем кастомы. Многие здесь помогают народу с их глупыми и не очень проблемами.
В то время как вы сидите на своем кастоме, а просящий о помощи, например, на стоковой прошивке, в зависимости от вопроса вы можете и не помнить "что там и как" чтобы помочь человеку. Все мы в какой-то степени ленивы, без исключений. Так вот именно лень подтолкнула меня на реализацию подобной вещи. Лень шиться обратно на сток :D Да и вообще не всегда имеется эта возможность.

Моей целью была реализация хранения в телефоне нескольких прошивок и беспроблемного переключения между ними. Возможно эта реализация костыльная и является "изобретенным велосипедом", но главное работает и это реально удобно.
Идея состоит в том, чтобы модифицировать ramdisk бута таким образом, чтобы в зависимости от каких-то внешних факторов (в моем случае это файлы-флаги на разделе /cache) загружалась та или иная прошивка. Либо вшитая в телефон, либо из нужных мне ext4-образов на встроенной памяти телефона (FAT32-раздел) или карте памяти. Я не хотел извращаться с разметкой карт памяти на реальные разделы, это было бы не очень удобно.

Я реализовал это подменой бинарника init на свой sh-скрипт, который:
  • Инициализирует окружение (/proc, /sys) и необходимые устройства - /dev/input/*, /dev/block/mmcblk* для возможности работать с ФС
  • Монтирует разделы (встроенная память, карта памяти, cache)
Далее начинается вся магия.
  • Первая попытка загрузки - при наличии файла-флага loadnand на разделе cache необходимо загружать стоковую ОС. В этом случае мы другим sh-скриптом возвращаем оригинальный init на свое место, делаем некоторую очистку (размонтируем все, устанавливаем другие флаги) и запускаем его. Запускается вшитая в телефон прошивка.
  • Вторая попытка загрузки - при наличии файлов-флагов systemimg, dataimg и (опционально) rootfs необходимо загружать ОС с карты памяти. Каждый файл-флаг содержит в себе пути до нужных нам ext4-образов, а rootfs - путь до папки с пользовательским ramdisk. Указанные образы монтируются как /system и /data, при наличии пользовательского ramdisk, из указанной папки копируется все содержимое в текущий работающий рамдиск. Если пользовательский рамдиск (то есть папка с его содержимым) не указан, в качестве рабочего init.rc используется init.sdcard.rc. Последний представляет собой обычный init.rc, но в секции on fs не содержащий команды монтирования разделов из EMMC. Пользовательский также не должен содержать команды монтирования. Опять возвращаем оригинальный init на место, чистим мусор, запускаем.
Вроде бы на этом все, но только осталась одна проблемка - как и когда создавать эти файлы-флаги? Можно было бы вручную из текущей запущенной прошивки. Но это не наш метод х)
Далее после некоторых экспериментов я решил эту проблему встраиванием в рамдиск бута, как бы странно это не звучало, Recovery. Ага, его самого. В качестве подопытного был взят имеющийся на мой телефон сборки TWRP, который был успешно добавлен в мой рамдиск. Он, кстати, несет за собой жизненно необходимый для работы данного метода busybox.

init.rc от Recovery в рамдиске переименован как init.bootmgr.rc. Он несет в себе одну-единственную модификацию - старт сервиса /sbin/recovery с аргументом -u=/boot/BootManager.zip. Этот аргумент позволит без всяких вопросов при запуске Рекавери запустить нужный нам ZIP.

Продолжим изучать магию:

После безуспешных попыток запустить либо вшитую, либо стороннюю прошивку (в связи с отсутствием файлов-флагов), мы сперва ищем на картах памяти ZIP-Пакет (ну, обновлением его уже не назовешь :D ) <корень_карты>/BootManager/BootManager.zip. Если мы его находим, копируем его в /boot/BootManager.zip и запускаем Recovery, подменяя init.rc на init.bootmgr.rc. Если не находим, ничего не меняем и возвращаем оригинальный init на место, очищаем, запускаем. Мы ничего не меняли, в этом случае будет запускаться вшитая прошивка как ни в чем не бывало.


О "загрузчике" все, вот такой вот получился шелл-скрипт:
#!/sbin/sh# Author: GoldRenard# License: GPL# ===============================================================# 					Переменные и инициализация# ===============================================================BOOT_DIR="/boot"EMMC_FAT_MOUNT_POINT="$BOOT_DIR/sdcard1"SDCARD_MOUNT_POINT="$BOOT_DIR/sdcard2"CACHE_MOUNT_POINT="$BOOT_DIR/cache"BM_CACHE_DIR="$CACHE_MOUNT_POINT/BootManager"BM_DIR="BootManager"EMMC_FAT_PARTITION=/dev/block/mmcblk0p6SDCARD_PARTITION=/dev/block/mmcblk1CACHE_PARTITION=/dev/block/mmcblk0p4echo "Begin initialization!" > $BOOT_DIR/logecho "BOOT_DIR is $BOOT_DIR" >> $BOOT_DIR/logecho "EMMC_FAT_MOUNT_POINT is $EMMC_FAT_MOUNT_POINT" >> $BOOT_DIR/logecho "SDCARD_MOUNT_POINT is $SDCARD_MOUNT_POINT" >> $BOOT_DIR/logecho "CACHE_MOUNT_POINT is $CACHE_MOUNT_POINT" >> $BOOT_DIR/logecho "BM_CACHE_DIR is $BM_CACHE_DIR" >> $BOOT_DIR/logecho "BM_DIR is $BM_DIR" >> $BOOT_DIR/logecho "EMMC_FAT_PARTITION is $EMMC_FAT_PARTITION" >> $BOOT_DIR/logecho "SDCARD_PARTITION is $SDCARD_PARTITION" >> $BOOT_DIR/logecho "CACHE_PARTITION is $CACHE_PARTITION" >> $BOOT_DIR/logmkdir -m 0700 $BOOT_DIRmkdir -m 0700 $EMMC_FAT_MOUNT_POINTmkdir -m 0700 $SDCARD_MOUNT_POINTmkdir -m 0700 $CACHE_MOUNT_POINT# ===============================================================# 					Используемые функции# ===============================================================# Функция ошибки, в которой будет записываться причина,# а потом запускаться ОС из EMMCfail() {	echo "$1" > $BOOT_DIR/log	clean	exec /init_android_start $@    exit 1}# Функция очистки окруженияclean() {	# Устанавливаем флаги последней загрузки	echo "Saving last configuration..." >> $BOOT_DIR/log	rm -f $BM_CACHE_DIR/last_loadnand	rm -f $BM_CACHE_DIR/last_systemimg	rm -f $BM_CACHE_DIR/last_dataimg	rm -f $BM_CACHE_DIR/last_rootfs	mv -f $BM_CACHE_DIR/loadnand $BM_CACHE_DIR/last_loadnand	mv -f $BM_CACHE_DIR/systemimg $BM_CACHE_DIR/last_systemimg	mv -f $BM_CACHE_DIR/dataimg $BM_CACHE_DIR/last_dataimg	mv -f $BM_CACHE_DIR/rootfs $BM_CACHE_DIR/last_rootfs	mv -f $BOOT_DIR/log $BM_CACHE_DIR/last_log	# Размонтируем временные разделы	umount $EMMC_FAT_MOUNT_POINT	umount $SDCARD_MOUNT_POINT	umount $CACHE_MOUNT_POINT	# Нам нужно, чтобы /etc в ОС стал симлинком на /system/etc (это делается в init.rc)	# Поэтому сносим текущий (от рамдиска) от греха подальше.	rm -f -r /etc}#функция инициализации файловой системы и устройствmakedevs() {	# Монтирование окружения	echo "Mounting environment" >> $BOOT_DIR/log	mount -t proc proc /proc	mount -t sysfs sys /sys	# Создание узлов устройств	echo "Creating dev nodes" >> $BOOT_DIR/log	mkdir -m 0777 /dev/block	mknod -m 0666 /dev/block/mmcblk0 b 179 0	mknod -m 0666 /dev/block/mmcblk0p1 b 179 1	mknod -m 0666 /dev/block/mmcblk0p2 b 179 2	mknod -m 0666 /dev/block/mmcblk0p3 b 179 3	mknod -m 0666 /dev/block/mmcblk0p4 b 179 4	mknod -m 0666 /dev/block/mmcblk0p5 b 179 5	mknod -m 0666 /dev/block/mmcblk0p6 b 179 6	mknod -m 0666 /dev/block/mmcblk1 b 179 96	mknod -m 0666 /dev/block/mmcblk1p1 b 179 97	mknod -m 0666 /dev/block/mmcblk1p2 b 179 98	mknod -m 0666 /dev/block/mmcblk1p3 b 179 99	mknod -m 0666 /dev/block/mmcblk1p4 b 179 100	mknod -m 0666 /dev/block/mmcblk1p5 b 179 101	mknod -m 0666 /dev/block/mmcblk1p6 b 179 102	mknod -m 0666 /dev/block/mmcblk1p7 b 179 103	mkdir -m 0777 /dev/input	mknod -m 0644 /dev/input/mouse c 13 32	mknod -m 0644 /dev/input/mice c 13 63	mknod -m 0644 /dev/input/event0 c 13 64	mknod -m 0644 /dev/input/event1 c 13 65	mknod -m 0644 /dev/input/event2 c 13 66	mknod -m 0644 /dev/input/event3 c 13 67	mknod -m 0644 /dev/input/event4 c 13 68	mknod -m 0644 /dev/input/event5 c 13 69	mknod -m 0644 /dev/input/event6 c 13 70	mknod -m 0644 /dev/input/event7 c 13 71	mknod -m 0666 /dev/null c 1 3	mknod -m 0444 /dev/zero c 1 5	mknod -m 0644 /dev/ppp c 108 0	mknod -m 0644 /dev/BOOT c 253 0	# Ожидание инициализации EMMC памяти	while [ ! -b $CACHE_PARTITION ]; do		echo "Waiting for cache partition"		sleep 1	done	# Ожидание инициализации EMMC памяти	while [ ! -b $EMMC_FAT_PARTITION ]; do		echo "Waiting for internal memory"		sleep 1	done		# Ожидание инициализации EMMC памяти	while [ ! -b $SDCARD_PARTITION ]; do		echo "Waiting for extermal SD-Card"		sleep 1	done}# Функция монтирования необходимых разделовmountdevs() {	echo "Mounting devices" >> $BOOT_DIR/log	echo "Mounting cache partition ([/dev/block/$CACHE_PARTITION] to [$CACHE_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t ext4 -o rw,nosuid,nodev,noatime,user_xattr,barrier=1,data=ordered,noauto_da_alloc $CACHE_PARTITION $CACHE_MOUNT_POINT	[ $? == 0 ] || echo "Failed to mount the external SD card." >> $BOOT_DIR/log	mkdir -m 777 $BM_CACHE_DIR		echo "Mounting internal memory ([/dev/block/$EMMC_FAT_PARTITION] to [$EMMC_FAT_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime $EMMC_FAT_PARTITION $EMMC_FAT_MOUNT_POINT	[ $? == 0 ] || echo "Failed to mount the internal memory." >> $BOOT_DIR/log		echo "Searching and mounting the first FAT32 partition of external SD-Card " >> $BOOT_DIR/log	echo "Trying to mount ([/dev/block/$SDCARD_PARTITION] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime $SDCARD_PARTITION $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		echo "Trying to mount ([/dev/block/${SDCARD_PARTITION}p1] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime ${SDCARD_PARTITION}p1 $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		echo "Trying to mount ([/dev/block/${SDCARD_PARTITION}p2] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime ${SDCARD_PARTITION}p2 $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		echo "Trying to mount ([/dev/block/${SDCARD_PARTITION}p3] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime ${SDCARD_PARTITION}p3 $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		echo "Trying to mount ([/dev/block/${SDCARD_PARTITION}p4] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime ${SDCARD_PARTITION}p4 $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		echo "Trying to mount ([/dev/block/${SDCARD_PARTITION}p5] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime ${SDCARD_PARTITION}p5 $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		echo "Trying to mount ([/dev/block/${SDCARD_PARTITION}p6] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime ${SDCARD_PARTITION}p6 $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		echo "Trying to mount ([/dev/block/${SDCARD_PARTITION}p7] to [$SDCARD_MOUNT_POINT])" >> $BOOT_DIR/log	mount -t vfat -o fmask=0111,dmask=0000,rw,utf8,noatime,nodiratime ${SDCARD_PARTITION}p7 $SDCARD_MOUNT_POINT	[ $? == 0 ] && return 0		#fail "Failed to mount the external SD card."	echo "Failed to mount the external SD card." >> $BOOT_DIR/log}# функция попытки запуска встроенной ОС при наличии соответствующего файла-флага,# путь до которого передан аргументомtry_loadnand() {	[ $# -eq 0 ] && return 0	[ -z "$1" ] && return 0	echo "Checking LOADNAND flag [$1]" >> $BOOT_DIR/log	if [ -f $1 ]; then		# Очищаем ФС (старые флаги, точки монтирования и т.д.		echo "LOADNAND flag [$1] was found. Loading internal ROM..." >> $BOOT_DIR/log		clean		exec /init_android_start $@		exit 0	fi}# функция попытки запуска внешней ОС при наличии соответствующих файлов-флагов# Аргументы - пути до флагов systemimg, dataimg и rootfs соответственноtry_sdcard() {	[ $# -eq 0 ] && return 0	[ $# -eq 1 ] && return 0	[ $# -eq 2 ] && return 0	[ -z "$1" ] && return 0	[ -z "$2" ] && return 0	[ -z "$3" ] && return 0	# Проверим наличие файлов-флагов с расположением внешних образов с прошивкой.	echo "Checking existence of SYSTEMIMG flag [$1]" >> $BOOT_DIR/log	if [ -f $1 ]; then		echo "SYSTEMIMG flag [$1] was found." >> $BOOT_DIR/log		echo "Checking existence of DATAIMG flag [$2]" >> $BOOT_DIR/log		if [ -f $2 ]; then			echo "DATAIMG flag [$2] was found." >> $BOOT_DIR/log			SYSTEM_IMG=`cat $1`			DATA_IMG=`cat $2`			echo "SYSTEM_IMG=$SYSTEM_IMG" >> $BOOT_DIR/log			echo "DATA_IMG=$DATA_IMG" >> $BOOT_DIR/log			if [ -f $3 ]; then				CUSTOM_ROOT_FS=`cat $3`				echo "CUSTOM_ROOT_FS=$CUSTOM_ROOT_FS" >> $BOOT_DIR/log			fi						# Флаги существуют, однако надо проверить существование указанных файлов			echo "Checking existence of file [$SYSTEM_IMG]" >> $BOOT_DIR/log			if [ -f $SYSTEM_IMG ]; then				echo "File [$SYSTEM_IMG] was found" >> $BOOT_DIR/log				echo "Checking existence of file [$DATA_IMG]" >> $BOOT_DIR/log				if [ -f $DATA_IMG ]; then					echo "File [$DATA_IMG] was found" >> $BOOT_DIR/log										# Файлы существуют. Создаем loop-узлы и ассоциируем с ними образы прощивки					echo "Creating LOOP-nodes and associating with our files" >> $BOOT_DIR/log					mknod -m 0666 /dev/block/loop0 b 7 0					mknod -m 0666 /dev/block/loop1 b 7 1					losetup /dev/block/loop0 $SYSTEM_IMG					losetup /dev/block/loop1 $DATA_IMG										# Монтируем их					echo "Mounting /system" >> $BOOT_DIR/log					mkdir -m 0755 /system					e2fsck -y /dev/block/loop0					mount -t ext4 -o rw,noatime,nodiratime,sync /dev/block/loop0 /system					[ $? -eq 0 ] || fail "Failed to mount /system from [$SYSTEM_IMG]"										echo "Mounting /data" >> $BOOT_DIR/log					mkdir -m 0771 /data					chown 1000:1000 /data					e2fsck -y /dev/block/loop1					mount -t ext4 -o rw,noatime,nodiratime,sync /dev/block/loop1 /data					[ $? -eq 0 ] || fail "Failed to mount /data from [$DATA_IMG]"										# Создаем папку кэша, если не существует. Нет смысла использовать					# отдельный образ для кэша, будем хранить его в /data					echo "Checking existence of cache folder [/data/.cache]" >> $BOOT_DIR/log					if [ ! -d /data/.cache ]; then						echo "Not found, creating new one" >> $BOOT_DIR/log						mkdir -m 0770 /data/.cache						chown 1000:2001 /data/.cache					fi					ln -s /data/.cache /cache										echo "Checking custom rootfs..." >> $BOOT_DIR/log					if [[ $CUSTOM_ROOT_FS ]]; then						# Если существует папка с пользовательским rootfs, копируем ее						if [ -d $CUSTOM_ROOT_FS ]; then							echo "Custom rootfs was found. Copying..." >> $BOOT_DIR/log							cp -r -f $CUSTOM_ROOT_FS/* /							# Если в пользовательском rootfs был init.rc, устанавливаем флаг							if [ -f $CUSTOM_ROOT_FS/init.rc ]; then								echo "Custom init.rc was found. Setting INITRC_REPLACED flag..." >> $BOOT_DIR/log								INITRC_REPLACED="true"							fi						else							echo "Custom rootfs not found" >> $BOOT_DIR/log						fi					else						echo "Custom rootfs not defined" >> $BOOT_DIR/log					fi					# Если пользовательского init.rc нет, устанавливаем стандартный скрипт инициализации					# ОС с карты памяти, который не монтирует никакие разделы, использует только существующие					if [ "$INITRC_REPLACED" != "true" ]; then						echo "Copying /init.sdcard.rc as /init.rc..." >> $BOOT_DIR/log						mv -f /init.sdcard.rc /init.rc					fi										# Очищаем ФС (старые флаги, точки монтирования и т.д.)					clean										# Загружаем ОС					echo "Loading system..." >> $BOOT_DIR/log					exec /init_android_start $@					exit 0				else					echo "File [$DATA_IMG] NOT found" >> $BOOT_DIR/log				fi			else				echo "File [$SYSTEM_IMG] NOT found" >> $BOOT_DIR/log			fi		else			echo "DATAIMG flag [$2] NOT found." >>  $BOOT_DIR/log		fi	else		echo "SYSTEMIMG flag [$1] NOT found." >>  $BOOT_DIR/log	fi}# Функция попытки запуска менеджера загрузки, если он существует по пути,# переданному в качестве аргументаtry_bootmanager() {	[ $# -eq 0 ] && return 0	[ -z "$1" ] && return 0	echo "Looking for BootManager package [$1]..." >> $BOOT_DIR/log	if [ -f "$1" ]; then		echo "BootManager Package found." >> $BOOT_DIR/log		echo "Copying it to [$BOOT_DIR/BootManager.zip]" >> $BOOT_DIR/log		cp "$1" "$BOOT_DIR/BootManager.zip"		mv -f /init.bootmgr.rc /init.rc		echo "Starting BootManager..." >> $BOOT_DIR/log		exec /init_android_start $@		exit 0	fi}# ===============================================================# 						Тело скрипта# ===============================================================makedevsmountdevs# Пытаемся запустить сперва встроенную ОС, потом внутреннюю, потом первый найденный менеджер загрузки# Любая функция try_ в случае успеха прекращает дальнейшее выполнение скриптаtry_loadnand "$BM_CACHE_DIR/loadnand"try_sdcard "$BM_CACHE_DIR/systemimg" "$BM_CACHE_DIR/dataimg" "$BM_CACHE_DIR/rootfs"try_bootmanager "$EMMC_FAT_MOUNT_POINT/$BM_DIR/BootManager.zip"try_bootmanager "$SDCARD_MOUNT_POINT/$BM_DIR/BootManager.zip"# Загружаем внутреннюю систему "Как есть", если ни одна из прерыдущих попыток не удалась.# Устанавливаем флаг, что загружалась внутренняя ОС и создался флаг last_loadnandecho "Loading flags and BootManager not found, loading the Internal ROM" >> $BOOT_DIR/logecho "loadnand" > $BM_CACHE_DIR/loadnandcleanexec /init_android_start $@
#!/sbin/sh# Author: GoldRenard# License: GPLmv -f /init_android /initexec /init $@
# ================================================================================================================# # AROMA Installer Main Script# Инфо: http://forum.xda-developers.com/showthread.php?t=1461712# Данный пакет используется в качестве менеджера загрузки.# # Пакет должен иметь имя "BootManager.zip" и должен находиться в папке "BootManager" любой карты памяти, то есть# либо на внутренней памяти, либо на внешней карте памяти. Если существуют оба, приоритет на внутреннюю память.# # Скрипт инициализации загрузки монтирует следующие разделы:# 	/boot/cache#		Cache-раздел устройства, в котором должны храниться# 		специальные файлы-флаги для менеджера загрузки# 	/boot/sdcard1#		Раздел внутренней памяти# 	/boot/sdcard2#		Раздел внешней карты памяти# # Скрипт инициализации загрузки смотрит на следующие файлы-флаги:# 	/boot/cache/BootManager/loadnand#		При наличии этого файла-флага загружается#		внутренняя ОС телефона. Остальные флаги игнорируются.## 	/boot/cache/BootManager/systemimg и /boot/cache/BootManager/dataimg# 		При наличии этих файлов флагов загружается ОС из образов, местоположение# 		которых и указано в содержимом этих файлов. Путь должен быть с использованием#		точек монтирования, описанных выше## 	/boot/cache/BootManager/last_*#		Эти флаги (last_loadnand, или last_systemimg или last_dataimg)#		не используются в инициализации загрузки, но могут использоваться для обозначения ОС#		для ее монтирования и использования в Recovery (при наличии соответствующей реализации в образе Recovery)##	/boot/cache/BootManager/rootfs#		При наличии этого флага копируются все файлы в текущую rootfs.#		Источник файлов (путь до папки) указывается в самом файле-флаге rootfs#		При наличии в источнике init.rc, используется именно этот.#		При отсутствии в источнике init.rc, используется стандартный для загрузки с SD-Карты##		ВНИМАНИЕ!!! Пользовательский init.rc НЕ ДОЛЖЕН МОНТИРОВАТЬ в СЕКЦИЯХ#		"on fs" и "on post-fs" РАЗДЕЛЫ /system, /data и /cache.## ================================================================================================================fontresload( "0", "ttf/Roboto-Regular.ttf;ttf/DroidSansFallback.ttf;", "12" );fontresload( "1", "ttf/Roboto-Regular.ttf;ttf/DroidSansFallback.ttf;", "14" );theme("ics");loadlang("langs/ru.lang");menubox(    "Операционная система",    "Выберите ОС для загрузки",    "@android",    "type.prop",	"AllegroROM v0.4",	"Android 4.0.4 - Прошивка в стиле AOSP и с некоторыми возможностями из CyanogenMod",	"@android_allegro",	#-- selected = 1    "Lenovo A390 Stock Firmware",	"Android 4.0.4 - Оригинальная заводская прошивка",	"@android_stock",	#-- selected = 2    "LeWa ROM",		"LeWa OS 4.0.4 - Тестовая сборка LeWa для A390",	"@android_lewa",	#-- selected = 3    "Recovery",		"Перезагрузка в Recovery",	"@recovery"	#-- selected = 4);if (prop("type.prop","selected")=="1") then	  write("/boot/cache/BootManager/loadnand", "loadnand");endif;if (prop("type.prop","selected")=="2") then	  write("/boot/cache/BootManager/systemimg", "/boot/sdcard1/BootManager/Stock/system.ext4.img");	  write("/boot/cache/BootManager/dataimg", "/boot/sdcard1/BootManager/Stock/data.ext4.img");endif;if (prop("type.prop","selected")=="3") then	  write("/boot/cache/BootManager/systemimg", "/boot/sdcard1/BootManager/LeWa/system.ext4.img");	  write("/boot/cache/BootManager/dataimg", "/boot/sdcard1/BootManager/LeWa/data.ext4.img");	  write("/boot/cache/BootManager/rootfs", "/boot/sdcard1/BootManager/LeWa/rootfs");endif;# Размонтируем /cache и /boot/cache для сохранения изменений.resexec("unmount.sh");if (prop("type.prop","selected")=="4") then	reboot("now", "recovery");else	reboot("now");endif;

/init:
/init_android_start:

Идем далее. BootManager.zip. Данный зип представляет собой AROMA Installer :D В зависимости от результата выбора menubox он создает файлы-флаги для нашего загрузочного скрипта и перезапускает телефон. Все просто. Вот такой вот простой у него конфиг:

В его закомментированной шапке все расписано, повторять не вижу смысла. Поскольку это AROMA, этот "менеджер загрузки" можно разукрасить и кастомизировать как душе угодно.

Вывод: На основе данного метода можно собрать такую штуку для любого телефона, главное в скрипте подменить имена блочных устройств внутренней памяти и карты памяти на свои, а так же исправить функцию инициализации /dev/input/ и блочных устройств /dev/block/ в соответствии с нужным устройством. И не забываем, что нужно уложиться всего-лишь в 6МБ (для большинства МТК-устройств).

+ Получаем почти полноценный мультибут. Почему почти? Читаем первый минус.
+ AROMA - значит кастомизация.
- Да потому что перезагрузки х)
- Скорость работы "внешних" ОС. На внутренней памяти телефона все работает прекрасно. На внешней SD-карте все зависит от ее класса. Естественно, чем больше, тем лучше. На моей карточке 4 класса (зачем я ее покупал, дурак...) ОС слишком долго "думает". Использовать не очень комфортно.
- Сброс к заводским настройкам у внешних ОС запустит сброс вшитой ОС. Я это предусмотрел в скрипте бута, оставляя старые флаги последней загруженной ОС - last_loadnand или last_systemimg + last_dataimg. Рамдиск рекавери требует модификацию для учета этих флагов. Себе я это не сделал, мне это не нужно (мне проще восстановить абсолютно чистый образ data.ext4.img). Кому нужно, реализуйте себе сами, используя шелл-скрипт бута как пример.
- Ядро для всех ОС используется одно и то же. Все прошивки должны быть с ним совместимы (например, основаны на одной и той же прошивке, от которой ядро и используется).
- Чуть более долгое суммарное время загрузки самой ОС из-за ожидания скриптом активации карт памяти.

А хотя... К черту минусы, выбирать не приходится :lol:

Кстати, плюс использования TWRP в данном случае - его прекрасная кастомизация. В моем видео видно, что диалог установки ZIP я изменил тупо на картинку с прогресс-баром для красоты.
Кстати[2], не забываем, что в качестве ext4-образов сжатые образы (которые обычно в стоковых прошивках) использовать не стоит. Юзаем sgs2toext4.
Кстати[3], у меня не очень сильный опыт работы в Linux-системах, так что за "грамотность" вышеуказанного скрипта меня пинать не нужно. С удовольствием выслушаю что, где и как можно было пойти иным образом.

В аттаче мой бут, его рамдиск (кому лень извлекать) и мой BootManager.zip. Изучаем, собираем аналогично себе, радуемся.

BootManager.zip

boot.img

rmdisk.zip

17 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прочитал и понял, что я в этом полный нуб))) А нельзя это всё сделать одним скриптом, чтобы один раз его поставить через TWRP и не дёргаться?)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прочитал и понял, что я в этом полный нуб))) А нельзя это всё сделать одним скриптом, чтобы один раз его поставить через TWRP и не дёргаться?)))

Не-а. Не зря эта тема создана в публичном разделе ромоделия, не может быть все слишком просто ;) Для каждого устройства индивидуально все настраивается и собирается.
3 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ой, скока букаф!!! Спасибо Лису за его рыжий умный подход.

2 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Для каждого устройства индивидуально все настраивается и собирается.

Вся красота Unix-подобной ОС ))) 

// Как говорится - кто не хочет включать мозг, просим воздержаться (не для слабонервных)...  :D

Надо будет на досуге вникнуть в это... не с одной бутылочкой пива...  :rolleyes:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

I flashed BootManager.zip  on my lenovo a390 then i didn't know how to continued dual boot

Could you tell me what i should do? please

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

thank you very much, GoldRenard

i'm using AllegroROM 0.4 but i don't know how to dual boot, i'm noob

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

If you're a noob, BootManager is not for you ;) I've already gave to you the link with information about how to configure the BootManager. If you can't translate it and understand then sorry, it's only your problem.

2 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

not sure i'm noob but i don't understand Russian...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Google Translation is worst to translate it

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

could you give me a guide with english?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Nope, sorry. We are Russian community. Our guides are only in Russian lang.

1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

i'm doing this with google trans, and i understand like this:

Step 1: convert system.img to system.ext4.img with sgs2toext4.jar using java enviroment

step 2: convert data.img to data.ext4.img

step 3: copy they to /BootManager/ExtraROM

step 4: put folder Boot Manager in /boot/sdcard1/

step 5: download BootManager.zip and extract it

and i don't know what i have to do then, i have put system.ext4.img and data.ext4.img in direction: boot/sdcard1/BootManager/ExtraROM

what i have to do then?

help me please

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

help me please....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как вариант, можно парсить recovery.fstab на предмет партиций, и конфиг инпутов тоже куда-нибудь отдельно от скрипта.

 

В коде шеллскрипта хардкод, зачем было задавать партиции если потом их маунтить по хардкодному имени?

 

Вопрос такой, у меня есть зипархив с прошивкой, как его преобразовать в ext4? mke2fs?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как вариант, можно парсить recovery.fstab на предмет партиций, и конфиг инпутов тоже куда-нибудь отдельно от скрипта.

Зачем Имхо, надежнее прямо указать разделы, зато потом будешь уверен что с этим проблем не возникнет. Я бы вообще из recovery.fstab список разделов убрал в данном случае, они не используются этим "рекавери".

В коде шеллскрипта хардкод, зачем было задавать партиции если потом их маунтить по хардкодному имени?

Немного не понял о чем ты х) Имеешь в виду маунтить их по именам вида emmc@fat, emmc@cache, etc?

Вопрос такой, у меня есть зипархив с прошивкой, как его преобразовать в ext4? mke2fs?

Лично я делаю бэкап в MTK Droid Tools, на выходе получается вполне рабочий ext4-образ. Можно конечно в лине создать вручную образ:

dd if=/dev/zero of=system.ext4.img bs=4k count=КОЛ-ВО_БЛОКОВmkfs.ext4 system.ext4.imgtune2fs -c0 -i0 system.ext4.img
Потом сделать tar.gz копию /system прямо с телефона и распаковать ее в тот образ. С MTK Droid Tools проще и быстрее. Он кстати tar.gz тоже делает.
2 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Немного не понял о чем ты х) Имеешь в виду маунтить их по именам вида emmc@fat, emmc@cache, etc?

У тебя до этого висит кучка дефайнов (ну или переменных), а дальше несмотря на них опять /dev/block..

можно туда вынести эти штуки, раз парсить fstab "бесполезно".

По поводу надежности, есть такая штука как внимательность. Упустил партицию (не переименовал) - прошь не загрузилась.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можно туда вынести эти штуки, раз парсить fstab "бесполезно".

Ну так сразу бы и сказал, что там лучше хранить абсолютный путь до раздела. У себя я это кстати вчера исправил, а в шапке поправить забыл х)

раз парсить fstab "бесполезно".

Не то, что бесполезно, просто зачем? Явно указал разделы и все довольны) Плюс парсинг прибавит парочку миллисекунд к времени загрузки :lol:
1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

:< :( pls help me

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

I'll never make English guide. Stop asking.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

sorry, i won't ask more

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обновил шелл-скрипт в шапке. Изменил функцию монтирования разделов. Раньше если фейлилось монтирование хоть одного раздела, загружалась вшитая ось в обход проверок наличия флагов и зипа бутменеджера. Не нужно это делать, ибо если, например, внешняя карта памяти извлечена, меню бутменеджера уже не увидеть.

Плюс, столкнулся с проблемой, что у одного человека раздел внешней карточки был не /dev/block/mmcblk1 как у меня, а /dev/block/mmcblk1p1. Сделал так, чтобы проверялись еще и /dev/block/mmcblk1p[1-7] (ну или ${SDCARD_PARTITION}p[1-7], в моем случае SDCARD_PARTITION=/dev/block/mmcblk1). Первый удачно смонтированный как vfat и есть нужный раздел, не думаю что кто-то будет делать на карточке более чем 7 разделов х)

3 пользователям понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Плюс, столкнулся с проблемой, что у одного человека раздел внешней карточки был не /dev/block/mmcblk1 как у меня, а /dev/block/mmcblk1p1.

Да кстати, заметил но не стал заострять внимание..

Вообще говоря всегда p1 как первый раздел дописывается даже если у карты 1 раздел, это видно по тому же фстабу. Остальное монтируется скриптами.

1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так-то это так, но у меня только mmcblk1, который и является единственным разделом. Хз почему, я думал так и должно быть х)

1 пользователю понравился пост

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу