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

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


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

@GoldRenard,

после перепаковки своего бута по твоей инструкции на выходе получаю 6.77 МБ..

как его можно уменьшить? чем пожертвовать?

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


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

Если TWRP, то выпили supersu, урежь графику, она все равно не нужна (не удалять, а подменить на пустышки 1х1, к примеру). Попробуй сделать на основе рабочего рамдиска рекавери, скопировав туда свои init*.rc, используй там бинарник init от бута, а не от рекавери, воссоздай структуру каталогов как в рамдиске бута. Если никак не укладываешься в 6МБ, придется юзать рекавери полегче. CWM в помощь.

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

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


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

@GoldRenard,

собрал.. зависаю на бутлого..

можно у тебя попросить помощи?

я б тебе дал свои бут и рекавери и мультибут.. можт посмотришь, где я ошибся?

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


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

Не имея на руках девайса я ничем не смогу помочь.

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


Ссылка на сообщение
Поделиться на другие сайты
Не имея на руках девайса я ничем не смогу помочь.

я имею в виду, что может быть я в самой технологии ошибся..

ну ок, давай я скажу, что именно делал, а ты меня поправишь:)

1. взял стоковый бут, взял свой twrp, распаковал их..

2. в папке с бутом заменил rmdisk на rmdisk от twrp, но туда добавил init от бута и твой init.rc..

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


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

твой init.rc..

Мда. Правда, лучше не пытайтесь, если не понимаете что чужой init.rc - нехорошо.
1 пользователю понравился пост

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


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

в папке с бутом заменил rmdisk на rmdisk от twrp, но туда добавил init от бута и твой init.rc..

по-моему речь шла только о добавлении папок навроде sbin и модификации своего init.rc

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


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

Я сейчас сам пытаюсь завести это на А1000 и пока что безуспешно. Бут с рекавери успешно скрестил, проша запускается напрямую с родным init. Но стоит вместо init подставить простой скрипт, возвращающий родной init на место и запускающий его:

#!/sbin/sh# Author: GoldRenard# License: GPLmv -f /init_android /initexec /init $@
то все, затык в бутлуп. Busybox рабочий. Что такое, не понимаю...
1 пользователю понравился пост

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


Ссылка на сообщение
Поделиться на другие сайты
Мда. Правда, лучше не пытайтесь, если не понимаете что чужой init.rc - нехорошо.

Ок, намек понятен:) Думал обойтись меньшей кровью..

Значит закапываюсь в скрипт

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


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

то все, затык в бутлуп. Busybox рабочий. Что такое, не понимаю...

sbin/sh существует?

И зачем иниту $@?

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


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

а можно тогда попросить еще и оригинальный бут? так сказать для сравнения

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


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

sbin/sh существует?

конечно, базибокс вместе с рекавери же идет.

И зачем иниту $@?

передача полученных параметров далее в init. Вдруг ядро запускает init с какими-нибудь параметрами.

Сейчас попробую впилить тот базибокс, с которым все работает на А390.

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


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

базибокс вместе с рекавери же идет.

открою страшную тайну, но sh-интерпретатор не входит в состав busybox ;)

передача полученных параметров далее в init. Вдруг ядро запускает init с какими-нибудь параметрами.

не припомню чтобы init получал параметры.. если только китайский.

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


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

открою страшную тайну, но sh-интерпретатор не входит в состав busybox

~ # busybox

busybox

BusyBox v1.20.2-jb bionic (2012-07-27 02:57 +0200) multi-call binary.

Copyright © 1998-2012 Erik Andersen, Rob Landley, Denys Vlasenko

and others. Licensed under GPLv2. Merged for bionic by tpruvot@github

See source distribution for full notice.

Usage: busybox [function [arguments]...]

or: busybox --list

or: function [arguments]...

BusyBox is a multi-call binary that combines many common Unix

utilities into a single executable. Most people will create a

link to busybox for each function they wish to use and BusyBox

will act like whatever it was invoked as.

Currently defined functions:

