BI-MPP Cvičení 5,6 - USB Mass Storage, Miroslav Skrbek (C)2010,2011 1 z 5 5. Čtení/zápis sektorů z/do USB paměťového média I Náplň cvičení V tomto cvičení se naučíte číst/zapisovat data z/na datovou USB Flash. Seznáníte se SCSI příkazy a jejich použitím při diskových operacích. Úkol Napište program, který přečte sektor z USB flash paměti. Obsah 5. Čtení/zápis sektorů z/do USB paměťového média I Náplň cvičení Úkol Literatura Návod Konfigurace USB zařízení GET MAX LUN USB obálka pro SCSI příkazy Obálka pro SCSI status Přenosy SCSI příkazů a dat Doporučené pořadí užití SCSI příkazů SCSI příkazy K USB médiu přistupujte prostřednictvím knihovny libusb ( www.libusb.org). Literatura 1. 2. 3. 4. Universal Serial Bus Mass Storage Specification Overview. Revision 1.2, June 2003. (http://www.usb.org/developers/devclass_docs/usb_msc_overview_1.2.pdf) Universal Serial Bus Mass Storage Class Bulk-Only Transport Revision 1.0 September 31, 1999 (http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf) Information technology - SCSI Primary Commands - 3 (SPC-3) (http://www.t10.org/cgi-bin /ac.pl?t=f&f=spc3r23.pdf) Information technology Reduced Block Commands. WORKING NCITS-330 DRAFT T10/1240-D Revision 10a August 18, 1999 (http://www.t10.org/cgi-bin/ac.pl?t=f&f=rbcr10a.pdf)
BI-MPP Cvičení 5,6 - USB Mass Storage, Miroslav Skrbek (C)2010,2011 2 z 5 Návod S USB flash pamětí komunikujte přes libusb. Vyčtěte plug&play informace a zjistěte na jakých endpointech komunikuje. Zjistěte, kolik logických zařízení obsahuje (GetMaxLun request, usbmassbulk_10.pdf [2]). Vytvořte datové typy pro Command Block Wrapper (CBW) a Command Status Wrapper ( [2]). Vytvořete funkce pro vyplnění wrapperů pro příkaz INQUIRY, REQUEST SENSE, READ CAPACITY, READ a WRITE [2], popis command bloků najdete v spc3r23.pdf [3] a rbc-r10a.pdf [4]). Pomocí funkcí Libusb pošlete CBW(INQUIRY) do USB flash paměti a přečtěte dodaná data a CSW blok. Zkontrolujte status v CSW bloku a dekodujte datovou část. Významné části vytiskněte. Pomocí funkcí Libusb pošlete CBW(REQUEST SENSE) do USB flash paměti a přečtěte dodaná data a CSW blok. Zkontrolujte status v CSW bloku a dekodujte datovou část. Pomocí funkcí Libusb pošlete CBW(READ CAPACITY) do USB flash paměti a přečtěte dodaná data a CSW blok. Zkontrolujte status v CSW bloku, zjistěte maximalní hodnotu LBA a velikost bloku. Spočtěte kapacitu disku. Přečtěte masterboot - sektor 0 (povinné) a vytiskněte položky partition table (dobrovolné). Dobří programátoři se mohou pokusit o vypsání položek hlavního adresáře disku, pokud bude naformátován na filesystem FAT. Konfigurace USB zařízení Nezapomeňte konfigurovat USB zařízení voláním funkcí libusb_set_configuration a libusb_set_interface, podobně, jak jsme to dělali v předchozím cvičení. GET MAX LUN Pro získání GET MAX LUN užijte řídící přenos na koncový bod 0. Užijte funkci libusb_control_transfer, parametry: request_type = 0xA1, request = 0xFE, value = 0, index = 0, length = 1. Vyčtená délka dat 1, očekávaná hodnota 0. USB obálka pro SCSI příkazy typedef struct attribute ((packed)) { unsigned long dcbwsignature; unsigned long dcbwtag; unsigned long dcbwdatatransferlength; unsigned char bmcbwflags; unsigned char bcbwlun; // pouze bity 0-3 unsigned char bcbwcblength; // pouze bity 0-5 unsigned char CBWCB[16]; } CBW_t; 55h 53h 42h 43h
BI-MPP Cvičení 5,6 - USB Mass Storage, Miroslav Skrbek (C)2010,2011 3 z 5 dcbwtag (LSB) dcbwtag dcbwtag dcbwtag (MSB) dcbwdatatransferlength (LSB) dcbwdatatransferlength dcbwdatatransferlength dcbwdatatransferlength (LSB) bmcbwflags (příznaky: 0 - data OUT, 0x80 - data IN) bcbwlun (číslo logické jednotky) bcbwcblength (velikost řídícího bloku CB) CBWCB (řídící blok 16 bytů) Obálka pro SCSI příkazy má jednotnou délku 31 bytů. SCSI příkaz se zapisuje do pole CBWCB. Skutečná délka SCSI příkazu se zapisuje do pole bcbwcblength, která určuje obsazení pole CBWCB. Pro kratší příkazy než 16 bytů se celková délka obálky nezkracuje a přenáší se vždy všech 30 bytů. Nevyužitou část CBWCB je možno například vyplnit nulami, zařínení musí nevyužité hodnoty ignorovat. Pole dcbwdatatransferlength určuje velikost dat přenášených v rámci provedení příkazu. Požadujeme-li příklazem přečtení jednoho bloku (sektoru), bude délka přenášených dat rovna délce bloku (sektoru). Typicky to bude 512 bytů (je třeba se ale řídít velikostí bloku vrácenou příkazem READ_CAPACITY). Obálka pro SCSI status typedef struct attribute ((packed)) { unsigned long dcswsignature; unsigned long dcswtag; unsigned long dcswdataresidue; unsigned char bcswstatus; } CSW_t; dcswsignature = 0x53425355; Pokud bcswstatus == 0, pak příkaz byl úspěšně dokončen. dcswtag má stejnou hodnotu jako Tag v příkazu (tedy v CBW). Přenosy SCSI příkazů a dat Vyplňte CBW příkazem a doplňte i ostatní položky ve struktuře. Funkcí libusb_bulk_transfer přeneste CBW do USB zařízení. Argumentem funkce musí být adresa koncového bodu typu OUT (např. 0x01 nebo 0x02 podle vaší USB flash paměti). Pokud příkaz vyžaduje přenos dat do PC, volejte funkci libusb_bulk_transfer, kde argumentem bude adresa koncového bodu typu IN (např. 0x81 nebo 0x82 podle vaší USB flash paměti). Délka přenosu musí odpovídat hodnotě uvedené v dcbwdatatransferlength. Funkcí libusb_bulk_transfer přeneste CSW (Status) z USB zařízení. Argumentem funkce musí být adresa koncového bodu typu IN (např. 0x81 nebo 0x82 podle vaší USB flash paměti), délka přenosu je velikost struktury CSW v bytech. Překontrolujte, že přečtená struktura CSW má signaturu dcswsignature == 0x53425355 a bcswstatus == 0. Doporučené pořadí užití SCSI příkazů 1. INQUIRY
BI-MPP Cvičení 5,6 - USB Mass Storage, Miroslav Skrbek (C)2010,2011 4 z 5 2. 3. 4. REQUEST SENSE READ CAPACITY READ Užití příkazu REQUEST SENSE před příkazy READ CAPACITY a READ se zdá kritické pro správnou funkci těchto příkazů. SCSI příkazy INQUIRY Vyčtení informací o zařízení. dcbwdatatransferlength: 36 bcbwcblength: 6; 0 1 2 3 4 5 12h 00h 00h AH AL 00h AH*256+AL udává alokační velikost bufferu pro přečtení informací o zařízení (tj. jak velkou část informace chceme přečíst). Nám bude stačit načíst 36 bytů (AL=36, AH=0) REQUEST SENSE Vyčtení informací o zařízení. dcbwdatatransferlength: 18 bcbwcblength: 6; 0 1 2 3 4 5 03h 00h 00h 00h AL 00h AL udává alokační velikost bufferu pro přečtení informací o zařízení (tj. jak velkou část informace chceme přečíst). Nám bude stačit načíst 18 bytů (AL=18) READ CAPACITY Zjištění kapacity disku. dcbwdatatransferlength: 8
BI-MPP Cvičení 5,6 - USB Mass Storage, Miroslav Skrbek (C)2010,2011 5 z 5 bcbwcblength: 10; 0 1 2 3 4 5 6 7 8 9 25h 00h 00h 00h 00h 00h 00h 00h 00h 00h Data zaslaná příkazem mají následující strukturu: 0 1 2 3 4 5 6 7 mlba3 mlba2 mlba1 mlba0 blen3 blen2 blen1 blen0 mlba = (mlba3 «24) (mlba2 «16) (mlba1 «8) mlba0; adresa posledního bloku. blen = (blen3 «24) (blen2 «16) (blen1 «8) blen0; velikost bloku v bytech. Kapacita media: size = (mlba+1)*blen; READ Čtení dat z disku (jeden nebo více bloků) dcbwdatatransferlength: blen * BC (blen viz. READ CAPACITY) bcbwcblength: 10; 0 1 2 3 4 5 6 7 8 9 28h 00h LBA3 LBA2 LBA1 LBA0 00h BC1 BC0 00h LBA = (LBA3«24)+(LBA2«16)+(LBA1«8)+LBA0 je číslo logického bloku na médiu (adresa bloku). BC = BC1«8+BC0 je délka přenášených dat v blocích. Délka přenášených dat v bytech viz. dcbwdatatransferlength.