Pull to refresh

Samsung Galaxy S: решение проблемы corrupted internal sd card

Не так давно мой Galaxy S GT-I9000 начал спонтанно перезагружаться с сообщением Internal SD card removed unexpectedly, а потом и вовсе зависать в boot-е.
Не найдя работающего решения в интернете (а проблема довольно распространенная и решений предлагается много), и ничего не понимая в утсройстве андройда, я решил, что раз уж я программист, надо все-таки попытаться разобраться самому.



Если у вашего телефона похожая проблема, или вам интересен процесс исследования таких проблем, прошу под кат.



Прежде всего: я не специалист в Android или Linux, и может быть, кому-то этот пост покажется тривиальным. Но так как нормального решения проблемы я в интернете не нашел, надеюсь, что пост окажется полезным.


И так в чем же проблема?
Немного погуглив, мы узнаем, что «Internal SD card» соответствует девайс файлу /dev/block/mmcblk0 на котором должны быть два партишена: mmcblk0p1(vfat, для /data) и mmcblk0p2 (ext2, для /sdcard).
Зайдем в recovery (Home+VolumeUp+Power) и через adb(нужен Android SDK и USB driver, если вы на Windows; подробго тут http://developer.android.com/guide/developing/device.html) проверим наличие mmcblk0:
$ adb shell
/ # ls -l /dev/block/

В моем случае mmcblk0 отсутствовал.
Ищем разнообразные логи:
/ # find -name *log*
./mnt/.lfs/logo_latona.jpg
./mnt/.lfs/logo.jpg
./mnt/.lfs/logo_s1ntt.jpg
find: ./cache/RECOVERY: No such file or directory
./cache/recovery/recovery_kernel_log
./cache/recovery/log
./cache/recovery/last_log
...

Логов конечно много, но так как я подозревал HW проблему. первым делом заинтересовался kernel логами.
/ # grep mmc /cache/recovery/recovery_kernel_log
...
<6>[ 0.717702] mmc0: SDHCI controller on samsung-hsmmc [s3c-sdhci.0] using ADMA

...
<3>[ 2.060251] mmc0: error -110 whilst initialising MMC card
...

Ага! Что же за error 110? Гугл подсказывает: ETIMEDOUT. Судя по всему вот сорс код, печающий эту ошибку: http://lxr.free-electrons.com/source/drivers/mmc/core/mmc.c#L1326
На этом этапе можно конечно попытаться сдать аппарат по гарантии, но мне было лень(да и не уверен, что телефон поменяли бы), и появилась вот какая идея: что если заменить проблемную внутреннюю СД-карточку на внешнюю?
На эту мысль меня натолкнул то факт. что когда я подключал внешнюю карточку, она появлялась как раз как mmcblk0.
Вот хороший топик, о том как создать нужные partitions:
http://forum.cyanogenmod.com/topic/6433-solved-messed-up-partitions-on-internal-storage
И еще один: http://forum.xda-developers.com/showthread.php?t=534714
А вот так все должно выглядеть в результате:
/ # ls /dev/block/mmc*
/dev/block/mmcblk0
/dev/block/mmcblk0p1
/dev/block/mmcblk0p2


Итак осталось только использовать наш новый mmcblk0.
Нужно понять, кто и когда маунтит mmcblk0p1 и mmcblk0p2 в /sdcard и /data.

Поищем fstab:
/ # find -name *fstab*
./system/etc/vold.fstab
./voodoo/root/etc/fstab
./voodoo/run/cwm_recovery.fstab
./voodoo/run/cwm.fstab
./res/recovery.fstab
/ #

Из всего найденного vold.fstab больше всего похож на то, что нам нужно (voodoo это система скриптов для конвертирования самсунговской rfs в ext4, а cwm это clockwork mod).
Из гугла не сложно узнать, что vold это демон ответсвенный за маунт СД-карточек. Посмотрим его конфиг:
## Vold 2.0 Generic fstab
## - San Mehat (san@android.com)
##

#######################
## Regular device mount
##
## Format: dev_mount <mount_point> <sysfs_path1...>
## label - Label for the volume
## mount_point - Where the volume will be mounted
## part - Partition # (1 based), or 'auto' for first usable partition.
## <sysfs_path> - List of sysfs paths to source devices
######################

# sdcard mount for the P1
# internal sdcard
{
ums_path = /sys/devices/platform/usb_mass_storage/lun0/file
discard = disable
asec = disable
}
dev_mount sdcard /mnt/sdcard 1 /devices/platform/s3c-sdhci.0/mmc_host/mmc0

# externel sdcard
{
ums_path = /sys/devices/platform/usb_mass_storage/lun1/file
asec = enable
}
dev_mount sdcard1 /mnt/sdcard/external_sd auto /devices/platform/s3c-sdhci.2/mmc_host/mmc2
#end line ## keep this line


Нетрудно догадаться, что vold маунтит первый партишен mmcblk0 как /mnt/sdcard (а /sdcard это soft link на /mnt/sdcard).
Попытаемся поменять местами mmc0 и mmc2:


## Vold 2.0 Generic fstab
## - San Mehat (san@android.com)
##

#######################
## Regular device mount
##
## Format: dev_mount <mount_point> <sysfs_path1...>
## label - Label for the volume
## mount_point - Where the volume will be mounted
## part - Partition # (1 based), or 'auto' for first usable partition.
## <sysfs_path> - List of sysfs paths to source devices
######################

# externel sdcard for /mnt/sdcard
{
ums_path = /sys/devices/platform/usb_mass_storage/lun1/file
discard = disable
asec = disable
}
dev_mount sdcard /mnt/sdcard 1 /devices/platform/s3c-sdhci.2/mmc_host/mmc2

# internal sdcard for /mnt/sdcard/external_sd
{
ums_path = /sys/devices/platform/usb_mass_storage/lun0/file
asec = enable
}
dev_mount sdcard1 /mnt/sdcard/external_sd auto /devices/platform/s3c-sdhci.0/mmc_host/mmc0

#end line ## keep this line


Важно оставить в конфиге ссылку на external_sd - иначе будем иметь вот такой неприятный крэш при попытке установить аппликации:
D/Vold ( 196): VolumeManager::isMountedAsec -> Can not find the label(/mnt/sdcard/external_sd)
E/JavaBinder( 902): *** Uncaught remote exception! (Exceptions are not yet supported across processes.)
...
E/AndroidRuntime( 902): *** FATAL EXCEPTION IN SYSTEM PROCESS: PackageManager
...

который приводит к перезагрузке системы.

Кто же маунтит mmcblk0p2?
Посмотрим на init.rc:
/ # grep mmcblk init.rc
mount rfs /dev/block/mmcblk0p2 /data nosuid nodev check=no
# mount rfs /dev/block/mmcblk0p2 /data nosuid nodev crypt check=no
/ #

тут нам ничего менять не надо.
Вроде бы все. Перезагружаем и та-дам!! все работает:)



Интересные ссылки по теме:


Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.