Bagaimana saya bisa menguji kapasitas penuh kartu SD di Linux?

17

Saya membeli kartu SD 64 GB dari eBay. Ini berfungsi dengan baik ketika saya membakar gambar ARM Arch Linux dan menggunakannya untuk mem-boot Raspberry Pi saya.

Namun, ketika saya mencoba membuat partisi ext4 tunggal di atasnya untuk menggunakan semua kapasitas kartu, kesalahan terjadi. mkfs.ext4selalu berakhir dengan bahagia; Namun, partisi tidak dapat mountdiedit, selalu menimbulkan kesalahan dan dmesgmenampilkan pesan-pesan kernel Cannot find journal. Ini telah terbukti menjadi kasus di setidaknya dua platform: Arch Linux ARM dan Ubuntu 13.04.

Di sisi lain, saya dapat membuat dan me-mount partisi FAT32 tanpa kesalahan (pemeriksaan kapasitas penuh belum dilakukan).

Saya mendengar bahwa beberapa orang jahat dapat mengubah antarmuka kartu SD untuk melaporkan kapasitas yang salah ke OS (yaitu kartu tersebut benar-benar hanya 2 GB tetapi ia melaporkan dirinya sendiri sebagai 64 GB) untuk menjual kartu dengan harga yang lebih baik.

Saya tahu bahwa alat seperti badblocksada bagi saya untuk memeriksa kartu SD untuk blok buruk. Bisakah badblocksmendeteksi masalah seperti ini? Jika tidak, solusi apa yang ada bagi saya untuk menguji kartu?

Saya idealnya ingin tahu apakah saya dicurangi atau tidak; jika hasilnya menunjukkan saya baru saja menerima barang yang buruk, saya dapat kembali ke penjual saja, lebih baik melaporkan ke eBay bahwa seseorang mencoba menipu saya.

MEMPERBARUI

operasi dan pesan:

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

MEMPERBARUI

Saya telah menjalankan badblocks /dev/sdetetapi tidak melaporkan kesalahan. Itu berarti sisa penyebabnya adalah:

  • Mobil SD bagus tetapi karena beberapa alasan mke2fsatau mountatau kernel memiliki bug yang menyebabkan masalah.

  • Saya ditipu dengan cara yang badblockstidak bisa mendeteksi kekalahan. Ini masuk akal karena saya pikir badblockshanya melakukan beberapa tes tulis-baca di tempat. Namun, penipu dapat membuat akses ke area keluar tautan kembali ke beberapa blok masuk. Dalam hal ini cek baca-baca di tempat tidak dapat mendeteksi masalah.

Jika tidak ada aplikasi yang dapat melakukan tes yang tepat, saya pikir saya dapat mencoba menulis program C sederhana untuk mengujinya.

Mesin Tanah
sumber
Sudahkah Anda mencobanya di pembaca kartu USB SDXC?
Ignacio Vazquez-Abrams
Juga, apakah ada pesan yang muncul di log sistem bersamaan dengan kesalahan?
Ignacio Vazquez-Abrams
Saya mencoba keduanya dengan pembaca kartu Raspberry Pi asli, dan pembaca kartu eksternal untuk desktop Ubuntu saya juga. Saya telah mengatakan bahwa dmesgmenampilkan pesan-pesan kernel dan saya yakin itu muncul bersamaan dengan kesalahan karena saya melakukan itu sebelum dan sesudah dan membandingkannya. Saya belum memeriksa syslogkarena saya yakin dmesgakan menampilkan pesan.
Earth Engine
Apakah itu menunjukkan pesan lain?
Ignacio Vazquez-Abrams
Pembaca kartu eksternal yang saya gunakan berfungsi untuk kartu saya yang lain, termasuk kartu SDXC. Namun yang bermasalah memiliki satu perbedaan: itu adalah kartu micro SD dengan adaptor SD.
Earth Engine

Jawaban:

26

Jika ada yang melihat ini nanti: Seseorang menulis alat sumber terbuka yang disebut "F3" untuk menguji kapasitas kartu SD dan media lainnya. Itu dapat ditemukan di hompage proyek dan di Github .

Radtoo
sumber
Sebenarnya itu adalah referensi dalam topik itu untuk menguji kartu SD ...
Philippe Gachoud
6

