LINUX.ORG.RU

Не монтируется rootfs с некоторых sd-карт

 ,


0

1

Вводные данные

Есть образ для sd:

$ gdisk -l sdcard.img
GPT fdisk (gdisk) version 1.0.10

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
Disk sdcard.img: 1105960 sectors, 540.0 MiB
Sector size (logical): 512 bytes
Disk identifier (GUID): B00D8182-4B3E-46AB-A778-EA132328E92D
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 1105926
Partitions will be aligned on 2048-sector boundaries
Total free space is 16357 sectors (8.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1           16384           24575   4.0 MiB     8300  uboot
   2           24576           32767   4.0 MiB     8300  misc
   3           32768          163839   64.0 MiB    8300  boot
   4          163840          425983   128.0 MiB   8300  recovery
   5          425984          491519   32.0 MiB    8300  backup
   6          491520         1105919   300.0 MiB   8300  rootfs

Заливаю следующим образом:

$ dd if=sdcard.img of=/dev/sdc bs=1M status=progress && sync

С некоторыми sd всё замечательно. После dd сразу можно сделать:

# mount /dev/sdc6 mnt/

И всё работает. А с другими какая-то фигня. sd-карты разных размеров: 8, 16, 32 гб.

Какая-то фигня

Другие sd-карты. Делаю всё также dd (можно предварительно if=/dev/zero для надёжности).

Если воткнуть в устройство

Устройство запускается uboot и kernel запускаются. Но потом случается kernel panic:

Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,6)

Если попробовать примонтировать

[173705.740640] EXT4-fs (sdc6): VFS: Can't find ext4 filesystem
[173705.741159] EXT4-fs (sdc6): VFS: Can't find ext4 filesystem
[173705.741470] EXT4-fs (sdc6): VFS: Can't find ext4 filesystem
[173705.759537] ISOFS: Unable to identify CD-ROM format.
[173705.759835] FAT-fs (sdc6): bogus number of reserved sectors
[173705.759837] FAT-fs (sdc6): Can't find a valid FAT filesystem
[173705.760256] hfs: can't find a HFS filesystem on dev sdc6
[173705.760632] hfsplus: unable to find HFS+ superblock
[173705.761486] exFAT-fs (sdc6): invalid boot record signature
[173705.761488] exFAT-fs (sdc6): failed to read boot sector
[173705.761489] exFAT-fs (sdc6): failed to recognize exfat type

А что говорит gdisk?

Caution: invalid backup GPT header, but valid main header; regenerating
backup header from main header.

Warning! Main and backup partition tables differ! Use the 'c' and 'e' options
on the recovery & transformation menu to examine the two tables.

Warning! One or more CRCs don't match. You should repair the disk!
Main header: OK
Backup header: ERROR
Main partition table: OK
Backup partition table: ERROR

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: damaged

****************************************************************************
Caution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk
verification and recovery are STRONGLY recommended.
****************************************************************************

Command (? for help): v

Caution: The CRC for the backup partition table is invalid. This table may
be corrupt. This program will automatically create a new backup partition
table when you save your partitions.

Identified 1 problems!

Откуда эти проблемы берутся? Как их лечить?

Ну с разметкой GPT всё как раз понятно: бэкап таблицы разделов в конце диска. Естесна, после dd он не находится. А вот по поводу остального - скорее или карточки битые или кард-ридер хреновый. Или то и другое вместе.

lonelywoolf
()
Ответ на: комментарий от lonelywoolf

или карточки битые

А вот хз. Коллега целую партию новых купил. Уже две попробовал. И, вроде, карточка, которая до этого нормально работала, внезапно стала себя также вести.

или кард-ридер хреновый

Три разных пробовал.

Jullyfish
() автор топика
Ответ на: комментарий от Jullyfish

Может ошибся. :^)

Я ошибся.

