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