Як я можу перевірити повну ємність SD-карти в Linux?


17

Я придбав SD-карту на 64 Гб у eBay. Це добре працює, коли я записую на нього зображення ARM Arch Linux і використовую його для завантаження мого Raspberry Pi.

Однак, коли я намагаюся створити на ньому єдиний розділ ext4, щоб використовувати всю ємність карти, виникають помилки. mkfs.ext4завжди закінчується щасливо; однак розділ не можна mountредагувати, завжди видаючи помилку і dmesgпоказуючи, що повідомлення ядра включає Cannot find journal. Це виявилося як мінімум на двох платформах: Arch Linux ARM та Ubuntu 13.04.

З іншого боку, я можу створювати та монтувати розділ FAT32 без помилок (не було зроблено повну перевірку ємності).

Я чув, що деякі погані хлопці можуть змінити інтерфейс SD-карти, щоб повідомити про неправильну ємність ОС (тобто карта дійсно лише 2 Гб, але вона повідомляє себе як 64 ГБ), щоб продати карту за вигідною ціною.

Я знаю, що такі інструменти, як я, badblocksіснують для перевірки SD-картки на наявність поганих блоків. Чи можете badblocksвиявити подібні проблеми? Якщо ні, то які інші рішення для мене існують для тестування карти?

Я б в ідеалі хотів знати, чи мене обдурили чи ні; якщо результат показує, що я щойно отримав поганий товар, я можу повернутися лише до продавця, швидше повідомити на eBay, що хтось намагався мене обдурити.

ОНОВЛЕННЯ

операції та повідомлення:

~$ sudo mkfs.ext4 /dev/sde1
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
4096000 inodes, 16383996 blocks
819199 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
500 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done   

~$ dmesg | tail
...
[4199.749118]...
~$ sudo mount /dev/sde1 /mnt
mount: wrong fs type, bad option, bad superblock on /dev/sde1,
   missing codepage or helper program, or other error
   In some cases useful info is found in syslog - try
   dmesg | tail  or so

~$ dmesg | tail
...
[ 4199.749118]...
[ 4460.857603] JBD2: no valid journal superblock found
[ 4460.857618] EXT4-fs (sde1): error loading journal

ОНОВЛЕННЯ

Я запустився, badblocks /dev/sdeале він не повідомляє про помилку. Це означає, що залишаються причини:

  • SD автомобіль хороший , але з якоїсь - то причини mke2fsабо mountабо ядра є помилка , яка викликає проблему.

  • Мене обдурили таким чином, badblocksщо він не може виявити поразку. Це правдоподібно, тому що я думаю, що я badblocksпросто роблю тест на місці запису читання. Однак шахрай може зробити доступ до вихідних районів посиланнями назад до якогось вхідного блоку. У цьому випадку перевірка читання на місці запису не в змозі виявити проблему.

Якщо немає додатків, можна зробити належний тест, я думаю, я можу спробувати написати просту програму на C, щоб перевірити її.


Ви пробували це в USB-рідері SDXC?
Ігнасіо Васкес-Абрамс

Також чи з'являються повідомлення в системному журналі одночасно з помилками?
Ігнасіо Васкес-Абрамс

Я спробував як з рідним зчитувачем карт Raspberry Pi, так і із зовнішнім зчитувачем карт для мого робочого столу Ubuntu. Я вже говорив, що dmesgпоказує повідомлення ядра, і я впевнений, що вони з'являються одночасно з помилками, тому що я робив це до і після, і порівнював їх. Я не перевірив, syslogтому що я вважаю dmesg, що покажуть повідомлення.
Земляний двигун

Чи відображаються інші повідомлення?
Ігнасіо Васкес-Абрамс

Зовнішній зчитувач карт, який я використовував, працює для інших моїх карт, включаючи карти SDXC. Однак у цієї проблематики є одна відмінність: це мікро SD-карта з адаптером SD.
Земляний двигун

Відповіді:


26

Якщо хтось бачить це пізніше: хтось написав інструмент з відкритим кодом під назвою "F3" для перевірки ємності SD-карт та інших подібних носіїв інформації. Його можна знайти на головній сторінці проекту та в Github .


Власне, це посилання в цій темі на тестування SDCards ...
Філіп Гачуд

6

