zoukankan      html  css  js  c++  java
  • linux2.6硬盘扇区直接读写程序 分类: 磁盘的扇区读写 2015-04-29 10:37 317人阅读 评论(0) 收藏

    下面的程序可以在linux2.6内核直接读写硬盘的指定扇区,也是根据网上一个朋友的做法做了修改的;

    有两个不是很明白的地方就是:1、bd_claim函数的使用,这个是个递归函数,像是匹配内存指针和设备,但是调用会返回错误;2、bdev = open_by_devnum(0x00800000, FMODE_READ | FMODE_WRITE); 中0x00800000数字的确认,不知从何而来:

    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/sched.h>
    #include <linux/kernel.h>
    #include <linux/fs.h>
    #include <linux/types.h>
    #include <linux/buffer_head.h>
    #include <linux/blkdev.h>
    #include <linux/msdos_fs.h>
    #include <linux/fcntl.h>
    #include <linux/delay.h>

    static int set_size = 512;
    static int nr = 0;

    static char pages_addr[PAGE_SIZE];
    static char pages_write_addr[PAGE_SIZE];

    module_param(set_size,int,S_IRUGO);
    MODULE_PARM_DESC(set_size,"how many bytes you want to read,not more than 4096");

    module_param(nr,long,S_IRUGO);
    MODULE_PARM_DESC(nr,"which sectors you want to read");

    MODULE_LICENSE("GPL");

    static struct block_device *bdev;
    static char *usage = "You can change the value:set_size nr devn";

    int bdev_write_one_page(struct block_device *bdev, unsigned long blocknr, void *page_addr)
    {
     int ret = -1;
     struct buffer_head *bh;
     if (!bdev || !page_addr)
     {
      printk("%s error ", __func__);
      return -1;
     }
     bh = __getblk(bdev, blocknr, PAGE_SIZE);
     if (!bh)
     {
      printk("get blk failed ");
      return -1;
     }
     memcpy(bh->b_data, page_addr, PAGE_SIZE);
     mark_buffer_dirty(bh);
     ll_rw_block(WRITE, 1, &bh);
     
     brelse(bh);
     ret = 0;
     return ret;
    }

    int bdev_read_one_page(struct block_device *bdev, unsigned long blocknr, void *page_addr)
    {
     int ret = -1;
     struct buffer_head *bh;
     if (!bdev || !page_addr)
     {
      printk("%s error ", __func__);
      return -1;
     }

     bh = __getblk(bdev, blocknr, PAGE_SIZE);
     if (!bh)
     {
      printk("get blk failed ");
      return -1;
     }

     if (!buffer_uptodate(bh))
     {
      ll_rw_block(READ, 1, &bh);
      wait_on_buffer(bh);
      if (!buffer_uptodate(bh))
      {
       ret = -1;
       goto out;
      }
     }
     memcpy(page_addr, bh->b_data, PAGE_SIZE);
     ret = 0;

    out:
     brelse(bh);

     return ret;
    }

    void block_test(void)
    {
     struct block_device *bdev;
    // void *pages_addr = (void *)kmalloc(2048,GFP_KERNEL);
     void *holder = (void *)pages_addr;
     int cnt, ret;
     int blocknr;
     //bdev = bdget(MKDEV(16, 0));
     int i = 0;
     
     printk("block_test:IN ---------2010-03-22 ");
     //memset(pages_addr,0x00,sizeof(pages_addr));
     printk("pages_addr:%x ",pages_addr);
     printk("holder:%x ",holder);
    #if 1 


     bdev = open_by_devnum(0x00800000, FMODE_READ | FMODE_WRITE);
        //    bdev=0x800;
     if (IS_ERR(bdev))
     {
      printk("bdget error, bdev=%08lx ", (unsigned long)bdev);
      return;
     }
     printk("bdev:%x ",bdev);
     bdev->bd_holder = holder;
    #if 0
     if (bd_claim(bdev, holder))
     {
      printk("claim failed ");
      goto out_bdev;
     
     printk("after bd_claim ");
    #endif 
    #if 0
    // blocknr = *(unsigned long *)(pages_addr + 0x100000);
     //for (cnt = 0; cnt < 10 * 1024; cnt++, blocknr++)
     {
      printk("nr=%d ",nr);
      memset(pages_addr,0xff,PAGE_SIZE);
      ret = bdev_read_one_page(bdev,nr, (void *)pages_addr);
      if (ret)
       printk("blk read failed ");

     }
     printk("after bdev_read_one_page ");
    // printk("get data:%0x,%0x ,",pages_addr[510],pages_addr[511]);
     for( i = 0; i < 512; i++ )   
           
      printk( "%02x ",(unsigned char)pages_addr[ i ] );       
      if(( i % 16  ) == 15)       
                
       printk( "   " );       
        
       
     printk( "   " );

     printk("nr=%d ",nr);
     memset(pages_write_addr,0xe7,PAGE_SIZE);
     ret = bdev_write_one_page(bdev,nr, (void *)pages_write_addr);
     if (ret)
      printk("blk write failed ");
    #endif
     {
      printk("nr=%d ",nr);
      ret = bdev_read_one_page(bdev,nr, (void *)pages_addr);
      if (ret)
       printk("blk read failed ");

     }
     printk("after bdev_read_one_page ");
    // printk("get data:%0x,%0x ,",pages_addr[510],pages_addr[511]);
     for( i = 0; i < 512; i++ )   
           
      printk( "%02x ",(unsigned char)pages_addr[ i ] );       
      if(( i % 16  ) == 15)       
                
       printk( "   " );       
        
       
     printk( "   " );

    out_bdev:
    // bd_release(bdev);
     
    // blkdev_put(bdev,FMODE_READ | FMODE_WRITE);
     blkdev_put(bdev);
    #endif
     return;
    }
    static int __init disk_rw_init(void)
    {
    // nr = 0;
    // set_size = PAGE_SIZE;

     block_test();

     return 0;
    }
    static void __exit disk_rw_exit(void)
    {
     printk("disk_rw_exit ");
     
    }

    module_init(disk_rw_init);
    module_exit(disk_rw_exit);

     

     

    Makefile:

    ifneq ($(KERNELRELEASE),)
     obj-m:=hw_disk_rw26.o
    else
     KDIR =/usr/src/linux-2.6.33
          KDIR = /usr/src/kernels/2.6.9-5.EL-i686
     PWD:=$(shell pwd)
    default:
     $(MAKE) -C $(KDIR) M=$(PWD) modules
    install:
     insmod hw_disk_rw26.ko
    uninstall:
     rmmod hw_disk_rw26.ko
    clean:
     $(MAKE) -C $(KDIR) M=$(PWD) clean

    endif

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    IDA 动态调试 ELF 文件
    双机调试环境搭建[win7+Windbg+VirtualKD]
    从域环境搭建到 MS14-068 提升为域权限
    栈溢出原理与 shellcode 开发
    Flask_0x05 大型程序结构
    rest-framework 框架的基本组件
    restful 规范
    Django的CBV和FBV
    Django-model 进阶
    Django-Ajax
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706434.html
Copyright © 2011-2022 走看看