Jak mogę przetestować pełną pojemność karty SD w systemie Linux?

17

Kupiłem kartę SD 64 GB w serwisie eBay. Działa dobrze, gdy wypalę na nim obraz Arch Linux ARM i użyję go do uruchomienia mojego Raspberry Pi.

Jednak gdy próbuję utworzyć na nim pojedynczą partycję ext4, aby wykorzystać całą pojemność karty, występują błędy. mkfs.ext4zawsze kończy się szczęśliwie; jednak partycja nie może być mountedytowana, zawsze zgłasza błąd i dmesgpokazuje komunikaty jądra Cannot find journal. Okazało się, że tak jest na co najmniej dwóch platformach: Arch Linux ARM i Ubuntu 13.04.

Z drugiej strony mogę utworzyć i zamontować partycję FAT32 bez błędów (nie przeprowadzono pełnej kontroli pojemności).

Słyszałem, że niektórzy złoczyńcy mogą zmienić interfejs karty SD, aby zgłosić nieprawidłową pojemność do systemu operacyjnego (tj. Karta ma naprawdę tylko 2 GB, ale zgłasza się jako 64 GB), aby sprzedać kartę w lepszej cenie.

Wiem, że badblocksistnieją takie narzędzia , aby sprawdzić kartę SD pod kątem uszkodzonych bloków. Czy można badblockswykryć takie problemy? Jeśli nie, jakie inne rozwiązania istnieją dla mnie, aby przetestować kartę?

Idealnie chciałbym wiedzieć, czy zostałem oszukany, czy nie; jeśli wynik pokazuje, że właśnie otrzymałem zły przedmiot, mogę wrócić tylko do sprzedawcy, raczej zgłosić na eBayu, że ktoś próbował mnie oszukać.

AKTUALIZACJA

operacje i komunikaty:

~$ 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

AKTUALIZACJA

Uruchomiłem, badblocks /dev/sdeale nie zgłasza żadnego błędu. Oznacza to, że pozostałe przyczyny to:

  • Samochód SD jest dobry, ale z jakiegoś powodu mke2fslub mountjądro ma błąd, który powoduje problem.

  • Zostałem oszukany w sposób, badblocksktóry nie może wykryć porażki. Jest to prawdopodobne, ponieważ myślę, że badblockspo prostu wykonuję jakiś test zapisu i odczytu w miejscu. Jednak oszust może sprawić, że dostęp do obszarów wychodzących będzie łączył się z pewnym blokiem wejściowym. W takim przypadku kontrola zapisu i odczytu w miejscu nie jest w stanie wykryć problemu.

Jeśli żadna aplikacja nie może wykonać właściwego testu, myślę, że mogę spróbować napisać prosty program w C, aby go przetestować.

Silnik Ziemi
źródło
Czy próbowałeś tego w czytniku kart SDXC USB?
Ignacio Vazquez-Abrams
Czy jakieś komunikaty pojawiają się w dzienniku systemowym w tym samym czasie co błędy?
Ignacio Vazquez-Abrams
Próbowałem zarówno z natywnym czytnikiem kart Raspberry Pi, jak i zewnętrznym czytnikiem kart do mojego pulpitu Ubuntu. Powiedziałem, że dmesgpokazuje komunikaty jądra i jestem pewien, że pojawia się w tym samym czasie co błędy, ponieważ zrobiłem to przed i po i porównałem je. Nie sprawdziłem, syslogbo wierzę, dmesgże pokażę wiadomości.
Earth Engine
Czy wyświetla jakieś inne wiadomości?
Ignacio Vazquez-Abrams
Zewnętrzny czytnik kart, z którego korzystałem, działa dla moich innych kart, w tym kart SDXC. Jednak ta problematyczna ma jedną różnicę: jest to karta micro SD z adapterem SD.
Earth Engine

Odpowiedzi:

26

Jeśli ktoś zobaczy to później: ktoś napisał narzędzie typu open source o nazwie „F3”, aby przetestować pojemność kart SD i innych tego typu mediów. Można go znaleźć na stronie projektu i w Github .

Radtoo
źródło
Właściwie to jest odniesienie w tym temacie do testowania kart SD ...
Philippe Gachoud
6