Підступ тепер підтверджено наступними кроками:

  • Створити файл випадкових даних. (4194304 = 4 × 1024 × 1024 = 4 МіБ, загальний розмір = 40 × 4 МіБ = 160 МіБ)

    Команда:

    dd if=/dev/urandom of=test.orig bs=4194304 count=40
    40+0 records in
    40+0 records out
    167772160 bytes (168 MB) copied, 11.0518 s, 15.2 MB/s
    
  • Скопіюйте дані на SD-карту. (2038340 × 4096 = 8153600 KiB = 7962,5 МіБ)

    Команда:

    sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096
    40960+0 records in
    40960+0 records out
    167772160 bytes (168 MB) copied, 41.6087 s, 4.0 MB/s
    
  • Прочитайте дані з SD-карти.

    Команда:

    sudo dd if=/dev/sde of=test.result skip=2038399 bs=4096 count=40960
    40960+0 records in
    40960+0 records out
    167772160 bytes (168 MB) copied, 14.5498 s, 11.5 MB/s
    
  • Покажіть результат

    Команда:

    hexdump test.result | less
    ...
    0000ff0 b006 fe69 0823 a635 084a f30a c2db 3f19
    0001000 0000 0000 0000 0000 0000 0000 0000 0000
    *
    1a81000 a8a5 9f9d 6722 7f45 fbde 514c fecd 5145
    
    ...
    

Що трапилось? Ми спостерігали розрив нулів. Це показник того, що випадкові дані насправді не були записані на карту. Але чому дані повертаються після 1a81000? Очевидно, що карта має внутрішній кеш.

Ми також можемо спробувати дослідити поведінку кешу.

hexdump test.orig | grep ' 0000 0000 '

не дає результату, а це означає, що утворене сміття не має такого зразка. Однак,

hexdump test.result | grep ' 0000 0000 '
0001000 0000 0000 0000 0000 0000 0000 0000 0000
213b000 0000 0000 0000 0000 0000 0000 0000 0000
407b000 0000 0000 0000 0000 0000 0000 0000 0000
601b000 0000 0000 0000 0000 0000 0000 0000 0000

провести 4 матчі.

Ось чому це проходить badblocksперевірку. Подальші тести можуть показати, що фактична ємність становить 7962,5 Мб, або трохи менше 8 ГБ.

Я роблю висновок, що це малоймовірно, що це лише випадковий апаратний збій, але, швидше за все, це свого роду обман (тобто шахрайство). Мені хотілося б знати, які дії я можу вжити, щоб допомогти іншим жертвам.

Оновлення 05.05.2019

  • Люди запитували мене про те, як я з'ясував правильний seekпараметр 2038399. Я зробив набагато більше досвіду, ніж я показав у вищесказаному. В основному ви повинні вгадати в першу чергу. Ви повинні відгадати належний розмір даних, і ви повинні здогадатися, де було пошкодження даних. Але ви завжди можете скористатися методом бісекції .

  • У коментарі нижче я подумав, що я вважав, що другий крок вище (скопіюйте дані на SD-карту) копіює лише 1 сектор. Але я не помилився в своєму досвіді. Натомість слід seekбуло показати, що у кроці "показ результату" зрушення 1000просто відбувається у другому секторі даних. Якщо seekце 2038399 секторів, корупція - у 2038400-му секторі.


(1) Звідки беруться цифри 2038340 та 2038399? (2) Чому ви використовуєте  bs=4194304 count=40 при читанні , /dev/urandom але   bs=4096 count=40960  при запису і читання з SD - карти? (Вони математично еквівалентні; 167772160 байт кожен.)
Скотт

1) Я використав bisec tecnique для того, щоб з'ясувати злочин. Оскільки процедура бісека занадто багатослівна для відповіді, я просто ставлю їх як очевидні без додаткових пояснень. 2) Так розрахунок рівносильний; але я не знаю, чи повинен я відповідати розміру сектора картки, який, на мою думку, становить 4096.
Earth Engine

О, для пункту 2) Я використовую seek, тому я написав на карту лише 1 сектор, що економить обсяг передачі даних. Зважаючи на це, під час експерименту я використовував більший блок даних, саме тому згенерований файл даних становить 160 Мбіт.
Земляний двигун

Ваш другий коментар не має сенсу. Друга команда у вашій відповіді - та, яка пише на карту, - це sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096. І явно ти маєш рацію; він використовує seek. І, так, технічно це не використовує count. … (Продовження)
Скотт

(Продовжував)… Але ви говорите: «Я записав на карту лише 1 сектор, що економить обсяг передачі даних». Це явно неправильно; без countспецифікації ddпередає весь вхід (тобто він передає до EOF або помилки). Отже, ця команда передає весь вміст test.orig, який становить 40960 записів по 4096 байт кожен, на загальну суму 167772160 байт (як я вже сказав).
Скотт

3

Перш за все, прочитайте відповідь F3 від @Radtoo. Це правильний шлях.

Я якось пропустив це і спробував по-своєму:

  1. створити тестовий файл 1 Гб: dd if=/dev/urandom bs=1024k count=1024 of=testfile1gb

  2. записати копії цього файлу на sdcard (64 - розмір sdcard в gb): for i in $(seq 1 64); do dd if=testfile1gb bs=1024k of=/media/sdb1/test.$i; done

  3. перевірити md5 файлів (усі, крім останнього, неповні, повинні відповідати): md5sum testfile1gb /media/sdb1/test.*


Це простий і швидкий підхід.
Земляний двигун

