Thursday, November 19, 2015

Issue SATA commands directly through IOCTL

Directly write to SATA interface to perform simple read and write operation on a storage device.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <scsi/sg.h>
#include <scsi/scsi.h>
main()
{
 int fd;
 unsigned char buffer[512];

 fd=open("/dev/sda", O_RDWR );

 ReadSector(fd, 0, 1, buffer);
 WriteSector(fd, 0, 1, buffer);
}


// return 0 on fail
// return 1 on success
int ReadSector(int fd, int sector, int nsec, unsigned char *pbuffer)
{
 int res;
 int t_length;
 sg_io_hdr_t io_hdr;
 unsigned char sense_b[SG_MAX_SENSE];
 unsigned char rdCmdBlk6[6];

 t_length = 512;              // 512 bytes transferred per sec

// Prepare SCSI READ (6) command
 rdCmdBlk6[0]  = READ_6;           // COMMAND
 rdCmdBlk6[1]  = (sector & 0xFF0000 ) >> 16;           // LBA
 rdCmdBlk6[2]  = (sector & 0xff00) >> 8;         // LBA
 rdCmdBlk6[3]  = sector & 0xff;  // LBA
 rdCmdBlk6[4]  = nsec;
 rdCmdBlk6[5]  = 0x00;

// Prepare the sg_io_hdr_t structure
 memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
 io_hdr.interface_id = 'S';                  // Always set to 'S' for sg driver
 io_hdr.cmd_len = sizeof(rdCmdBlk6);         // Size of SCSI command
 io_hdr.mx_sb_len  = sizeof(sense_b);        // Max sense buffer size(for error)
 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; // Data transfer direction(no data)
 io_hdr.dxfer_len = nsec*t_length;                // Data transfer length(512)
 io_hdr.dxferp = pbuffer;                       // Data transfer buffer(none)
 io_hdr.cmdp = rdCmdBlk6;                    // SCSI command buffer
 io_hdr.sbp = sense_b;                       // Sense buffer
 io_hdr.timeout = 5000;                      // Timeout(5s)

// Sends the command to device
 if ((res = ioctl(fd, SG_IO, &io_hdr)) < 0) {
   return 0;
 }

// Error processing
 if ( ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) || // check info
      (io_hdr.masked_status != 0x00) ||                  // check status(0 if ioctl success)
      (io_hdr.msg_status != 0x00) ||                     // check message status
      (io_hdr.host_status != 0x00) ||                    // check host status
      (io_hdr.driver_status != 0x00) )                   // check driver status
 {
   return 0;
 } else {
   return 1;
 }
}

int WriteSector(int fd, int sector, int nsec, unsigned char *pbuffer)
{
 int res;
 int t_length;
 sg_io_hdr_t io_hdr;
 unsigned char sense_b[SG_MAX_SENSE];
 unsigned char rdCmdBlk6[6] ;
 t_length = 512;              // 512 bytes transferred per sec

// Prepare SCSI WRITE (6) command
 rdCmdBlk6[0]  = WRITE_6;           // COMMAND
 rdCmdBlk6[1]  = (sector & 0xFF0000 ) >> 16;           // LBA
 rdCmdBlk6[2]  = (sector & 0xff00) >> 8;         // LBA
 rdCmdBlk6[3]  = sector & 0xff;  // LBA
 rdCmdBlk6[4]  = nsec;
 rdCmdBlk6[5]  = 0x00;

// Prepare the sg_io_hdr_t structure
 memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
 io_hdr.interface_id = 'S';                  // Always set to 'S' for sg driver
 io_hdr.cmd_len = sizeof(rdCmdBlk6);         // Size of SCSI command
 io_hdr.mx_sb_len  = sizeof(sense_b);        // Max sense buffer size(for error)
 io_hdr.dxfer_direction = SG_DXFER_TO_DEV; // Data transfer direction(no data)
 io_hdr.dxfer_len = nsec*t_length;                // Data transfer length(512)
 io_hdr.dxferp = pbuffer;                       // Data transfer buffer(none)
 io_hdr.cmdp = rdCmdBlk6;                    // SCSI command buffer
 io_hdr.sbp = sense_b;                       // Sense buffer
 io_hdr.timeout = 5000;                      // Timeout(5s)

// Sends the command to device
 if ((res = ioctl(fd, SG_IO, &io_hdr)) < 0) {
   return 0;
 }

// Error processing
 if ( ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) || // check info
      (io_hdr.masked_status != 0x00) ||                  // check status(0 if ioctl success)
      (io_hdr.msg_status != 0x00) ||                     // check message status
      (io_hdr.host_status != 0x00) ||                    // check host status
      (io_hdr.driver_status != 0x00) )                   // check driver status
 {
   return 0;
 } else {
   return 1;
 }
}