$ dd if=/dev/sdc of=test.img count=2
2+0 records in
2+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 6.1817e-05 s, 16.6 MB/s
$ dd if=/dev/sdc of=test.img count=2 bs=4K
2+0 records in
2+0 records out
8192 bytes (8.2 kB, 8.0 KiB) copied, 0.000121917 s, 67.2 MB/s
Jullyfish
() автор топика
Ответ на: комментарий от anonymous

Попробовал с той карточкой, которая работает нормально:

$ dd if=sdcard.img of=/dev/sdc && sync
$ dd if=/dev/sdc of=test.img bs=1024 count=552980
$ du -b sdcard.img test.img 
566251520	sdcard.img
566251520	test.img
$ diff sdcard.img test.img
Binary files sdcard.img and test.img differ

rootfs из обоих img успешно монтируется.

Jullyfish
() автор топика
Ответ на: комментарий от Jullyfish

Binary files sdcard.img and test.img differ сделай обоим файлам hex-dump и посмотри текстовым diff по каким смещениям разница и как она выглядит. (или утилитой для визуализации бинарного diff, но с ними туго)

И, на всякий случай - там перед записью точно все разделы отмонтированы? А то если есть какое-то автомонтирование, оно может монтировать разделы в неудачный момент и потом файловая система может что-то пытаться записать в метаданные

GPFault ★★★★
()

возможно, банально твоя карта просто раздуплиться не успевает(такое и с усб-флешками бывает)
попробуй указать параметр ведру rootdelay=5(время ожидания в секундах) или rootwait

madcore ★★★★★
()
Ответ на: комментарий от Jullyfish

Раздел, кстати, очень похож на ограничение BIOS/DOS в 504 Миб. Случайность, или…? :)

yars068 ★★★★★
()
Ответ на: комментарий от GPFault

сделай обоим файлам hex-dump и посмотри текстовым diff по каким смещениям разница и как она выглядит. (или утилитой для визуализации бинарного diff, но с ними туго)

У вас часть текста в цитату улетела, но хорошо, что заметил.

Что интересно, разница совсем небольшая:

15728707,15728708c15728707,15728708
< 0f000420: 0080 0000 0080 0000 8065 0000 5c3a aa6a  .........e..\:.j
< 0f000430: 623a aa6a 0100 ffff 53ef 0100 0100 0000  b:.j....S.......
---
> 0f000420: 0080 0000 0080 0000 8065 0000 2a59 aa6a  .........e..*Y.j
> 0f000430: 3159 aa6a 0400 ffff 53ef 0100 0100 0000  1Y.j....S.......
15728728c15728728
< 0f000570: 0000 0000 0401 0000 191c 0200 0000 0000  ................
---
> 0f000570: 0000 0000 0401 0000 1d1c 0200 0000 0000  ................
15728768c15728768
< 0f0007f0: 0000 0000 0000 0000 0000 0000 7b56 dd09  ............{V..
---
> 0f0007f0: 0000 0000 0000 0000 0000 0000 08a3 f406  ................

А то если есть какое-то автомонтирование

На 100% не могу исключать. Как в современных дистрах это отключать – затрудняюсь ответить.

Хотя, я проводил опыт, сделав dd на Slackware без запущенной графики, там, кажется нечему делать automount.

Jullyfish
() автор топика
Ответ на: комментарий от madcore

посмотреть через «mount» и при необходимости руками сделать umont никак?

Как. Всё чисто. :^)

Jullyfish
() автор топика

Если сначала загрузить образ на «хорошую» sd-карту и выгрузить обратно:

$ dd if=/dev/sdc of=goodsd.img bs=1024 count=552980

то следующая команда отработает успешно:

# mount -o offset=$(( 512*491520 )) goodsd.img mnt/

А если взять «плохую» sd-карту:

$ dd if=/dev/sdc of=badsd.img bs=1024 count=552980

то следующая команда завершится с ошибкой:

# mount -o offset=$(( 512*491520 )) badsd.img mnt/
wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.
       dmesg(1) may have more information after failed mount system call.