Цей метод добре задокументований тут ccollins.wordpress.com/2016/01/18/testing-sd-cards-with-linux
Philippe Gachoud

2

Найпростіший спосіб перевірити повну ємність SD-карти - це заповнити її файлами, а потім перевірити правильність файлів: diff -qr /directory/on/computer /directory/on/SD

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

Як зазначав @Earthy Engine , важливо заповнити SD-карту, а потім прочитати дані, оскільки традиційні підходи, які просто записують невеликий блок даних, а потім їх читають, обдурюють підроблені SSD-карти.


2

Я написав невеликий сценарій, який робить наступне.

-Створює тимчасовий каталог на цільовій USB або SC картці

-створює 5 Мб випадково генерований довідковий файл з контрольною сумою md5sum

-копіює довідковий файл у цільовий і генерує перевірку md5sum від цілі для підтвердження успіху читання / запису

-заповнює ціль до ємності (100%) або зупиняється, коли виникає помилка контрольної суми

-once скрипт природним чином зупиняється, він відображає цільовий розмір звіту, використані та безкоштовні суми.

За допомогою цього сценарію я зробив висновок, що мене зірвав продавець ebay, який передав 8GB microSD для 64GB

#!/bin/bash
#Save file as 'filltext' and remember to set the executable flag to run it
if [ -d "$1" ]; then
 if [ -d "$1/tmp" ]; then
  echo "."
 else
  mkdir $1/tmp
 fi

#Make a tmp file and fill it with 3MB of junk
 TMPTSTR=$(mktemp)      
 base64 </dev/urandom  | head -c 5000000 > $TMPTSTR

 TESTVAL=$(md5sum $TMPTSTR | awk '{ print $1 }')

 while $CHECKEDOK; do

  FL=$( tr -dc A-Za-z0-9 </dev/urandom  | head -c 5).TEST

  cp $TMPTSTR $1/tmp/$FL
  TESTTMP=$(md5sum $1/tmp/$FL | awk '{ print $1 }')
  if [ "$TESTVAL" != "$TESTTMP" ]; then   
   echo "Checksum ERROR"
   echo "Original: $TESTVAL Temp File:$TESTTMP"
   CHECKEDOK=false
   df $1 -Ph
   echo 
   echo 
   echo "Removing test files"
   rm $1/tmp -r
   rm $TMPTSTR
   df $1 -Ph
  else
   #echo -n "$FL..."
   clear
   df $1 -Ph
  fi
 done

else
 echo "Error: Directory $1 does not exists."
 echo "Usage: filltest [PATH]"
 echo
 echo "Try the PATH of a mounted USB dongle or SD card to confirm it's capacity"

fi

1
Це, можливо, дасть оманливі результати. Оскільки файлова система буферів ОС пише, ви в основному випробовуєте пам'ять вашої системи, а не SD-карту.
Серін

виконання "hdparm -W 0 / dev / disk" повинно вирішити проблему запису в буферному режимі.
Михайло

1

Можна написати послідовність чисел (кожен рядок - 16 байт), а потім перевірити вміст:

dd if=<(seq -w 0 123456789012345) of=/dev/yourSdHere

Потім перевірте вихід skip == (використовуючи невелику вибірку пропущених значень, меншу кількість записаних записів), наприклад skip = 9876 :

dd if=/dev/yourSdHere bs=16 count=1 skip=9876
000000000009876
1+0 records in
1+0 records out
16 bytes copied, ...

Або зробіть зразок з 20 місць за допомогою одного вкладиша:

seq -w 000000000000000 NumberOfWrittenRecords | shuf | head -20 | while read i; do [[ $(dd if=/dev/yourSdHere bs=16 count=1 skip=$i) == $i ]] && echo ok || echo bad; done
  • Переконайтеся, що ви пишете на SD-карту
  • Напишіть у файл of=tempFileOnSD, якщо ви хочете уникнути знищення даних, що зберігаються на вашій карті (актуально лише, якщо це не підробка)
  • У випадку з 8 Гб карткою, позначеною як 64 ГБ, шанс пройти всі 20 тестів становить (8 ГБ / 64 ГБ) ** 20 <1е-18

1
Мені довелося прочитати вашу відповідь три рази, перш ніж я зрозумів, що ви говорите: "перевірити пропуск == вихід" не зрозуміло. І якщо я щось не пропускаю, ваш підхід вимагає, щоб користувач виконував команди 123456789012345 і  вручну перевіряв вихід! Очевидно, що це нерозумно. Чому б просто не зробити seq -w 0 123456789012345 > /dev/yourSdHereі seq -w 0 123456789012345 | cmp - /dev/yourSdHere?
Скотт

Дякую за коментар :) Я відредагував свою відповідь, сподіваюся, що зараз краще!
karpada

Крім того, 123456789012345 - це 15-значний номер, щоб кожне число використовувало 16 байт. можна використовувати кількість блоків на 16 байт на SD
карпада
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.