[, [[, adjtimex, arp, ash, awk, base64, basename, bbconfig, blkid,

blockdev, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chattr, chgrp,

chmod, chown, chroot, clear, cmp, comm, cp, cpio, crond, crontab, cut,

date, dc, dd, depmod, devmem, df, diff, dirname, dmesg, dnsd, dos2unix,

du, echo, ed, egrep, env, expand, expr, false, fbsplash, fdisk, fgrep,

find, flash_lock, flash_unlock, flashcp, flock, fold, free,

freeramdisk, fsync, ftpget, ftpput, fuser, getopt, grep, groups,

gunzip, gzip, halt, head, hexdump, id, ifconfig, inetd, insmod,

install, ionice, iostat, ip, kill, killall, killall5, less, ln,

losetup, ls, lsattr, lsmod, lsof, lsusb, lzcat, lzma, lzop, lzopcat,

man, md5sum, mesg, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2,

mkfs.vfat, mknod, mkswap, mktemp, modinfo, modprobe, more, mount,

mountpoint, mpstat, mv, nanddump, nandwrite, nbd-client, nc, netstat,

nice, nohup, nslookup, ntpd, od, patch, pgrep, pidof, ping,

pipe_progress, pkill, pmap, poweroff, printenv, printf, ps, pstree,

pwd, pwdx, rdev, readlink, realpath, reboot, renice, reset, resize,

rev, rm, rmdir, rmmod, route, run-parts, rx, sed, seq, setconsole,

setserial, setsid, sh, sha1sum, sha256sum, sha512sum, sleep, sort,

split, stat, strings, stty, sum, swapoff, swapon, sync, sysctl, tac,

tail, tar, taskset, tee, telnet, telnetd, test, tftp, tftpd, time,

timeout, top, touch, tr, traceroute, true, ttysize, tune2fs, umount,

uname, uncompress, unexpand, uniq, unix2dos, unlzma, unlzop, unxz,

unzip, uptime, usleep, uudecode, uuencode, vi, watch, wc, wget, which,

whoami, xargs, xz, xzcat, yes, zcat

Эм, что? Апплет же есть такой :) Или я чего-то не понимаю?

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


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

Эм, что? Апплет же есть такой :) Или я чего-то не понимаю?

по крайней мере в system эти понятия разнесены..

все равно стоит проверить наличие линка в sbin.

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


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

по крайней мере в system эти понятия разнесены..

Речь идет о базибоксе, используемым в рекавери.

все равно стоит проверить наличие линка в sbin.

Имеется.

Короче, подмена базибокса с А390 рамдиска решила проблему. Странно это, ведь прошлый 100% был рабочий (было проверено в адб рекавери). Кстати, они в размерах существенно отличаются. Тот, что был - ~500кб. Тот что заработал почти 1.5мб. Может последний является статическим (тянет в себе все нужные либы), а прошлый из-за отсутствия какой-нибудь переменной вроде LD_LIBRARY_PATH не находил либы и умирал.

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

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


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

Как мне реализовать мультибут на А789? Я смотрел характеристики с А390 похожие...

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


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

В шапке описана основная идея, что вы еще хотите?

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


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

Ничего. Спасибо за идею. ))

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


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

Можете какую ту подробную инструкцию выложить. Я даже не понял куда папки с прошивками девать, как их извлечь? и откуда? чем? Все-таки это на много сложнее чем просто перепрошиться. Я все-таки нуб(

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


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

Как хотелось бы это все реализовать, мне это бы упростило жизнь) а и кстати где взять леву?

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


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

Можете какую ту подробную инструкцию выложить. Я даже не понял куда папки с прошивками девать, как их извлечь? и откуда? чем? Все-таки это на много сложнее чем просто перепрошиться. Я все-таки нуб(

Большую красную рамку в шапке темы видите? Закрываете эту тему и больше сюда не суетесь до времен, когда изучите азы Linux и ромоделия под андроид.
2 пользователям понравился пост

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


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

А рекавери работает на своем ядре, или загружает стандартное ядро Андроида? Очень интересует получение мультибута с двумя разными ядрами.

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


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

 

Очень интересует получение мультибута с двумя разными ядрами.
А где ты возьмешь два разных ядра??? Все прошивки делаются на оф. ядре и с правленым ramdisk ... 

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


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

А где ты возьмешь два разных ядра??? Все прошивки делаются на оф. ядре и с правленым ramdisk ... 

 

Это не на телефоне. Если интересно - планшет, с Ubuntu и Android'ом.

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


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

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

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

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

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


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

Войти

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


Войти

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

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