Расширение внутреннего хранилища ГУ Changan CS55 Plus
После публикации моей предыдущей статьи по переносу данных и кэша приложение в раздел /resources, одногруппник Сергей из нашей TG-группы Changan UNI-S / CS55 plus предложил более радикальный вариант решения и использование раздела /resources
, а именно переместить туда все файлы и директории с раздела /data
и сделать свои новые точки монтирования.
Это рассматривалось как смелый эксперимент, однако наличие у Сергея уже выведенного UART разъема из ГУ, проверка изменений в систему с неудачным результатом потенциально подразумевало возможность безопасного отката изменений к заводскому варианту.
Используемый алгоритм переопределения разделов ГУ
В ходе анализа алгоритма загрузки нашего ГУ, изучения файлов init.rc
, и сопутствующих *.rc файлов, которые включены в основной init.rc
как import
файлы, было выявлено, что основная таблица распределения точек монтирования блочных устройств с /dev/block/mmcblk0p1
по /dev/block/mmcblk0p51
прописана в файле /vendor/etc/fstab.mt6771
.
Таким образом, внеся изменения в файл /vendor/etc/fstab.mt6771
, мы можем переопределить точку монтирования раздела /data
на блочное устройство самого большого размера (12 Гб), которое сейчас занимает /resources
. А раздел /resources
можно посадить на блочное устройство, на котором ранее сидел /data
, так как /resources
всё равно не нужен такой большой объем для хранения данных. Естественно, предварительно надо обменять файлы и директории на двух разделах, чтобы дальнейшая загрузка пошла успешно.
Пока я думал и анализировал точную возможность загрузки такого варианта, Сергей уже смело выполнил изменения в файле /vendor/etc/fstab.mt6771
, и завершил успешную загрузку системы с обновленными точками монтирования разделов!
Теперь стояла задача автоматизировать все действия для других пользователей, и предусмотреть возможность отката всего назад. Как обычно, я решил сделать это в виде традиционного batch-скрипта, который уже запускает необходимый shell скрипт на ГУ.
В ходе работы над скриптом, я пришел к выводу, что в схеме придется задействовать раздел /fota
, потому что у большинства пользователей не хватит места в разделе /data
для переноса всех файлов из раздела /resources
, и тогда не получится завершить скрипт, либо надо удалять часть приложений с данными, а это не очень удобно. Более того, схема с использованием раздела /fota
оказалось еще безопаснее.
Скрипт перемещения раздела /DATA
Что делает скрипт?
- создаёт списки изначальных файлов и папок каждого раздела
/data
,/resources
и/fota
, и сохраняет их в виде отдельных файлов TXT в папке/fota/file_lists/
; - копирует все файлы и папки из
/resources
в/fota
c атрибутами; - копирует все файлы и папки из
/data
в/resources
c атрибутами; - копируем все файлы и папки из
/fota
в/data
c атрибутами; - cоздаёт резервную копию файла
/vendor/etc/fstab.mt6771
перед изменениями; - выполняет изменения в файле
/vendor/etc/fstab.mt6771
, изменяя блочные устройства для точек монтирования:/resources
теперь становится/data
;/fota
становится/resources
;/data
становится/fota
;
Содержание скрипта перемещения разделов:
#!/bin/sh
echo "*****************************************************"
echo "СКРИПТ ПЕРЕМЕЩЕНИЯ РАЗДЕЛА 'DATA' В ХРАНИЛИЩЕ ГУ"
echo "*****************************************************"
echo " "
echo "Начинаем процесс переноса данных!"
# Сохраняем исходный перечень файлов и директорий '/fota' в '/fota/fota_list.txt'
ls /fota > /resources/fota_list.txt
mkdir -p /fota/file_lists
echo "Создаём папку /fota/file_lists..."
mv /resources/fota_list.txt /fota/file_lists
echo "Создаём файл fota_list.txt..."
# Сохраняем исходный перечень файлов и директорий '/data' в '/fota/data_list.txt'
ls /data > /fota/file_lists/data_list.txt
echo "Создаём файл data_list.txt..."
# Сохраняем исходный перечень файлов и директорий '/resources' в '/fota/resources_list.txt'
ls /resources > /fota/file_lists/resources_list.txt
echo "Создаём файл resources_list.txt..."
# Копируем все файлы и папки из '/resources' в '/fota' c атрибутами
echo "Копируем все файлы и папки из '/resources' в '/fota' c атрибутами..."
cp -a /resources/* /fota/
# Проверяем успешность копирования
if [ $? -eq 0 ]; then
echo "Копирование файлов и папок из '/resources' в '/fota' выполнено успешно, переходим к следующему этапу!..."
else
echo "Произошла ошибка в процессе копирования файлов из '/resources' в '/fota', процесс приостановлен"
exit 1
fi
# Копируем все файлы и папки из '/data' в '/resources' c атрибутами
echo "Копируем все файлы и папки из '/data' в '/resources' c атрибутами..."
cp -a /data/* /resources/
# Проверяем успешность копирования
if [ $? -eq 0 ]; then
echo "Копирование файлов и папок из '/data' в '/resources' выполнено успешно, переходим к следующему этапу!..."
else
echo "Произошла ошибка в процессе копирования файлов из '/data' в '/resources', процесс приостановлен"
exit 1
fi
# Копируем все файлы и папки из '/fota' в '/data' c атрибутами
echo "Копируем все файлы и папки из '/fota' в '/data' c атрибутами..."
## Проверяем наличие файла fota_list.txt
if [ ! -f /fota/file_lists/fota_list.txt ]; then
echo "Не найден файл /fota/file_lists/fota_list.txt"
exit 1
fi
# Чтение содержимого файла и копирование каждого элемента
while IFS= read -r line; do
if [ -e "/fota/$line" ]; then
# Копируем файл или директорию с сохранением атрибутов
cp -a "/fota/$line" /data/
else
echo "Папка или файл /fota/$line не найден, пропускаем, копируем дальше..."
fi
done < /fota/file_lists/fota_list.txt
# Проверяем успешность копирования
if [ $? -eq 0 ]; then
echo "Копирование файлов и папок из '/fota' в '/data' выполнено успешно, переходим к следующему этапу!..."
else
echo "Произошла ошибка в процессе копирования файлов из '/fota/' в '/data', процесс приостановлен"
exit 1
fi
# Создаем резервную копию файла '/vendor/etc/fstab.mt6771' перед изменениями
cp -a /vendor/etc/fstab.mt6771 /vendor/etc/fstab.mt6771.bak
echo "Создаем резервную копию файла '/vendor/etc/fstab.mt6771' перед изменениями..."
# Выполняем замену строки для /data (меняем на '/dev/block/platform/bootdevice/by-name/resources')
sed -i 's|/dev/block/platform/bootdevice/by-name/userdata /data ext4 noatime,nosuid,nodev,noauto_da_alloc,errors=panic wait,check,formattable,quota,resize,reservedsize=128m,encryptable=/dev/block/platform/bootdevice/by-name/metadata,|/dev/block/platform/bootdevice/by-name/resources /data ext4 noatime,nosuid,nodev,noauto_da_alloc,errors=panic wait,check,formattable,quota,resize,reservedsize=384m,encryptable=/dev/block/platform/bootdevice/by-name/metadata,|' /vendor/etc/fstab.mt6771
echo "Выполняем замену строки для /data..."
# Выполняем замену строки для /resources (меняем на '/dev/block/platform/bootdevice/by-name/fota')
sed -i 's|/dev/block/platform/bootdevice/by-name/resources /resources ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable|/dev/block/platform/bootdevice/by-name/fota /resources ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable|' /vendor/etc/fstab.mt6771
echo "Выполняем замену строки для /resources..."
sed -i 's|/dev/block/platform/bootdevice/by-name/fota /fota ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable|/dev/block/platform/bootdevice/by-name/userdata /fota ext4 noatime,nosuid,nodev,noauto_da_alloc,commit=1,nodelalloc wait,check,formattable|' /vendor/etc/fstab.mt6771
echo "Выполняем замену строки для /fota..."
echo "Изменения в систему выполнены, можно перезагружать устройства (кнопка "-" на руле)!"
После внесенных изменений можно перезагружать ГУ с новыми разделами, где раздел /data
получает уже 12 Гб вместо ранее выделенных 3,9 Гб!
После удачной перезагрузки ГУ можно очистить новый раздел /data
от старых файлов и папок /resources
(они там остались), для этого я сделал еще один скрипт, который пройдется по новому разделу /data
и удалит все файлы и папки согласно заданного списка. Это можно и не делать, но это освободит 1,5-2 Гб пространства.
/resources
В моём традиционном BATCH файле это выглядит в виде дополнительного пункта меню "7. Перемещение раздела DATA в хранилище ГУ"
Ход выполнения скрипта:
Очистку нового раздела /data
от старых файлов и папок /resources
, после первой перезагрузки, выполняем вторым пунктом меню "Очистить раздела DATA от лишних файлов после переноса".
В итоге, после завершения работы скриптов, имеем следующую картину:
Архив с необходимым пакетом файлов и BATCH скриптом (Changan_CS55Plus_HU_installation_move_data.bat) находится по ссылке ниже:
Что делать на случай обновления прошивки?
В случае обновления прошивки, большая вероятность, что файл /vendor/etc/fstab.mt6771
будет заменен изначальным (но мы точно не уверены), поэтому разделы возможно опять вернутся к своему исходному виду, раздел /data
станет таким, каким был до работы скрипта, а раздел /resources
вообще останется без своих нужных файлов, и система не загрузится!
Решения 2:
- не удалять остатки файлов
/resources
c нового раздела/data
(но 2 Гб свободного пространства сразу минус); - если удалили, перед обновлением прошивки скопировать их обратно, из нового
/resources
в новый/data
, но сохраняя атрибуты и системные права. Для этой операции я сделаю отдельный скрипт, который быстро и без проблем вернет файлы;
Будут обновления, но сейчас решение максимально рабочее, теперь можно не думать о заканчивающемся свободном пространстве!
Сергей, спасибо за идею и смелое тестирование!