Kecurangan sekarang telah dikonfirmasi oleh langkah-langkah berikut:

  • Hasilkan file data acak. (4194304 = 4 × 1024 × 1024 = 4 MiB, ukuran total = 40 × 4 MiB = 160 MiB)

    Perintah:

    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
    
  • Salin data ke kartu SD. (2038340 × 4096 = 8153600 KiB = 7962,5 MiB)

    Perintah:

    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
    
  • Baca kembali data dari kartu SD.

    Perintah:

    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
    
  • Tunjukkan hasilnya

    Perintah:

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

Apa yang terjadi? Kami mengamati celah nol. Ini merupakan indikator bahwa data acak belum benar-benar ditulis ke kartu. Tetapi mengapa data kembali setelahnya 1a81000? Jelas kartu memiliki cache internal.

Kami juga dapat mencoba menyelidiki perilaku cache.

hexdump test.orig | grep ' 0000 0000 '

tidak memberikan hasil, yang berarti bahwa sampah yang dihasilkan tidak memiliki pola seperti itu. Namun,

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

punya 4 pertandingan.

Jadi inilah mengapa ia melewati badblockspemeriksaan. Tes lebih lanjut dapat menunjukkan bahwa kapasitas sebenarnya adalah 7962,5 MB, atau sedikit kurang dari 8 GB.

Saya menyimpulkan bahwa ini sangat tidak mungkin hanya kegagalan perangkat keras acak, tetapi lebih cenderung menjadi semacam kecurangan (yaitu, penipuan). Saya ingin tahu tindakan apa yang bisa saya ambil untuk membantu korban lainnya.

Pembaruan 11/05/2019

  • Orang-orang bertanya kepada saya tentang bagaimana cara mengetahui seekparameter yang benar 2038399. Saya melakukan lebih banyak pengalaman daripada yang saya tunjukkan di atas. Pada dasarnya Anda harus menebak sejak awal. Anda harus menebak ukuran data yang tepat, dan Anda harus menebak di mana korupsi data itu. Tetapi Anda selalu dapat menggunakan metode membagi dua untuk membantu.

  • Dalam komentar di bawah, saya pikir saya berasumsi bahwa langkah kedua di atas (menyalin data ke kartu SD) hanya menyalin 1 sektor. Tapi saya tidak melakukan kesalahan ini dalam pengalaman saya. Alih-alih, seekitu untuk menunjukkan bahwa pada langkah "tampilkan hasil" offset 1000hanya terjadi di sektor kedua data. Jika seeksektor 2038399, korupsi di sektor 2038400.

Mesin Tanah
sumber
(1) Dari mana angka 2038340 dan 2038399 berasal? (2) Mengapa Anda menggunakan  bs=4194304 count=40 saat membaca dari /dev/urandom tetapi   bs=4096 count=40960  ketika menulis ke dan membaca dari kartu SD? (Mereka secara matematis setara; masing-masing 167772160 bytes.)
Scott
1) Saya menggunakan bisec tecnique untuk mencari tahu offset Anda. Karena prosedur bisec terlalu bertele-tele untuk jawabannya, saya hanya menempatkan mereka sebagai bukti tanpa penggambaran lebih lanjut. 2) Ya perhitungannya setara; tapi saya tidak tahu apakah saya harus cocok dengan ukuran sektor kartu, yang saya percaya adalah 4096.
Earth Engine
Oh, untuk poin 2) Saya menggunakan seek, jadi saya hanya menulis 1 sektor ke kartu, yang menghemat jumlah transfer data. Sebabnya, ketika bereksperimen saya menggunakan blok data yang lebih besar, ini sebabnya file data yang dihasilkan adalah 160MiB.
Earth Engine
Komentar kedua Anda tidak masuk akal. Perintah kedua dalam jawaban Anda - salah satu yang menulis ke kartu - adalah sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096. Dan jelas Anda benar; itu menggunakan seek. Dan, ya, secara teknis, itu tidak digunakan count. … (Lanjutan)
Scott
(Lanjutkan) ... Tetapi Anda mengatakan, “Saya hanya menulis 1 sektor ke kartu, yang menghemat jumlah transfer data.” Itu jelas salah; tanpa countspesifikasi, ddtransfer seluruh input (mis., itu mentransfer hingga EOF atau kesalahan). Jadi perintah itu mentransfer seluruh konten test.orig, yaitu 40.960 catatan masing-masing 4096 byte, dengan total 167772160 byte (seperti yang saya katakan).
Scott
3