Если сделать:

$diff badsd.img goodsd.img

То там с какого-то момент идёт огромный выхлоп. И в badsd.img очень много нулей в местах где должны быть данные.

Jullyfish
() автор топика
Ответ на: комментарий от Jullyfish

Предположение @lonelywoolf о том, что резервная копия GPT, находящаяся в конце диска, теряется после dd, проверял? Попробуй создать GPT-разметку не непосредственно на флешке, а сначала на файле, залить туда файлы, и уже образ заливать через dd. В этом случае резервная GPT останется на месте, но может возникнуть другая проблема – у файла, в отличие от флешки, нет CHS-геометрии, даже виртуальной. А флешка эту самую геометрию эмулирует. Помнится, тоже долго возился с подобной проблемой, пытаясь понять, почему у меня какой-то образ не загружался. Только в моём случае, если мне память не изменяет, была MBR-разметка и FAT. И помогло вроде бы указание правильного аргумента для ключа -g в аргументах mkdosfs.

yars068 ★★★★★
()
Последнее исправление: yars068 (всего исправлений: 4)
Ответ на: комментарий от Jullyfish

всё в районе одного смещения.

Наверное хорошо бы понять где это смещение расположено с точки зрения таблицы разделов - является ли оно примерно началом или концом одной из фс?

GPFault ★★★★
()
Ответ на: комментарий от yars068

Там разница в районе 0x0f000000. Может быть это в районе границы между какими-то разделами на образе

GPFault ★★★★
()
Последнее исправление: GPFault (всего исправлений: 1)
Ответ на: комментарий от GPFault

Посчитал. Конец 6-го раздела – это 0x21BFFE00, пятого – 0xEFFFE00, четвёртого – 0xCFFFE00, третьего – 0x4FFFE00… То есть, это где-то в шестом разделе, который начинается с 0xF000000 как раз. Остаётся понять, что лежит по данным смещениям в этом разделе.

yars068 ★★★★★
()
Последнее исправление: yars068 (всего исправлений: 1)
Ответ на: комментарий от yars068

6й я так понимаю rootfs в ext4 и что-то меняет его начало.

Но может быть в конкретном случае это даже не порча, а просто последвия попытки примонтировать, какие-нибудь тайстемпы

GPFault ★★★★
()
Ответ на: комментарий от GPFault

Ну, если это суперблок корня, то, возможно, это именно флешка виновата – отдаёт мусор вместо записанных данных (она рапортует успех записи, но по факту читает мусор и нули?). @Jullyfish, попробуй на проблемных флешках sudo badblocks -s -w /dev/sdX. Может, что найдётся. Только осторожно, эта команда уничтожит данные на указанном носителе.

yars068 ★★★★★
()
Последнее исправление: yars068 (всего исправлений: 1)
Ответ на: комментарий от Jullyfish

0x0f000420 = 251658240
251659296-491520*512-1024 = 32 = 0x20