Oszukiwanie zostało teraz potwierdzone przez następujące kroki:

  • Wygeneruj losowy plik danych. (4194304 = 4 × 1024 × 1024 = 4 MiB, całkowity rozmiar = 40 × 4 MiB = 160 MiB)

    Komenda:

    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
    
  • Skopiuj dane na kartę SD. (2038340 × 4096 = 8153600 KiB = 7962,5 MiB)

    Komenda:

    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
    
  • Odczytaj dane z karty SD.

    Komenda:

    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
    
  • Pokaż wynik

    Komenda:

    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
    
    ...
    

Co się stało? Zaobserwowaliśmy odstęp zer. Jest to wskaźnik, że dane losowe nie zostały faktycznie zapisane na karcie. Ale dlaczego dane po tym wracają1a81000 ? Oczywiście karta ma wewnętrzny bufor.

Możemy również spróbować zbadać zachowanie pamięci podręcznej.

hexdump test.orig | grep ' 0000 0000 '

nie daje żadnego wyniku, co oznacza, że ​​generowane śmieci nie mają takiego wzoru. Jednak,

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

mieć 4 mecze.

Dlatego to mija badblocks kontrolę. Dalsze testy mogą wykazać, że faktyczna pojemność wynosi 7962,5 MB, czyli nieco mniej niż 8 GB.

Wnioskuję, że jest to bardzo mało prawdopodobne, aby była to przypadkowa awaria sprzętu, ale bardziej prawdopodobne, że będzie to rodzaj oszustwa (tj. Oszustwa). Chciałbym wiedzieć, jakie działania mogę podjąć, aby pomóc innym ofiarom.

Aktualizacja 11.05.2019

  • Ludzie pytali mnie o to, jak odkryłem poprawny seekparametr 2038399. Zrobiłem o wiele więcej doświadczenia niż pokazałem powyżej. Zasadniczo musisz przede wszystkim zgadywać. Musisz odgadnąć odpowiedni rozmiar danych i zgadnąć, gdzie było uszkodzenie danych. Ale zawsze możesz użyć metody bisekcji, aby pomóc.

  • W komentarzu poniżej pomyślałem, że założono, iż drugi krok powyżej (skopiowanie danych na kartę SD) kopiuje tylko 1 sektor. Ale nie popełniłem tego błędu w moim eksperymencie. Zamiast tego seekmiało to pokazać, że w kroku „pokaż wynik” przesunięcie 1000następuje po prostu w drugim sektorze danych. Jeśli seekjest to 2038399 sektorów, korupcja dotyczy 2038400. sektora.

Silnik Ziemi
źródło
(1) Skąd pochodzą liczby 2038340 i 2038399? (2) Dlaczego używasz  bs=4194304 count=40 podczas czytania z, /dev/urandom ale   bs=4096 count=40960  podczas pisania na i odczytu z karty SD? (Są matematycznie równoważne; 167772160 bajtów każdy.)
Scott
1) Użyłem techniki bisec, aby obliczyć przesunięcie. Ponieważ procedura bisek jest zbyt wyczerpująca, aby odpowiedzieć, po prostu przedstawiam je jako oczywiste bez dalszego wyjaśniania. 2) Tak, obliczenia są równoważne; ale nie wiem, czy powinienem dopasować rozmiar sektora karty, który moim zdaniem wynosi 4096.
Earth Engine
Och, dla punktu 2) Używam seek, więc zapisałem tylko 1 sektor na karcie, co oszczędza ilość transferu danych. Oczywiście podczas eksperymentowania użyłem większego bloku danych, dlatego wygenerowany plik danych ma rozmiar 160 MB.
Earth Engine
Twój drugi komentarz nie ma sensu. Drugim poleceniem w twojej odpowiedzi - tym, które zapisuje na karcie - jest sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096. I oczywiście masz rację; używa seek. I tak, technicznie rzecz biorąc, nie używa count. … (Ciąg dalszy)
Scott
(Ciąg dalszy)… Ale mówisz: „Zapisałem tylko 1 sektor na karcie, co oszczędza ilość transferu danych”. To oczywiście źle; bez countspecyfikacji ddprzenosi całe dane wejściowe (tzn. przenosi do EOF lub błędu). To polecenie przekazuje całą zawartość test.orig, czyli 40960 rekordów po 4096 bajtów każdy, w sumie 167772160 bajtów (jak powiedziałem).
Scott
3

Przede wszystkim przeczytaj F3 odpowiedź autorstwa @Radtoo. To jest właściwy sposób.

