zoukankan      html  css  js  c++  java
  • 使用HD/IDE层的ioctl接口获取磁盘容量get_hdd_max_sector

    利用HD/IDE layer的ioctl函数接口获取HD/IDE的磁盘容量。HDIO_DRIVE_TASK  能发出訪问LBA地址的命令。但不能读写数据。

    #include <stdio.h>

    #include <string.h>

    #include <unistd.h>

    #include <stdlib.h>

    #include <linux/hdreg.h>

    #include <linux/types.h>

    #include <sys/stat.h>

    #include <scsi/sg.h>

    #include <scsi/scsi.h>

    #include <sys/ioctl.h>

    #include <linux/fs.h>

    #include <fcntl.h>

    #include <errno.h>

    #include <sys/time.h>

     

    #define ATA_DRQ             (1 << 3)    /* data request i/o */

    #define ATA_ERR             (1 << 0) /* have an error */

    #define DRIVER_SENSE        0x08

    #define CONDITION_GOOD      0x02

    #define ATA_PASS_THRU_12    12

    #define ATA_12              0xa1

    #define ATA_PASS_THRU_16    16

    #define ATA_16              0x85

     

    #define u64     unsigned long long

    #define u32     unsigned int

    #define u8      unsigned char

    #define u16     unsigned short

     

    //ATA commands

    enum {

        ATA_OP_DSM          = 0x06, // Data Set Management (TRIM)

        ATA_OP_READ_PIO         = 0x20,

        ATA_OP_READ_PIO_ONCE        =0x21,

        ATA_OP_READ_LONG        =0x22,

        ATA_OP_READ_LONG_ONCE       =0x23,

        ATA_OP_READ_PIO_EXT     =0x24,

        ATA_OP_READ_DMA_EXT     =0x25,

        ATA_OP_READ_FPDMA       =0x60, // NCQ

        ATA_OP_WRITE_PIO        =0x30,

        ATA_OP_WRITE_LONG       =0x32,

        ATA_OP_WRITE_LONG_ONCE      =0x33,

        ATA_OP_WRITE_PIO_EXT        =0x34,

        ATA_OP_WRITE_DMA_EXT        =0x35,

        ATA_OP_WRITE_FPDMA      =0x61, // NCQ

        ATA_OP_READ_VERIFY      =0x40,

        ATA_OP_READ_VERIFY_ONCE     =0x41,

        ATA_OP_READ_VERIFY_EXT      =0x42,

        ATA_OP_WRITE_UNC_EXT        =0x45, // lba48, no data, uses feat reg

        ATA_OP_FORMAT_TRACK     =0x50,

        ATA_OP_DOWNLOAD_MICROCODE   = 0x92,

        ATA_OP_STANDBYNOW2      =0x94,

        ATA_OP_CHECKPOWERMODE2      =0x98,

        ATA_OP_SLEEPNOW2        =0x99,

        ATA_OP_PIDENTIFY        =0xa1,

        ATA_OP_READ_NATIVE_MAX      =0xf8,

        ATA_OP_READ_NATIVE_MAX_EXT  = 0x27,

        ATA_OP_SMART            = 0xb0,

        ATA_OP_DCO          = 0xb1,

        ATA_OP_ERASE_SECTORS        =0xc0,

        ATA_OP_READ_DMA         = 0xc8,

        ATA_OP_WRITE_DMA        =0xca,

        ATA_OP_DOORLOCK         = 0xde,

        ATA_OP_DOORUNLOCK       =0xdf,

        ATA_OP_STANDBYNOW1      =0xe0,

        ATA_OP_IDLEIMMEDIATE        =0xe1,

        ATA_OP_SETIDLE          = 0xe3,

        ATA_OP_SET_MAX          = 0xf9,

        ATA_OP_SET_MAX_EXT      =0x37,

        ATA_OP_SET_MULTIPLE     =0xc6,

        ATA_OP_CHECKPOWERMODE1      =0xe5,

        ATA_OP_SLEEPNOW1        =0xe6,

        ATA_OP_FLUSHCACHE       =0xe7,

        ATA_OP_FLUSHCACHE_EXT       =0xea,

        ATA_OP_IDENTIFY         = 0xec,

        ATA_OP_SETFEATURES      =0xef,

        ATA_OP_SECURITY_SET_PASS    = 0xf1,

        ATA_OP_SECURITY_UNLOCK      =0xf2,

        ATA_OP_SECURITY_ERASE_PREPARE   = 0xf3,

        ATA_OP_SECURITY_ERASE_UNIT  = 0xf4,

        ATA_OP_SECURITY_FREEZE_LOCK = 0xf5,

        ATA_OP_SECURITY_DISABLE     =0xf6,

        ATA_OP_VENDOR_SPECIFIC_0x80 = 0x80,

    /* added by openvox */

        ATA_OP_SET_MAX_SET_PASSWORD = 0xf9,

       

    };

     

    int verbose = 1;

    u8 last_identify_op = 0;

    u16 *id;

     

    static u64 get_disk_size(const char*name)

    {

       const char *ptr = name + strlen(name) - 3;

       u64 size;

       char buff[128];

       FILE *fp;

       

       sprintf(buff,"/sys/block/%s/size",ptr);

     

       if(NULL == (fp = fopen(buff,"r"))){

           perror("fopen");

           return 0;

       }

       fscanf(fp,"%lld",&size);

       fclose(fp);

       

       return size;

    }

     

    /*!

        IssuingATA commands 

    */

    int ata_ioctl(int fd)

    {

       unsigned char cdb[7];

       int err = 0;

       

       cdb[0] = ATA_OP_READ_NATIVE_MAX ; //command id ATA_OP_READ_NATIVE_MAX_ADDRESS 0xf8

       cdb[1] = 0x00;              //feature id

       cdb[2] = 0x00;              //number of sectors

        cdb[3]= 0x00;              //LBAlow

       cdb[4] = 0x00;              //LBA mid

       cdb[5] = 0x00;              //LBA high

       cdb[6] = 0x40;              // device select

       

       if (-1 == (err = ioctl(fd, HDIO_DRIVE_TASK, (void *)cdb))) {

           perror("HDIO_DRIVE_TASK erro in ata_ioctl! ");

           return -1;

       }

       printf ("status %02x ", cdb[0]);

        printf("error  %02x ", cdb[1]);

        printf("n sect %02x ", cdb[2]);

        printf("LBA L  %02x ", cdb[3]);

        printf("LBA M  %02x ", cdb[4]);

        printf("LBA H  %02x ", cdb[5]);

        printf("select %02x ", cdb[6]);

       return 0;

    }

     

     

    static void get_identify_data (int fd)

    {

        staticu8 args[4+512];

        inti = 0;

        memset(args,0, sizeof(args));

        last_identify_op= ATA_OP_IDENTIFY;

        args[0]= last_identify_op;

        args[3]= 1;    /* sector count */

        if(do_drive_cmd(fd, args, 0)) {

            perror(" HDIO_DRIVE_CMD(identify)failed");

            return;

        }  

        printf("incomingdata : ");

        for(; i < 512; i++)

        {   if(i == 0)

                printf(" 0 :");

            printf("%02x ",args[i+4]);

            if ((i+1) % 20 == 0)

                printf(" %d:",i+1);

        }

        printf(" ");

     

    }

     

    int main(int argc, char *argv[])

    {

       u64 offset = 0;

       int fd;

       u64 capacity;

       int size;

       

       if (argc != 2) {

           printf("Usage: %s devname ",argv[0]);

           printf(" ");

           return 0;

       }

     

       capacity = get_disk_size(argv[1]);

       printf("HDD capacity = %lld ",capacity);

       

       if(-1 == (fd = open(argv[1],O_RDWR))){

           perror("open");

           return fd;

       }

        get_identify_data(fd);

       

        if(ata_ioctl(fd) != 0)

        {

            printf("ata_ioctl error ! ");

            exit(-1);

        }

       close(fd);

       

       return 0;

    }

    博约分享代码:http://blog.csdn.net/yuesichiu/article/details/40535501


  • 相关阅读:
    PCB封装分配
    1.26-CAD异形封装的制作
    1.40-CAE封装6个实例单门制作
    简单的URL解析
    冒泡排序和简单的递归
    作用域的提升
    数组的去重,以及随机一个验证码
    数组和字符串的相互转换。
    substring,substr,和slice的区别详解。
    去除Input输入框中边框的方式
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/6852420.html
Copyright © 2011-2022 走看看