Tuesday, November 17, 2015

Intel xHCI drivers

xHCI

https://downloadcenter.intel.com/download/21129/USB-3-0-Driver-Intel-USB-3-0-eXtensible-Host-Controller-Driver-for-Intel-7-Series-C216-Chipset-Family

https://downloadcenter.intel.com/download/22824/USB-3-0-Driver-Intel-USB-3-0-eXtensible-Host-Controller-Driver-for-Intel-8-9-100-Series-and-C220-C610-Chipset-Family

CentOS 7 32 bit VirtualBox client

Officially, CentOS 7 only has x86_64.  The first version 7.0 was released in 2014.

Not until 10/13/2015, AltArch SIG released a CentOS 7 32 bit for IOT x86 boards.
Release note: https://wiki.centos.org/SpecialInterestGroup/AltArch/i386
Release images: http://mirror.centos.org/altarch/7/isos/i386/

Not like the x86_64 version, the 32 bit version is not typically available on CentOS mirror sites.

At this moment, AltArch CentOS 7 32 bit version meets our need of creating USB token now with a catch.
- The two required RPM packages are from CentOS 6.7.  Luckily, they are working.

So far, I believe that it would be in the best interests of normal institution to consider taking CentOS 7 x86_64 instead of 32bit (i386/i686) version.  With x86_64, there is definitely less worry for future.


Note for getting the task done.

2 VirtualBox
2.1 Required VirtualBox components
Both VirtualBox installer and extension pack are required.  They can be found on the URL
http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html

2.2 Virtual Machine Creation
2.2.1 VirtualBox options
System->Motherboard->Base Memory must be >= 512MB
System->Processor->Extended Features check Enable PAE/NX
Network->Adapter 1 -> Advanced ->Adapter Type Intel PRO/1000 MT Desktop (8254OEM)
USB -> Enable USB Controller -> USB 3.0 (xHCI) Controller

Note that xHCI driver should be from vendors, Intel etc.

3 Install CentOS
3.1 Required CentOS 7 components
CentOS 7 ISO image
http://mirror.centos.org/altarch/7/isos/i386/CentOS-7-i386-Minimal-1503.iso
vim filesystem RPM package
ftp://fr2.rpmfind.net/linux/centos/6.7/os/i386/Packages/vim-filesystem-7.4.629-5.el6.i686.rpm
vim common RPM package
ftp://fr2.rpmfind.net/linux/centos/6.7/os/i386/Packages/vim-common-7.4.629-5.el6.i686.rpm

Friday, November 13, 2015

CentOS 7 32 bit virtualbox client

32bit CentOS 7 was released on 10/15/2015

The download is available here
http://mirror.centos.org/altarch/7/isos/i386/

When creating virtualbox client, the default configurations are not sufficient.

Create Virtual Machine:
- Linex and Other Linux(32-bit)

Settings
- System->Processor->Enable PAE/NX
- Network->Advanced->Adapter Type: Intel PRO/1000 MT Desktop (8254OEM)

CentOS 7 i386 by default won't recognize the default virtualbox network device.  This is from the 3.10 kernel taken by CentOS 7
https://www.centos.org/forums/viewtopic.php?f=47&t=47724

For development on CentOS, the following line will install compiler/linker packages.
yum groupinstall 'Development Tools'