下面的程序可以在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\n");
 //memset(pages_addr,0x00,sizeof(pages_addr));
 printk("pages_addr:%x\n",pages_addr);
 printk("holder:%x\n",holder);
#if 1

bdev = open_by_devnum(0x00800000, FMODE_READ | FMODE_WRITE);
    //    bdev=0x800;
 if (IS_ERR(bdev))
 {
  printk("bdget error, bdev=%08lx \n", (unsigned long)bdev);
  return;
 }
 printk("bdev:%x\n",bdev);
 bdev->bd_holder = holder;
#if 0
 if (bd_claim(bdev, holder))
 {
  printk("claim failed \n");
  goto out_bdev;
 } 
 printk("after bd_claim\n");
#endif 
#if 0
// blocknr = *(unsigned long *)(pages_addr + 0x100000);
 //for (cnt = 0; cnt < 10 * 1024; cnt++, blocknr++)
 {
  printk("nr=%d\n",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\n");
// printk("get data:%0x,%0x\n,",pages_addr[510],pages_addr[511]);
 for( i = 0; i < 512; i++ )   
 {       
  printk( "%02x ",(unsigned char)pages_addr[ i ] );       
  if(( i % 16  ) == 15)       
  {           
   printk( "  \n" );       
  }   
 }   
 printk( "  \n" );

printk("nr=%d\n",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\n",nr);
  ret = bdev_read_one_page(bdev,nr, (void *)pages_addr);
  if (ret)
   printk("blk read failed ");

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

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\n");
 
}

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

linux2.6硬盘扇区直接读写程序的更多相关文章

  1. C语言编写的bmp读写程序

    C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下 <span style="font-size:16px;">#include "Windows ...

  2. 获取硬盘序列号的Fortran程序

    以前写了个获取硬盘序列号的fortran程序,但未经实证 program FortranDemo Use Kernel32 Implicit None Interface SUBROUTINE Get ...

  3. 分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)

    分配粒度和内存页面大小 x86处理器平台的分配粒度是64K,32位CPU的内存页面大小是4K,64位是8K,保留内存地址空间总是要和分配粒度对齐.一个分配粒度里包含16个内存页面. 这是个概念,具体不 ...

  4. WIN32和Kernel)直接读写硬盘扇区

    第一篇写技术的文章哦,以前好少写文章,我的文字表达很差劲,大家不要笑哦.前几天仙剑4通关了,感觉好惆怅,什么都不想去做.今天看了一下书发现一篇比较好玩的文章,于是自己静静地实践一番.文章是<基于 ...

  5. MSP430的IO口模拟I2C总线对AT24C25进行读写程序

    功能: 实现MSP430口线模拟I2C总线协议与24C04通信.                                           ** 描述: 主系统工作时钟为12MHz,I2C工 ...

  6. 一个简单的mfc单页界面文件读写程序(MFC 程序入口和执行流程)

    参考:MFC 程序入口和执行流程  http://www.cnblogs.com/liuweilinlin/archive/2012/08/16/2643272.html 程序MFCFlie      ...

  7. How to fix 'sudo: no tty present and no askpass program'以及硬盘序列号的读写

    在调用system命令读写硬盘序列号的过程中遇到问题,报错如下: sudo: no tty present and no askpass program 发现此问题是由于帐号并没有开启免密码导致的 . ...

  8. CPU卡读写程序

    CPU卡也称智能卡,卡内的集成电路中带有微处理器CPU.存储单元(包括随机存储器RAM.程序存储器ROM以及芯片操作系统COS.装有COS的CPU卡相当于一台微型计算机,不仅具有数据存储功能,同时具有 ...

  9. Excel 读写程序 C#源代码下载

    http://u.163.com/lNaJAjOz  提取码: E4ZHjnfD

随机推荐

  1. (转)Unity控制反转和依赖注入

    昨天,面试官说他们的项目使用的是Unity,我们的项目中使用的是autofac,看了一下,用法都差不多,就连方法的名字都是一样的哈,想了解的朋友可以看看这篇文章,作者讲解的挺详细的,关于autofac ...

  2. HTTP面试题都在这里

    HTTP常见面试题 Http与Https的区别: Http与Https的区别: HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头 HTTP 是不安全的,而 ...

  3. python学习1:程序元素和基本使用方法(跟随mooc学习)

    程序元素: 注释,缩进,变量,常量,表达式 输入,输出,分支,循环 示例程序,温度转换程序: #TempConvert.pyval=input("请输入带温度表示符号发温度值(例如:32C) ...

  4. c语言环境初始化&c语言和汇编混合编程

    bootloader通常会分为两个阶段:第一阶段采用汇编语言来编写,主要是一些核心的初始化工作(内存,时钟的初始化),第二阶段使用C语言来编写,主要是它会完成一些板载硬件的初始化(串口,网口)然后其启 ...

  5. 从Myeclipse到Intelj Idea

    前言:经历了从eclipse到Myeclipse的时间,大学时候用Eclipse,开始工作的时候选择Myeclipse,都能体会到Java的IDE的先进和高明之处,直到最近,公司项目采git和Grad ...

  6. 使用Ajax发送http请求(get&post请求)

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 同步和异步 同步和异步的概念 同步:必须等待前面的任务完成,才能继续后面 ...

  7. SpringMvc自动装配@Controller无效

    1.问题原因:SpringMvc驱动器没有扫描该Controller层 虽然配置了 <!-- 启用spring mvc 注解 --> <context:annotation-conf ...

  8. 记一次内存溢出的分析经历——thrift带给我的痛orz

    说在前面的话 朋友,你经历过部署好的服务突然内存溢出吗? 你经历过没有看过Java虚拟机,来解决内存溢出的痛苦吗? 你经历过一个BUG,百思不得其解,头发一根一根脱落的烦恼吗? 我知道,你有过! 但是 ...

  9. JDBC数据库操作

    JDBC:   创建SQL语句对象    Statement statement = (Statement) con.createStatement() ;   调用执行     statement. ...

  10. markdown学习经验

    文章首发于我的github博客 前言 markdown是一种简洁有力的文本编辑语言.由于它十分好用,我将所有的博客都换成了markdown编辑器. 学习方法 工具为先,从工具中学习,熟能生巧. 工具选 ...