Jakoś mi tego brakowało i próbowałem na swój sposób:

  1. utwórz plik testowy 1GB: dd if=/dev/urandom bs=1024k count=1024 of=testfile1gb

  2. zapisz kopie tego pliku na sdcard (64 to sdcard rozmiar w gb): for i in $(seq 1 64); do dd if=testfile1gb bs=1024k of=/media/sdb1/test.$i; done

  3. sprawdź md5 plików (wszystkie oprócz ostatniego, niekompletne, powinny pasować): md5sum testfile1gb /media/sdb1/test.*

domen
źródło
To łatwe i szybkie podejście.
Earth Engine
Ta metoda jest dobrze udokumentowana tutaj ccollins.wordpress.com/2016/01/18/testing-sd-cards-with-linux
Philippe Gachoud
2

Najprostszym sposobem przetestowania pełnej pojemności karty SD jest wypełnienie jej plikami, a następnie sprawdzenie, czy pliki są poprawne: diff -qr /directory/on/computer /directory/on/SD

Alternatywnie możesz użyć programów do zapisania wzorców lub łańcuchów skrótów do pliku, a następnie sprawdzić, czy są poprawne.

Jak zauważył @Earthy Engine , ważne jest, aby wypełnić kartę SD, a następnie odczytać dane, ponieważ tradycyjne podejścia, które po prostu zapisują mały blok danych, a następnie czytają, są oszukiwane przez fałszywe karty SSD.

Zaz
źródło
2

Napisałem mały skrypt, który wykonuje następujące czynności.

- tworzy katalog tymczasowy na docelowej karcie USB lub SC

- tworzy losowo generowany plik referencyjny o wielkości 5 MB z sumą kontrolną md5sum

- kopiuje plik referencyjny do celu i generuje sprawdzanie sumy md5 z celu, aby potwierdzić powodzenie odczytu / zapisu

- wypełnia cel do pojemności (100%) lub zatrzymuje się, gdy wystąpi błąd sumy kontrolnej

-ponownie skrypt zatrzymuje się naturalnie, wyświetla docelowy zgłaszany rozmiar, Użyte i Wolne kwoty.

Za pomocą tego skryptu doszedłem do wniosku, że zostałem oszukany przez sprzedawcę w serwisie eBay, który przekazał kartę microSD o pojemności 8 GB na 64 GB

#!/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
Robert Charest
źródło
1
To może dać mylące wyniki. Ponieważ system plików buforuje system operacyjny, najczęściej testujesz pamięć systemu, a nie kartę SD.
Cerin
wykonanie polecenia „hdparm -W 0 / dev / disk” powinno rozwiązać problem buforowanego zapisu.
Michael
1

Można napisać sekwencję liczb (każdy wiersz ma 16 bajtów), a następnie zweryfikować zawartość:

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

Następnie sprawdź wyniki skip == (używając małej próbki wartości pominięcia, które są mniejszą liczbą zapisanych rekordów) np. Skip = 9876 :

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

Lub zrób próbkę 20 lokalizacji za pomocą jednego linera:

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
  • Upewnij się, że piszesz na kartę SD
  • Napisz do pliku of=tempFileOnSD, jeśli chcesz uniknąć zniszczenia danych przechowywanych na karcie (dotyczy tylko sytuacji, gdy nie jest to fałszywa karta)
  • W przypadku karty 8 GB oznaczonej jako 64 GB szansa na zaliczenie wszystkich 20 testów wynosi (8 GB / 64 GB) ** 20 <1e-18
karpada
źródło
1
Musiałem przeczytać twoją odpowiedź trzy razy, zanim zrozumiałem, co mówisz: „sprawdź pominięcie == wynik” nie jest jasne. I chyba, że ​​czegoś mi brakuje, twoje podejście wymaga, aby użytkownik uruchomił komendy 123456789012345 i  ręcznie sprawdził dane wyjściowe! Oczywiście to nieracjonalne. Dlaczego nie po prostu zrobić seq -w 0 123456789012345 > /dev/yourSdHerei seq -w 0 123456789012345 | cmp - /dev/yourSdHere?
Scott
Dzięki za komentarz :) Zredagowałem swoją odpowiedź, mam nadzieję, że teraz jest lepiej!
karpada
Ponadto 123456789012345 jest 15 cyfrową liczbą, dzięki czemu każdy numer ma 16 bajtów. można użyć liczby 16-bajtowych bloków na karcie SD
karpada