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 пользователям понравился пост

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


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

Ну тогда Grub тебе в помощь...

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


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

Тоже задумывался об этом. Ну а там дальше, как пойдет.

Кстати, а нельзя ли на устройствах, "заточенных" под андроид заменить лоадер GRUB на GRUB2?

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


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

Кто-то смог повторить? Хочу попробовать на своём. Вроде всё понятно. На первый взгляд конечно!

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


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

GoldRenard, а можно ли вживить аромовский update-binary в rmdisk? Конфиг и ресурсы можно повесить симлинком на карту памяти, а запускать можно в обход recovery, как здесь под спойлером 2, только до загрузки андроида.

Р.S. Сделай историю версий пожалуйста ;)

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


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

Нельзя. Первая проблема - ограниченное место в рамдиске. На некоторые девайсы рекавери еле влезает. Вторая проблема, самая главная, update-binary аромы не будет работать в обход рекавери. Рекавери делает много важных вещей для его работы - инициализация графики и т.п.

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

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


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

А если в Boot.img оставить ТОЛЬКО Bootmanager, а все остальное (включая init'ы подгружать) из файловой системы? CWM поддерживает подключение устройства в качесвте mass_storage, так что можно будет все подгружать с компа по мере надобности. 

P.S. Это может понадобиться при экспериментах с не_андроидными прошивками, такими как Ubuntu Touch, Debian ARM и т.д. :)

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


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

А если в Boot.img оставить ТОЛЬКО Bootmanager, а все остальное (включая init'ы подгружать) из файловой системы? CWM поддерживает подключение устройства в качесвте mass_storage, так что можно будет все подгружать с компа по мере надобности.

Имхо, в рамдиске в любом случае должен оставаться оригинальный стандартный набор (init, *.rc), чтобы в любом случае можно было загрузить основную ОС если что вдруг не так.

P.S. Это может понадобиться при экспериментах с не_андроидными прошивками, такими как Ubuntu Touch, Debian ARM и т.д.

"Сабжевым" методом ни о чем таком даже не нужно заикаться, ибо здесь всегда загружается одно и то же ядро, которое может корректно работать только с одним типом ОС. Было бы совсем другое дело, если бы можно было использовать kexec, но большинством стоковых ядер оно не поддерживается.
2 пользователям понравился пост

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


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

Ну так Android'ное ядро - чуть допиленное Linux'овое, разве нет?

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


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

Ну так Android'ное ядро - чуть допиленное Linux'овое, разве нет?

Конечно да, но никто не гарантирует работу на нем других дистрибутивов. Например, 3.0.13 ядро, заточенное под 4.0.4 дройд, в неизменном виде не будет дружить с 4.1+ Да и вообще, в плане разнообразия прошивок на МТК - все печальней некуда. Какие там Ubuntu Touch и дебиан.
2 пользователям понравился пост

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


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

Здравствуйте! вопрос на засыпку, /sbin/recovery с аргументом -u=/boot/BootManager.zip.  где можно посмотреть опции именно recovery, попробывал собрать но у меня не воспринимает аргумент!

Отредактировал dj_max_demon

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


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

В исходниках используемого вами рекавери.

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


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

В исходниках используемого вами рекавери.

спасибо уже нашол!

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


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

А как тебе такой вариант? Если не все поместится в рамдиск - часть можно перенести на /data, потом просто отмонтироваить и продолжать загрузку в обычном режиме. 4pda.ru/forum/index.php?showtopic=453087

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


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

В дата не вариант, лучше уж в системном разделе. А вообще, у меня давно уже появилась мысль покруче, но актуальную только для МТК. Можно воспользоваться Factory Mode. Он, насколько я знаю, грузится из бута сценариями вроде factory_init.rc (имя может везде различаться). Вшить рекавери и все необходимое в системный раздел и модифицировать эти сценарии на загрузку рекавери с арома соответствующим образом. А уж при обычной загрузке монтировать и загружать что нужно и как нужно, места в рамдиске для таких уж мелочей всегда должно хватать.

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

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


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

Его можно загружать без рекавери. Открой последнюю версию архива в той теме и посмотри как он запускается. Aroma installer не требует никаких инициализаций графики кроме создания дерева папки /dev, он использует свои внутренние библиотеки для работы с фреймбуффером и тачем. Это может сильно сэкономить место.

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


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

Реализовать загрузку разных прошивок андроида можно используя общую идею отсюда forum.xda-developers.com/showthread.php?t=1572924 , тогда можно будет организовать даже поддержку разного количества систем на разных разделах карты памяти либо даже просто в разных папках/файлах.

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


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

Aroma installer не требует никаких инициализаций графики кроме создания дерева папки /dev

Еще как требует. Пока до инит.д с вашим скриптом дело дойдет, все необходимое уже 10раз инициализируется. Попробуйте запустить его из рамдиска напрямую шелл скриптом вместо init, монтируя /proc /sys, создав базовое дерево /dev, без загрузки остальных служб. У вас ничего не получится.

Реализовать загрузку разных прошивок андроида можно используя общую идею отсюда forum.xda-developers.com/showthread.php?t=1572924 , тогда можно будет организовать даже поддержку разного количества систем на разных разделах карты памяти либо даже просто в разных папках/файлах.

chroot не есть гуд. Мало ли какие косяки вылезут. Но идея прикольная.
1 пользователю понравился пост

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


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

В принципе можно будет организовать даже поддержку разных рекавери. Загрузить содержимое рамдиска в память, отмонтировать все диски, chroot + exec init в папку с содержимым рамдиска и он запускается в полном обьеме. Ехес обязателен ,т.к. у инита pid всегда должен быть равен единице.

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


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

Поздно обновил страницу :) . Я не имел ввиду init.d , я имел ввиду одну конкретную строку 

/system/etc/aroma/aroma 1 0 /system/etc/aroma/aroma.zip

Так его можно запускать без рекавери, так же как и aroma filemanager

Отредактировал ottiwell

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


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

В принципе можно обойтись и без чрута. Просто скопировать содержимое нужного рамдиска в корневую файловую систему с заменой, либо просто предварительно все очистив, что бы потом не было никаких следов работы преинита.

Отредактировал ottiwell

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


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

Так его можно запускать без рекавери, так же как и aroma filemanager

Так-то да, ведь всю магию за рекавери делают запущенные ранее службы дройда.
1 пользователю понравился пост

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


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

Можно попробовать запустить арому из преинита и узнать, способна ли она на магию сама. Только нужно подложить к нему файл конфигурации с указанием на автоматическое монтирование всех доступных дисков и ффайлик fstab чтобы он знал что ему нужно монтировать.

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


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

Можно попробовать запустить арому из преинита и узнать, способна ли она на магию сама.

Не способна. Если даже взять рамдиск рекавери, вшить в него арому и в init.rc вместо рекавери запускать сразу ее, ничего хорошего не выйдет. Я уже пробовал.
1 пользователю понравился пост

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


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

@GoldRenard , i want to ask you some questions...

- we are proccessing recovery.img or boot.img ?

- it's just rename init to init_android, and add init, init_android_start, init.bootmgr.rc(recovery's init.rc edited) .

- and in your boot.img, i have unpack it and saw ini.rc , is that boot.img's init.rc ??

thanks ?

i really not understand your tutorial because i used google translate , and my english is very bad !

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


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

Доброго времени суток. Требуется помощь, сижу соображаю уже второй день. Вроде как собрать boot понял, а вот дальше тупик. Если есть кто добрый - помогите, пожалуйста, можно в ЛС.

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


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

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

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

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

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


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

Войти

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


Войти

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

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