vgovseychuk 0 11 марта, 2016 Опубликовано 11 марта, 2016 · Жалоба Привет, Электроникс! Пытаюсь обновиться из-под линукса. В sysupgrade нет поддержки UBI, так что пытаюсь сделать обновление вручную. При попытке переписать в лоб - ошибка (хотя mtd write работает): root@TestTest:/# ubiupdatevol dev/ubi0_0 /tmp/rootfs.img [ 2885.328555] UBI error: ubi_open_volume: cannot open device 0, volume 0, error -16 ubiupdatevol: can't open 'dev/ubi0_0': Device or resource busy Посмотрел, как это делает sysupgrade: Сначала копирует необходимые бинарники, а затем переключается на работу из оперативки. У меня переключение рута в tmp/root не удалось (не понял принципа, ибо нуб) В общем интересуют 2 вопроса: 1. Как переключаться на работу из оперативки, освобождая тем самым /dev/ubi0_0? 2. Если есть более удобный способ обновления системы с UBI? P.S. разделы у меня такие: ----------------------------------------------------------------- |bootloader|boot_env| fdt | kernel | root | MTD | 3M | 256k | 128k | 5M | - | ----------------------------------------------------------------- |rootfs|rootfs_data| UBI | 40M | - | ----------------------------------------------------------------- Части системы (fdt, kernel, rootfs) пишу в пямять по отдельности. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 17 марта, 2016 Опубликовано 17 марта, 2016 (изменено) · Жалоба В sysupgrade нет поддержки UBI, так что пытаюсь сделать обновление вручную. Поскольку никто Вам не отвечает, решил вставить реплику. Сразу скажу, что ответов на ваши конкретные вопросы у меня нет. Но есть другая мысль. Насколько я понял (после гугленья sysupgrade), Вы планируете делать апгрейд следующим образом: нужные файлы (например конфиги) сохраняются на другой FS, корневая FS полностью стирается и переписывается новым образом, после чего сохраненные файлы возвращаются на место. Суть моей реплики - нафига Вам переписывать всю файловую систему целиком? Почему бы не воспользоваться системой пакетов и каким-либо пакетным менеджером? Описанной проблемы тогда у Вас не будет в принципе, в процессе обновления будут переписываться только реально обновляемые файлы... Может Вы и ответа не получаете именно потому, что выбранным Вами путем мало кто идет? Еще несколько преимуществ использования пакетов: - Не надо заново выкачивать и перезаписывать образ всей файловой системы ради крошечного обновления (к примеру, чтобы обновить SSL-сертификат), достаточно одного малюсенького пакетика. - Перерыв в работе системы отсутствует совсем или минимален - после обновления требуется перезапуск только реально обновившихся компонентов. - Гибкость - на разных системах может быть разный набор пакетов. Изменено 17 марта, 2016 пользователем alx2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vgovseychuk 0 17 марта, 2016 Опубликовано 17 марта, 2016 · Жалоба Вообще да, можно и так. Но это же каждый раз надо вписывать в скрипт, какие пакеты и файлы ты обновлял. Может Вы и ответа не получаете именно потому, что выбранным Вами путем мало кто идет? Я посчитал такой вариант наиболее верным с оглядкой на то, как это сделано, например, в роутерах. В любом случае, большое спасибо за совет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vgovseychuk 0 17 марта, 2016 Опубликовано 17 марта, 2016 (изменено) · Жалоба Сделал полное обновление немного кривым способом, потеряв где-то 20% места на NAND: выделил разделы под запись обновляемых файлов: updfdt(размер 0х40000), updkernel(0х500000), updroot(последний включен в UBI, 0х2а00000). Из этого вытекает вопрос контроля того, что записали. Я пишу из-под линукса скачанные файлы обновления в запасные разделы командами встроенных утилит: mtd erase updroot mtd write rootfs.img updroot mtd erase updkern mtd write openwrt-mxs-uImage updkern fw_setenv filesize_kernel $(printf %x $(stat -c %s openwrt-mxs-uImage)) mtd erase updfdt mtd write TestTest.dtb updfdt fw_setenv filesize_fdt $(printf %x $(stat -c %s TestTest.dtb)) А из бутлоадера "nand read ${loadaddr} updfdt 0x40000;" "nand erase.part fdt;" "nand write ${loadaddr} fdt 0x40000;" "nand read ${loadaddr} updkern 0x500000;" "nand erase.part kernel;" "nand write ${loadaddr} kernel 0x500000;" "ubi part root; " "ubi read ${loadaddr} updroot 0x2A00000; " "nand erase.part root; " "ubi part root; " "ubi create updroot 0x2A00000; " "ubi create rootfs 0x2A00000; " "ubi create rootfs_data; " "ubi write ${loadaddr} rootfs 0x2A00000" Меня интересуют механизмы работы команд mtd, nand, ubi (проверяют ли они бэдблоки, надо ли следить, что они записали). Например, нет команды mtd read в OpenWrt, и не проверить, правильно ли все записалось. Или как узнать, все ли бутлоадер правильно прочтет, если в разделе есть так любимые NAND-ом бэдблоки. Нормально ли то, что я копирую весь раздел операцией read/write а не размер файла(понятно, что это медленнее, но что будет происходить при наличии бэдблоков)? P.S. В Openwrt есть еще команда nandwrite. Может, ее применять вместо mtd write? P.P.S Посмотрел в коде mtd и nandwrite, вроде, есть проверка бэдблоков при записи. Изменено 17 марта, 2016 пользователем vgovseychuk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Вообще да, можно и так. Но это же каждый раз надо вписывать в скрипт, какие пакеты и файлы ты обновлял. Не понял, о каком скрипте Вы говорите. Возможно, Вы не совсем понимаете, как работают менеджеры пакетов. В системе имеется список пакетов, установленных в текущий момент. При необходимости обновиться менеджер пакетов скачивает из репозитория свежий список пакетов и сравнивает с установленными. Если он видит в списке пакет более поздней версии, чем установленный, то новый пакет скачивается и устанавливается. Все это (и многое другое, я тут сильно упростил процесс) выполняет готовый менеджер пакетов, Вам как разработчику об этом заботиться не надо, разве что не забывать менять версию пакета (да и это можно автоматизировать, у меня версии пакетов формируются автоматически из ревизии SVN)... Например, нет команды mtd read в OpenWrt, и не проверить, правильно ли все записалось. Хм... Да, mdt read нет. Но чем Вас не устраивает mtd verify? Или как узнать, все ли бутлоадер правильно прочтет, если в разделе есть так любимые NAND-ом бэдблоки. Смотрите документацию/код вашего бутлоадера. Вы, кстати, не сказали, каким бутлоадером пользуетесь. Например u-boot может читать как с учетом, так и без учета бэдблоков. В вашем случае, очевидно, бэдблоки надо учитывать, поэтому вместо nand read следует использовать nand read.jffs2 (если у Вас u-boot). То же самое касается nand write. Нормально ли то, что я копирую весь раздел операцией read/write а не размер файла(понятно, что это медленнее, но что будет происходить при наличии бэдблоков)? В общем случае - не нормально. Это может быть нормально, если целевой раздел (куда мы копируем) больше размера копируемых данных, и даже при наличии бэдблоков данные в него заведомо влезут. Иначе, если в процессе записи будет пропуск бэдблока, запись "вылезет" за пределы раздела. У Вас здесь, кстати, вообще какая-то путаница с размерами: в первом сообщении Вы пишете, что размер раздела fdt 128k. А теперь Вы пишете в него данные размером 0x40000, то есть 256k! :) Надеюсь, это не ошибка, а Вы просто поменяли разбивку... P.S. В Openwrt есть еще команда nandwrite. Может, ее применять вместо mtd write? Это - на Ваш вкус. Лично я именно nandwrite использую для обновления ядра. И еще вопрос - зачем Вы fdt и ядро переписываете дважды (через промежуточные разделы)? С файловой системой понятно - Вы не можете переписать ее пока она смонтирована. Но с fdt и kernel-то какая проблема? Вы не перемудрили ли здесь? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vgovseychuk 0 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Не понял, о каком скрипте Вы говорите.Скрипт для обновления изначальных конфигов, например, или добавления новых файлов. В общем для тех файлов, которые не охвачены менеджером пакетов. Я понимаю, что по-хорошему все файлы должны генериться тем или иным пакетом, но я до этого пока не дошел и почти вручную меняю некоторые конфиги. Вы, кстати, не сказали, каким бутлоадером пользуетесь ... В вашем случае, очевидно, бэдблоки надо учитывать, поэтому вместо nand read следует использовать nand read.jffs2 (если у Вас u-boot).Пользуюсь U-Boot 2014.10. Не знал, что есть функции nand read(write).jffs2. Думал, что nand write учитывает bad, а write.raw как раз пишет без них. Буду смотреть и пробовать. Иначе, если в процессе записи будет пропуск бэдблока, запись "вылезет" за пределы раздела.Вот, это и подозревал, спасибо, исправлю зачем Вы fdt и ядро переписываете дважды (через промежуточные разделы)Да, явно перемудрил И еще один вопрос про чтение/запись: Как пример, у меня есть разделы: и vol2 и они "физические", т.е. их видно в mtdparts в U-Boot, и на разделе vol2 есть логические разделы UBI (vol2_ubi1, на котором root ubifs, и vol2_ubi2, куда я пишу обновление). Если я пишу из линукса в vol2_ubi2: mtd write rootfs.img vol2_ubi2 fw_setenv filesize_rootfs $(printf %x $(stat -c %s rootfs.img)) и в vol1: mtd write rootfs.img vol1 fw_setenv filesize_rootfs $(printf %x $(stat -c %s rootfs.img)) то как они запишутся и как их считать правильно в оперативку из U-Boot? vol1 как nand с учетом bad, а vol2_ubi2 как UBI? P.S. Большое спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vgovseychuk 0 18 марта, 2016 Опубликовано 18 марта, 2016 · Жалоба Например u-boot может читать как с учетом, так и без учета бэдблоков. В вашем случае, очевидно, бэдблоки надо учитывать, поэтому вместо nand read следует использовать nand read.jffs2 (если у Вас u-boot). То же самое касается nand write. Посмотрел код U-Boot (cmd_nand.c). Просто nand read(write) тоже учитывает бэдблоки: (в районе 690 строки) ret = nand_read_skip_bad(nand, off, &rwsize, NULL, maxsize, (u_char *)addr); как они запишутся и как их считать правильно в оперативку из U-Boot? vol1 как nand с учетом bad, а vol2_ubi2 как UBI? Методом проверки на своем девайсе (как раз бэдблок в root) выяснил, что вроде все так. Только есть нюанс: если мы записываем из линукса файл в UBI, и передаем в переменную бута его размер(как в линуксе), этот размер не сойдется с размером для убута. В итоге при перезаписи целостность не сохранится и как минимум получаем предупреждение: UBI warning: ubi_io_read: error -74 (ECC error) while reading 2048 bytes from PEB 1206:2048, read only 2048 bytes, retry [ 3.319056] UBI error: ubi_io_read: error -74 (ECC error) while reading 2048 bytes from PEB 1206:2048, read 2048 bytes [ 3.329885] CPU: 0 PID: 1 Comm: swapper Not tainted 3.18.23 #73 [ 3.335829] Backtrace: .... Итог: переразметил так: ---------------------------------------------------------------------- |bootloader| fdt | kernel | updroot | root | MTD | 5M | 256k | 5M | 40M | - | ---------------------------------------------------------------------- |rootfs|rootfs_data| UBI | 40M | - | ---------------------------------------------------------------------- Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 20 марта, 2016 Опубликовано 20 марта, 2016 · Жалоба Посмотрел код U-Boot (cmd_nand.c). Просто nand read(write) тоже учитывает бэдблоки: (в районе 690 строки) Да, верно. В 2014.10 просто read бэдблоки пропускает. Я использую другую версию, там просто read не пропускает... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться