Linux'ta bir SD kartın tam kapasitesini nasıl test edebilirim?


17

EBay'den 64 GB SD kart satın aldım. Bir Arch Linux ARM görüntüsünü yaktığımda ve Raspberry Pi'mi başlatmak için kullandığımda iyi çalışıyor.

Ancak, kartın tüm kapasitesini kullanmak için tek bir ext4 bölümü oluşturmaya çalıştığımda hatalar oluşuyor. mkfs.ext4her zaman mutlu biter; ancak, bölüm mountdüzenlenemez, her zaman bir hata atar ve dmesgçekirdek mesajları içerir gösterir Cannot find journal. Bunun en az iki platformda olduğu kanıtlanmıştır: Arch Linux ARM ve Ubuntu 13.04.

Diğer yandan hatasız bir FAT32 bölümü oluşturabilir ve monte edebilirim (tam kapasite kontrolü yapılmadı).

Bazı kötü adamların SD kart arayüzünü işletim sistemine yanlış bir kapasite bildirmek için değiştirebileceğini duydum (yani kart gerçekten sadece 2 GB, ancak 64 GB olarak rapor ediyor), kartı daha iyi bir fiyata satmak için.

badblocksSD kartta kötü bloklar olup olmadığını kontrol etmek için benim gibi araçların olduğunu biliyorum . badblocksBöyle sorunları tespit edebilir mi? Değilse, kartı test etmem için başka hangi çözümler var?

İdeal olarak aldatılıp alınıp alınmadığımı bilmek istiyorum; sonuç kötü bir ürün aldığımı gösterirse, sadece satıcıya geri dönebilirim, daha ziyade birinin beni kandırmaya çalıştığını eBay'e rapor edebilirim.

GÜNCELLEME

işlemler ve mesajlar:

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

GÜNCELLEME

Ben çalıştım badblocks /dev/sdeama hiçbir hata rapor. Bu, kalan nedenlerin:

  • SD araç iyidir ancak herhangi bir nedenle mke2fsveya mountçekirdeğin soruna neden olan bir hata vardır.

  • badblocksYenilgiyi tespit edemeyecek şekilde aldatılmıştım . Bu akla yatkındır çünkü bence badblocksbazı yerinde yazma-okuma testi yapıyor. Ancak, hile yapan, giden alanlara erişimin bazı gelen bloklara geri bağlanmasını sağlayabilir. Bu durumda, yerinde yazma-okuma denetimi sorunu algılayamaz.

Uygulamanın uygun testi yapamaması durumunda, sınamak için basit bir C programı yazmaya çalışabileceğimi düşünüyorum.


SDXC USB kart okuyucusunda denediniz mi?
Ignacio Vazquez-Abrams

Ayrıca, sistem günlüğünde hatalarla aynı anda herhangi bir ileti görünüyor mu?
Ignacio Vazquez-Abrams

Hem yerel Raspberry Pi kart okuyucu hem de Ubuntu masaüstüm için harici bir kart okuyucu ile denedim. Ben söylediler dmesggösterileri mesajları çekirdek ve ben önce ve sonra onları karşılaştırıldığında bunu yaptı çünkü emin hatalar aynı anda gösterilebilir olduğunu duyuyorum. Kontrol syslogetmedim çünkü dmesgmesajları göstereceğine inanıyorum .
Dünya Motoru

Başka mesaj gösteriyor mu?
Ignacio Vazquez-Abrams

Kullandığım harici kart okuyucu, diğer kartlarım için çalışıyor, SDXC kartları içeriyor. Ancak bu sorunlu olanın bir farkı vardır: SD adaptörlü bir mikro SD karttır.
Dünya Motoru

Yanıtlar:



6

Hile şimdi aşağıdaki adımlarla onaylanmıştır:

  • Rasgele bir veri dosyası oluşturun. (4194304 = 4 × 1024 × 1024 = 4 MiB, toplam boyut = 40 × 4 MiB = 160 MiB)

    Komut:

    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
    
  • Verileri SD karta kopyalayın. (2038340 × 4096 = 8153600 KiB = 7962,5 MiB)

    Komut:

    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 karttan veriyi tekrar okuyun.

    Komut:

    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
    
  • Sonucu göster

    Komut:

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

Ne oldu? Bir sıfır boşluk gözlemledik. Bu, rastgele verilerin gerçekten karta yazılmadığının bir göstergesidir. Ama veriler neden sonra geri geliyor 1a81000? Kartın dahili bir önbelleği var.

Ayrıca önbelleğin davranışını araştırmayı deneyebiliriz.

hexdump test.orig | grep ' 0000 0000 '

sonuç vermez, yani üretilen çöpün böyle bir paterni yoktur. Ancak,

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 maç var.

Bu yüzden badblockskontrolü geçiyor . Diğer testler, gerçek kapasitenin 7962.5 MB olduğunu veya 8 GB'den biraz daha az olduğunu gösterebilir.

Bunun sadece rastgele bir donanım arızası olması muhtemel olmadığı, ancak bir çeşit hile (yani sahtekarlık) olması muhtemel olduğu sonucuna varıyorum. Diğer kurbanlara yardım etmek için neler yapabileceğimi bilmek istiyorum.

Güncelleme 11/05/2019

  • İnsanlar bana doğru seekparametrenin nasıl olduğunu anladım 2038399. Yukarıda gösterdiğimden çok daha fazla deneyim yaptım. Temelde ilk etapta tahmin etmelisiniz. Doğru boyutta bir veri tahmin etmelisiniz ve veri bozulmasının nerede olduğunu tahmin etmelisiniz. Ama her zaman yardımcı olmak için ikiye ayırma yöntemini kullanabilirsiniz .

  • Aşağıdaki yorumda, yukarıdaki ikinci adımın (verileri SD karta kopyala) yalnızca 1 sektörü kopyaladığını varsaydığımı düşündüm. Ama deneyimlerimde bu hatayı yapmadım. Bunun yerine, seek"sonucu göster" adımında ofsetin 1000verilerin ikinci sektöründe gerçekleştiğini göstermekti. Eğer seek2038399 sektör ise, yolsuzluk 2038400. sektördedir.


(1) 2038340 ve 2038399 sayıları nereden geliyor? (2) Neden kullanıyorsunuz  bs=4194304 count=40 okurken /dev/urandom ama   bs=4096 count=40960  yazılı ve SD karttan okurken? (Matematiksel olarak eşdeğerdir; her biri 167772160 bayt.)
Scott

1) Bu ofseti anlamak için bisec tekniğini kullandım. Bisec prosedürü cevap için çok ayrıntılı olduğundan, onları daha fazla exaplaination olmadan açık bir şekilde koydum. 2) Evet, hesaplama eşittir; ancak 4096 olduğuna inandığım kartın sektör büyüklüğüne uyup uymayacağımı bilmiyorum.
Earth Engine

Oh, nokta 2 için) kullanıyorum seek, bu yüzden karta sadece 1 sektör yazdım, bu da veri aktarım miktarını koruyor. Nedeni, denerken daha büyük veri bloğu kullandım, bu yüzden oluşturulan veri dosyası 160MiB'dir.
Dünya Motoru

İkinci yorumunuz bir anlam ifade etmiyor. Cevabınızdaki ikinci komut - karta yazan komut - sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096. Ve tabii ki haklısın; kullanır seek. Ve, evet, teknik olarak, kullanmıyor count. … (Devamı)
Scott

(Devam)… Ama diyorsunuz ki “Karta sadece 1 sektör yazdım, bu da veri aktarımından tasarruf sağlıyor.” Bu açıkça yanlış; countspesifikasyon olmadan dd, tüm girişi aktarır (yani EOF veya bir hataya kadar aktarır). Böylece bu komut test.orig, her biri 4096 bayt olan 40960 kayıt olan tüm içeriği toplam 167772160 bayta aktarır (dediğim gibi).
Scott

3

Her şeyden önce, @Radtoo'nun F3 cevabını okuyun . Doğru yol budur.

Bir şekilde kaçırdım ve kendi yolumu denedim:

  1. 1 gb test dosyası oluştur: dd if=/dev/urandom bs=1024k count=1024 of=testfile1gb

  2. bu dosyanın kopyalarını sdcard'a yazın (64, gb cinsinden sdcard boyutudur): for i in $(seq 1 64); do dd if=testfile1gb bs=1024k of=/media/sdb1/test.$i; done

  3. Dosyaların md5'lerini kontrol edin (sonuncusu hariç, tümü eksik, eşleşmelidir): md5sum testfile1gb /media/sdb1/test.*


Bu kolay ve hızlı bir yaklaşımdır.
Dünya Motoru


2

Bir SD kartın tam kapasitesini test etmenin en basit yolu, kartı dosyalarla doldurmak ve dosyaların doğru olduğunu doğrulamaktır: diff -qr /directory/on/computer /directory/on/SD

Alternatif olarak, programları bir dosyaya desen veya karma zincir yazmak ve bunların doğru olduğunu doğrulamak için kullanabilirsiniz.

As @Earthy Motor işaret, onu okumak, sonra basitçe küçük bir veri bloğunu yazmak geleneksel yaklaşımlardan olarak, o zaman, SD kart doldurmak veri okumak için önemlidir, sahte SSD kartları ile kandırılır.


2

Aşağıdakileri yapan küçük bir senaryo yazdım.

- hedef USB veya SC karta geçici bir dizin oluşturur

- md5sum sağlama toplamı ile 5MB rasgele oluşturulmuş bir referans dosyası oluşturur

- referans dosyasını hedefe kopyalar ve okuma / yazma başarısını onaylamak için hedeften bir md5sum kontrolü oluşturur

- hedefi kapasiteye doldurur (% 100) veya bir sağlama toplamı hatası oluştuğunda durur

- komut dosyası doğal olarak durduğunda, raporlanan hedef boyutu, Kullanılmış ve Serbest miktarları görüntüler.

Bu senaryo ile 64GB için 8GB microSD'yi geçen bir ebay satıcısı tarafından dolandırıldığım sonucuna vardım.

#!/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
Bu muhtemelen yanıltıcı sonuçlar verecektir. İşletim sistemi dosya sistemi yazdığı için, çoğunlukla SD kart yerine sistem belleğinizi test ediyorsunuz.
Cerin

"hdparm -W 0 / dev / disk" komutunun çalıştırılması, arabelleğe alınmış bir yazma sorununu çözmelidir.
Michael

1

Bir sayı dizisi yazılabilir (her satır 16 bayttır) ve ardından içeriği doğrular:

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

Sonra skip == output'u (daha az sayıda kayıt yazılmış küçük bir atlama değeri örneği kullanarak) doğrulayın, örn. Skip = 9876 :

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

Veya bir astarla 20 konumdan bir örnek alın:

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 karta yazdığınızdan emin olun
  • of=tempFileOnSDKartınızda saklanan verilerin yok edilmesini önlemek istiyorsanız bir dosyaya yazın (yalnızca sahte değilse ilgili)
  • 64 GB olarak etiketlenmiş 8GB kart durumunda, 20 testin tümünü geçme şansı (8GB / 64GB) ** 20 <1e-18

1
Ne dediğini anlamadan önce cevabını üç kez okumak zorunda kaldım: “verikip skip == output” açık değil. Bir şey eksik olmadıkça, yaklaşımınız kullanıcının 123456789012345 komutlarını çalıştırmasını ve çıktıyı manuel olarak incelemesini gerektirir  ! Açıkçası bu mantıksız. Neden sadece seq -w 0 123456789012345 > /dev/yourSdHereve değil seq -w 0 123456789012345 | cmp - /dev/yourSdHere?
Scott

Yorum için teşekkürler :) Cevabımı düzenledim, şimdi daha iyi olduğunu umuyorum!
karpada

Ayrıca, 123456789012345, her sayının 16 bayt kullanmasını sağlayan 15 haneli bir sayıdır. SD'deki 16bayt blok sayısını kullanabilirsiniz
Karpada
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.