Установка NAND памяти
Введение
Toshiba AC100 имеет на плате место для установки чипа NAND памяти в корпусе 48TSOP1. В процессе изучения схемы и платы выяснилось, что дорожки к посадочному месту подходят, питание есть и остальные пассивные компоненты, вроде конденсаторов, установлены.
Upstream
Lucas Stach ведет работы по созданию NAND драйвера для Tegra 2 в мэйнлайн ядре.
Вторая серия патчей: Tegra 2 NAND Flash Support
Что работает в данный момент
В данный момент при правильно пропатченном ядре появляется устройство /dev/mtd0, а также возможность работать с ним через mtd-utils. При условии, что флешка пустая или отформатирована на самой ac100 (подробная информация ниже), можно подключить mtd0 к UBI и даже создать раздел.
Примонтировать NAND-память и пользоваться как обычным диском пока что не получится — по неизвестным в данный момент причинам при монтировании ubifs failed to recover master node.
Подготовка
Что потребуется для модификации
- Паяльник с тонким жалом, желательно с регулировкой температуры
- В случае, когда чип необходимо снять с донора — термовоздушная или инфракрасная паяльная станция
- Флюс (как можно менее агрессивный), припой
- Металлическая оплетка для удаления лишнего припоя
- Непосредственно микросхема памяти. Её выбор следует рассмотреть отдельно.
Выбор микросхемы памяти
Плата paz00 предполагает использование 8-битной NAND памяти с напряжением питания 3.3V. Как правило, в серии микросхем существуют модификации с различной разрядностью и напряжением питания. Кроме того, текущая версия драйвера (drivers/mtd/devices/tegra_nand) поддерживает только чипы с 2k и 4k размером страниц (pagesize).
Проще всего извлечь микросхему из USB-флешки. Перед извлечением следует найти datasheet на чип в Google и убедиться, что он подходит по параметрам.
Аппаратная часть
Установка микросхемы
Припаивание производится без каких-либо особых тонкостей. Проще всего сначала аккуратно залудить контактные площадки на плате, затем с помощью паяльника припаять память, зафиксировав сначала крайние контакты. Использовать фен или ИК на плате можно только в том случае, если вы представляете себе последствия термического расширения платы и перегрева компонентов.
Программная часть
Компиляция ядра
В данный момент NAND-память поддерживается только в ветке 3.1 (l4t-r16-r2-ac100). Для включения поддержки необходимо применить следующий патч:
patch -p1 < paz00-nand-support.patch
Однако, простого применения патча недостаточно, и перед компиляцией необходимо будет задать параметры используемого чипа в файле /arch/arm/mach-tegra/board-paz00.c. Пример конфигурации для Hynix HY27UF081G2M:
static struct tegra_nand_chip_parms nand_chip_parms[] = { /* Hynix HY27UF081G2M */ [0] = { .vendor_id = 0xAD, .device_id = 0xF1, .read_id_fourth_byte = 0x15, .capacity = 1024, .timing = { .trp = 25, .trh = 20, /* FIXME: this value wasn't found in datasheet */ .twp = 40, .twh = 20, .tcs = 20, /* FIXME: this value is 0 in datasheet */ .twhr = 60, .tcr_tar_trr = 20, .twb = 100, .trp_resp = 25, /* FIXME */ .tadl = 100, }, }, };
Все значения таймингов и ID можно найти в даташите на микросхему. В большинстве случаев название тайминга в коде будет соответствовать таковому в даташите.
Для включения поддержки MTD и NAND в ядре нужно изменить следующие опции конфига:
CONFIG_MTD=y CONFIG_MTD_CHAR=m CONFIG_MTD_BLKDEVS=m CONFIG_MTD_BLOCK=m CONFIG_MTD_BLOCK_RO=m CONFIG_FTL=m CONFIG_NFTL=m CONFIG_NFTL_RW=y CONFIG_INFTL=m CONFIG_RFD_FTL=m CONFIG_SSFDC=m CONFIG_SM_FTL=m CONFIG_MTD_NAND_TEGRA=y CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_ECC=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_VERIFY_WRITE=y CONFIG_MTD_NAND_BCH=y CONFIG_MTD_NAND_ECC_BCH=y CONFIG_MTD_NAND_GPIO=y CONFIG_MTD_NAND_PLATFORM=y
Проблемы с OOB и badblocks
В NAND памяти используется разделение на страницы (page). В текущей версии драйвера поддерживаются чипы с page size 2k и 4k; для чипов с другим размером страниц потребуется модификация драйвера.
Каждая страница сопровождается out-of-band блоком, размер которого зависит от размера страницы. Блок содержит контрольные суммы, предназначенные для проверки и коррекции данных, информацию о состоянии блока и другую служебную информацию. Коррекция данных в случае с Tegra реализована на аппаратном уровне.
Скорее всего, найденный вами чип памяти будет содержать структуру oob-блока, отличную от того, что используется в tegra-драйвере. Это приведет к тому, что MTD будет считать, что большая часть блоков на устройстве повреждена. Возможны следующие решения этой проблемы:
- Прошить NAND-флешку на программаторе. Основным недостатком метода является необходимость наличия программатора.
- Можно попробовать переписать функцию tegra_nand_block_isbad так, чтобы блок всегда считался рабочим. Это может привести к потере данных и сбоях в UBIFS. Однако, в моем случае никакие другие методы не сработали, сделал так, что check_block_isbad всегда возвращает 0, очистил флешку с помощью flash_eraseall и вернул проверку бэд-блока обратно. После этого нужно запустить nandtest -m, чтобы действительно нерабочие блоки были отмечены соответствующим образом.
В текущей версии драйвера неправильно определяется размер spare-области в функциях чтения-записи oob-данных. Исправляется это следующим патчем:
Кроме того, для работы с UBI потребуется исправить установку значения размера буфера записи в функции tegra_nand_scan:
Файл:Tegra-writebufsize-fix.patch
После этого можно собирать ядро, прошивать и общаться с новоявленной памятью посредством mtd_debug из пакета mtd-utils. Если ubiformat считает подавляющее большинство блоков исправными — вам повезло, и вы можете создать раздел, используя ubimkvol.
Проблемы с UBI и ECC
В данный момент UBI отказывается монтировать созданные разделы. Если включить в ядре опцию отладки UBI, можно увидеть следующие сообщения в dmesg:
[ 1134.971829] UBI error: ubi_io_read: error -74 (ECC error) while reading 126976 bytes from PEB 512:4096, read 126976 bytes [ 1135.147497] UBI error: ubi_io_read: error -74 (ECC error) while reading 126976 bytes from PEB 512:4096, read 126976 bytes [ 1135.155329] UBIFS error (pid 6138): ubifs_recover_master_node: failed to recover master node
Как видно, при чтении происходит ошибка ECC. Об этом же говорит и nandtest:
root@user-laptop:~# nandtest -m /dev/mtd0 ECC corrections: 0 ECC failures : 516064 Bad blocks : 0 BBT blocks : 0 005c0000: reading...
Однако, чтение/запись данных происходит без ошибок, и nandtest не отмечает bad-блоки.
UPD: UBI выдает ошибку failed to recover master node даже в том случае, если в драйвере принудительно отключить проверку ECC. UPD2: возможно, это относится только к моему случаю, но get_master_node падает тут и возвращает -EINVAL. UPD3: опытным путем было установлено, что ECC то ли не работает, то ли не справляется с ошибками на данной конкретной флешке. На многих страницах четвертый байт поврежден:
[ 240.284142] UBIFS error (pid 1373): ubifs_scan: corrupt empty space at LEB 3:2561 [ 240.291784] UBIFS error (pid 1373): ubifs_scanned_corruption: corruption at LEB 3:2561 [ 240.302846] 00000000: ffffff5f ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff _............................... [ 240.313488] 00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.325211] 00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.336906] 00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.348725] 00000080: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.359398] 000000a0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.371115] 000000c0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.382827] 000000e0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.394513] 00000100: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.406197] 00000120: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.417881] 00000140: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.429711] 00000160: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.441411] 00000180: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.453317] 000001a0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.465120] 000001c0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.475791] 000001e0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.487642] 00000200: ffffff5f ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff _............................... [ 240.499519] 00000220: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.511337] 00000240: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.523233] 00000260: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.534921] 00000280: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.545615] 000002a0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.557428] 000002c0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.569194] 000002e0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.580958] 00000300: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.592679] 00000320: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.604365] 00000340: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.615018] 00000360: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.626921] 00000380: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.638773] 000003a0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.650689] 000003c0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.662768] 000003e0: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ................................ [ 240.674924] 00000400: ffffff5f ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff _...............................
UPD4: в функции prep_transfer_dma не указывается размер tag-данных, поэтому в NAND при записи они не попадают. Патч в разработке. Подробную информацию о процессе записи можно найти в Tegra Reference Manual в разделе 16.3.5.7 Multiple Page Write with HW ECC and Tag Information (стр. 613).
Помимо прочего, была найдена другая реализация драйвера. Отдаленно напоминает текущий драйвер, возможно, это его переписанная версия. Выглядит чуть лучше и поддерживает больше чипов. Процесс записи можно также посмотреть там.
TODO
- Добавить фотографии
- Настроить UBI, YAFFS или другую ФС для доступа к памяти как к обычному устройству хранения
- Убрать лишние опции конфига
- Написать, как создать и подключить UBI-раздел.