Pertama-tama, baca jawaban F3 oleh @Radtoo. Itu cara yang benar.

Entah bagaimana saya melewatkannya, dan mencoba caranya sendiri:

  1. buat file uji 1gb: dd if=/dev/urandom bs=1024k count=1024 of=testfile1gb

  2. tulis salinan file itu ke sdcard (64 adalah ukuran sdcard dalam gb): for i in $(seq 1 64); do dd if=testfile1gb bs=1024k of=/media/sdb1/test.$i; done

  3. periksa MD5 file (semua kecuali yang terakhir, tidak lengkap, harus cocok): md5sum testfile1gb /media/sdb1/test.*

Domen
sumber
Ini adalah pendekatan yang mudah dan cepat.
Earth Engine
Metode ini didokumentasikan dengan baik di sini ccollins.wordpress.com/2016/01/18/testing-sd-cards-with-linux
Philippe Gachoud
2

Cara paling sederhana untuk menguji kapasitas penuh kartu SD adalah mengisinya dengan file, lalu memverifikasi file-file itu benar: diff -qr /directory/on/computer /directory/on/SD

Atau, Anda dapat menggunakan program untuk menulis pola, atau rantai hash, ke file, dan kemudian memverifikasi bahwa mereka benar.

Seperti yang ditunjukkan oleh @Earthy Engine , penting untuk mengisi kartu SD, lalu membaca data, sebagai pendekatan tradisional yang hanya menulis sekumpulan kecil data, lalu membacanya, terkecoh dengan kartu SSD palsu.

Zaz
sumber
2

Saya menulis skrip kecil yang melakukan hal berikut.

-membuat direktori sementara ke USB target atau kartu SC

-membuat file referensi 5MB yang dibuat secara acak dengan md5sum checksum

-menyalin file referensi ke target dan menghasilkan cek md5sum dari target untuk mengkonfirmasi keberhasilan baca / tulis

-mengisi target ke kapasitas (100%) atau berhenti ketika kesalahan checksum terjadi

-Setelah skrip berhenti secara alami, ini akan menampilkan ukuran target yang dilaporkan, jumlah Digunakan dan Gratis.

Dengan skrip ini saya menyimpulkan bahwa saya ditipu oleh penjual ebay yang melewatkan microSD 8GB untuk 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
Robert Charest
sumber
1
Ini mungkin akan memberikan hasil yang menyesatkan. Karena OS filesystem buffer menulis, Anda kebanyakan menguji memori sistem Anda, bukan kartu SD.
Cerin
mengeksekusi "hdparm -W 0 / dev / disk" harus menyelesaikan masalah penulisan buffer.
Michael
1

Orang dapat menulis urutan angka (setiap baris adalah 16 byte) dan kemudian memverifikasi isinya:

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

Kemudian verifikasi lewati == output (menggunakan sampel kecil nilai lewati yang lebih kecil dari jumlah catatan tertulis) misalnya lewati = 9876 :

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

Atau, buat sampel 20 lokasi dengan satu liner:

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
  • Pastikan Anda menulis ke kartu SD
  • Menulis ke file of=tempFileOnSD, jika Anda ingin menghindari penghancuran data yang disimpan kartu Anda (hanya relevan jika itu bukan palsu)
  • Dalam hal kartu 8GB berlabel 64GB, kemungkinan lulus semua 20 tes adalah (8GB / 64GB) ** 20 <1e-18
karpada
sumber
1
Saya harus membaca jawaban Anda tiga kali sebelum saya mengerti apa yang Anda katakan: "verifikasi lewati == output" tidak jelas. Dan, kecuali saya kehilangan sesuatu, pendekatan Anda mengharuskan pengguna menjalankan 123456789012345 perintah dan  secara manual memeriksa output! Jelas itu tidak masuk akal. Mengapa tidak hanya melakukan seq -w 0 123456789012345 > /dev/yourSdHeredan seq -w 0 123456789012345 | cmp - /dev/yourSdHere?
Scott
Terima kasih atas komentarnya :) Saya telah mengedit jawaban saya, semoga sekarang lebih baik!
karpada
Juga, 123456789012345 adalah angka 15 digit untuk membuat setiap angka menggunakan 16 byte. seseorang dapat menggunakan jumlah blok 16byte pada SD
karpada