Суперблок ext4:
struct ext4_super_block {
/*00*/  __le32  s_inodes_count;         /* Inodes count */
        __le32  s_blocks_count_lo;      /* Blocks count */
        __le32  s_r_blocks_count_lo;    /* Reserved blocks count */
        __le32  s_free_blocks_count_lo; /* Free blocks count */
/*10*/  __le32  s_free_inodes_count;    /* Free inodes count */
        __le32  s_first_data_block;     /* First Data Block */
        __le32  s_log_block_size;       /* Block size */
        __le32  s_log_cluster_size;     /* Allocation cluster size */
/*20*/  __le32  s_blocks_per_group;     /* # Blocks per group */
        __le32  s_clusters_per_group;   /* # Clusters per group */
        __le32  s_inodes_per_group;     /* # Inodes per group */
        __le32  s_mtime;                /* Mount time */
Первое различие — s_mtime, 1789540956 и 1789548842. Первая половина дня по UTC 16 Sep 2026.

Второе различие (0f000570) — это s_kbytes_written, увеличилось на 4, значит была запись 4096 байт — один блок ФС (записывался суперблок из-за изменения s_mtime).

Третье различие (0f0007f0) — это s_checksum.

Всё показывает, что где-то между вашими dd одна из ФС монтировалсь. Уж не знаю, сами вы до этого додумались — монтировать ФС не в RO, а потом удивляться, почему не совпадает, или какое автомонтирование у вас буйствует. Но, эти различия вполне объяснимы.

А всякие большие различия — глюки SD-карты, да, они с магазина бывают битые. И

можно предварительно if=/dev/zero для надёжности

никак надёжности не прибавит, да и badblocks не очень. Карты нужно мучать F3 https://github.com/AltraMayor/f3 там пишется не повторяющаясь последовательность байт, так что всякие глюки карты, типа запись по одним адресам портит другие проявляется. Можно погуглить по команде f3probe, чтобы примеры использования посмотреть.

Или генерить из /dev/urandom файл размером с SD-карту, dd туда, dd обратно в другой файл, сравнивать.

mky ★★★★★
()
Ответ на: комментарий от Jullyfish

То там с какого-то момент идёт огромный выхлоп

Я же тебе сказал - у тебя или карты дерьмо или кард-ридер или все вместе взятое. У тебя нули на карте. Хотя чего это я.

Короче. Теперь варианта у тебя два: либо скорость этих SD ужасно низкая (а ты делаешь без sync) и у тебя просто записывается на флэху хрен да нихрена, либо у тебя эти SD фактически трупы изначально.

  1. После dd на карту сделай sync из консоли. Параллельно хорошо бы посмотреть dmesg. Может так, что у тебя скорость записи на карточку - не больше полумегабайта в секунду, например.

  2. Да просто банально форматируешь карточку и кладешь в нее большой файл. А потом читаешь этот файл с карточки и сравниваешь с эталоном. Если карточка битая - у тебя файл побьется. Ну, конечно, перед копированием файла обратно надо ее отмонтировать и передернуть (гусары, молчать!) в ридере (карточку).

Такое ощущение, что купили рассыпуху у китайцев уже мертвую при изготовлении по дешёвке и вот щас че-то делать с ней пытаетесь.

lonelywoolf
()
Ответ на: комментарий от yars068

что резервная копия GPT, находящаяся в конце диска, теряется после dd, проверял?

Это проверять не надо, это стандарт. mbr всегда была в начале диска. GPT - в конце держит копию. Поэтому при запуске gdisk ему ее создает и ругается. Само по себе наличие или отсутствие копии GPT в конце (пока не повреждена копия в начале) ни на что не влияет. А когда он делает разметку через условный fdisk или с помощью dd записывает образ другого устройства, логично, что размер нового девайса больше и в конце у него нулики.

Не, если он на флэху 512 метров кидает образ 8 гиг, то тут я уже могу сказать только «кек».

lonelywoolf
()
Ответ на: комментарий от mky

Да какое тут автомонтирование, если с одной картой работает, а с другой не работает - т.е. он четко говорит, что прямая корелляция от карточки. А вот то, что для embedded подходят не все карточки - это уже вариант.

Бывают случаи, когда карте не хватает питания в embedded девайсе. То есть она вроде рабочая, но в части железок уже тормозит, глючит и отдает мусор. Это известно ещё с древних времён, когда одна карточка в одном телефоне работает прекрасно, а в другом - бьет файлы или прикидывается трупом, а то и вовсе не видна. Поэтому в сое время когда я был продавалкой в магазине (20 лет назад) - люди приходили за MicroSD в мобилу им предлагались дорогие от SanDisk/Kingston и рядом клали дешевую от нонейма и объясняли, что дешевая может доставить сюрпрайзов.

lonelywoolf
()
Ответ на: комментарий от lonelywoolf

А, во. вот пример на столе лежит. Флэха от SanDisk на 64 гига живая и Lexar так же на 64 гига (скорее подделка) - полудохлая. Вторая работает крайне медленно и сыплет ошибками иногда при вычитке или записи сразу большого объема данных (больше 2 гигов залпом), а первая живет нормально. Но даже после записи во вторую успешной, если вторую вставить в ТВ-приставку, она начинает бить содержимое (именно бить даже то, что не читалось). А в ноуте с горем-пополам она данные не бьет, просто отваливается и если читать с нее кусками по гигабайту - то, в общем-то, даже работает.

lonelywoolf
()
Ответ на: комментарий от lonelywoolf

Я про различия с той картой, которая работает. Если автомонтирования нет, значит ТС сам монтирует в RW, а в списке команды монтирования/отмонтирования не показывает.

не хватает питания в embedded девайсе.

Забыли про embedded, ТС уже занимается dd туда и обратно. Да, и sync он делает, если верить приводимым им командам.

mky ★★★★★
()
Ответ на: комментарий от lonelywoolf

Да, только у ТС ещё не

dev/mmcblkXXX

а /dev/sdc, он пока usb-кардридером пишет/читает и получает разницу между записанным и прочитанным.

И в badsd.img очень много нулей в местах где должны быть данные.

И, если у него три разных кардридера дают одинаковую картину, получается, что карточки хлам.

Коллега целую партию новых купил. Уже две попробовал

получается, коллега ТС купил партию хлама :(

losetup img1 && mount - success

Да, только mount лучше делать RO, иначе содержимое img1 чуть-чуть меняется, и потом получается, что img1 не совпадает с тем, что записывали на хорошую SD-карту.

mky ★★★★★
()
Ответ на: комментарий от GPFault

На всякий случай уточню. Коротенький diff это результат следующих команд:

$ dd if=sdcard.img of=/dev/sdc bs=1M && sync
Вытаскиваю sd-карту из usb-reader и вставляю обратно в него же.
$ dd if=/dev/sdc of=goodsd.img bs=1024 count=552980
$ diff goodsd.img sdcard.img 
Binary files goodsd.img and sdcard.img differ
$ xxd sdcard.img > sdcard.hex
$ xxd goodsd.img > goodsd.hex
$ diff goodsd.hex sdcard.hex

sdcard.img исходный образ для sd-карты, goodsd.img значит, что образ я списал с хорошей карточки. Т.е. всё работает.

Jullyfish
() автор топика
Ответ на: комментарий от mky

Уж не знаю, сами вы до этого додумались — монтировать ФС не в RO, а потом удивляться, почему не совпадает, или какое автомонтирование у вас буйствует. Но, эти различия вполне объяснимы.

Очень круто, спасибо! Ручками не монтирую, это автомонтирование буйствует, которое исходно есть в системе. Его никак не настраивал.

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

Добавил в очередь напопробовать.

Jullyfish
() автор топика
Последнее исправление: Jullyfish (всего исправлений: 1)
Ответ на: комментарий от lonelywoolf
  1. После dd на карту сделай sync из консоли.

После dd у меня всегда стоит && sync.

  1. Да просто банально форматируешь карточку и кладешь в нее большой файл. А потом читаешь этот файл с карточки и сравниваешь с эталоном.

Попробую.

Jullyfish
() автор топика
Ответ на: комментарий от mky

что карточки хлам.

Именно на это я и намекаю, очень толсто. Как мне кажется, сначала надо просто больших файлов туда покидать и посмотреть, будут ли они там биться. Это однозначно покажет, живые они или нет.

lonelywoolf
()
Ответ на: комментарий от Jullyfish

А. Ну если разница возникает после этого - то у тебя битые SD. Не, ну если у тебя автомонтироание срабатывает при записи образа… Но это звяздец, конечно же.

lonelywoolf
()
Ответ на: комментарий от lonelywoolf

звяздец

Ну, вообще да – я недавно брал USB 3.x флешку, сначала взял подешевле и там возникла как раз такая ситуация, что она не справлялась с копированием на неë больших файлов. Поменял с доплатой на более дорогую и всë сразу же заработало.

yars068 ★★★★★
()
Ответ на: комментарий от yars068

Это как? Здесь либо флэшка битая, либо она просто медленная на запись. Если она уходит в аут при копировании большого файла - это всё, это брак, флэха битая. У меня есть флэшки, которые имеют скорость записи что-то около 7 метров секунду, а когда пишешь весь объем (20-100 гектар) - она уходит в троттлинг и скорость падает буквально до полутора метров в секунду, но чтобы она именно «не справлялась» - это ой. Такому место в мусоре.

lonelywoolf
()

Хозяйке на заметку:
dd, встретив ошибку, завершает работу.
Вопрос: контролировалась ли длина записанного?

PS. Чтобы и не завершал, и смещения входа/выхода оставались синхронными, можно добавить conv=noerror,sync, но в данной конкретной ситуации это скорее вредно, чем полезно.

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)
Ответ на: комментарий от bormant

Вопрос: контролировалась ли длина записанного?

Ну он же прям в выводе в консоль плюнет, что завершился по ошибке.

lonelywoolf
()
Ответ на: комментарий от lonelywoolf

Там файл сначала попадал в кэш на хорошей скорости, потом ФМ делал sync(), и на этом скорость начинала плавно сходить на нет. А когда случался этот самый «нет», флешка отваливалась и переподключалась под новым именем. А под виндой процесс копирования просто вис.

yars068 ★★★★★
()
Ответ на: комментарий от yars068

Ну да. Классический брак по отвалу контроллера ввиду его перегрева, либо зависания из-за медленного флэша. В общем, одна из причин, по которой я стараюсь не брать нонейм-флэшки.

lonelywoolf
()
  1. Берёте несколько разных карт-ридеров, USB2 и USB3
  2. Берёте https://github.com/AltraMayor/f3/
  3. Запускаете f3brew на /dev/sdX 3-4 раза
  4. Если флешка не проходит валидацию — откладываете и тестируете в другом ридере
  5. Если не проходит и в другом ридере — возвращаете в место покупки или выкидываете в мусорку

Плохих MicroSD-флешек, особенно на китайских площадках, просто уйма.

У флешек есть несколько скоростей шины и стандартов питания:

  • Default Speed mode: 3.3V signaling, Frequency up to 25 MHz, up to 12.5 MB/sec
  • High Speed mode: 3.3V signaling, Frequency up to 50 MHz, up to 25 MB/sec
  • SDR12: UHS-I 1.8V signaling, Frequency up to 25 MHz, up to 12.5MB/sec
  • SDR25: UHS-I 1.8V signaling, Frequency up to 50 MHz, up to 25MB/sec
  • SDR50: UHS-I 1.8V signaling, Frequency up to 100 MHz, up to 50MB/sec
  • DDR50: UHS-I 1.8V signaling, Frequency up to 50 MHz, sampled on both clock edges, up to 50MB/sec

(супер скоростные пропущены)

Некоторые дешевые нестабильно работают при 1.8V, но нормально в High Speed mode. USB-ридеры особо не дают возможности ни посмотреть информацию о флешке, ни посмотреть согласованный режим. Есть хаки для конкретных ридеров.

Информацию о флешке проще всего прочитать в аппаратном SD IP, Linux выдаёт в /sys/block/<yourBlockDevice>/device/{csd,cid}. Поищите в интернете, как её декодировать, либо подсмотрите код вот этого и этого проекта (выглядит вот так и так (youtube.com)).

Если заказываете партию флешек, убедитесь, что у них в CID хотя бы один и тот же код производителя. Китайцы могут нанести какие угодно надписи и изображения на флешку.

ValdikSS ★★★★★
()
Последнее исправление: ValdikSS (всего исправлений: 1)
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария