linux2.6硬盘扇区直接读写程序

下面的程序可以在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

时间: 2024-10-28 06:05:01

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

Java与XML(二)用java编写xml的读写程序

xml|程序 Java与XML(二)用java编写xml的读写程序 这是读取xml文件的java程序,我调试好的.采用的是dom方式读取xml文件到Vector中.package src;import java.io.*;import java.util.Vector;import javax.xml.parsers.*;import org.w3c.dom.*;public class readxml { static Document document; private boolean va

C语言编写的bmp读写程序

C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下  [cpp] view plaincopy   <span style="font-size:16px;">#include "Windows.h"   #include "stdio.h"   #include "string.h"   #include "malloc.h"      unsigned char *pBmpBuf

写个取硬盘号的注册程序,测试了IDE可以,但串口硬盘不行,能否给点思路,谢谢了

问题描述 用C#写个取硬盘号的注册程序,测试了IDE可以,但串口硬盘不行,能否给点思路,谢谢了 解决方案 解决方案二:协议?还是什么?关注,没有做过这么深奥的cs解决方案三:程序咋写的?通过ManagementClass读取的吗?解决方案四:没做过,关注,帮顶解决方案五:当取不到硬盘序列号时,就取主板或者CPU的吧..解决方案六:[DllImport("Kernel32.dll",CharSet=CharSet.Auto,SetLastError=true)]privateextern

javascript cookie读写程序

网页特效 cookie读写程序 这里介绍了下关于cookie由js的实现,主要有删除,设置,读取cookie代码,有需要的朋友可以参考一下. //写cookies函数         function SetCookie(name, value)//两个参数,一个是cookie的名子,一个是值         {             var Days = 30; //此 cookie 将被保存 30 天             var exp = new Date();    //new D

cardme 0.3.2.03发布 vCard文件读写程序

cardme 是一个实现RFC 2426 VCard的Java库,提供了vCard文件格式读写方式的Java应用程序.其目标是提供一个灵活和易于使用的优秀文档库. cardme 0.3.2.03该版本修正了展开正则表达式的问题,以及不符合安全要求的RFC-822折叠. 软件信息:http://sourceforge.net/projects/cardme/ 下载地址:http://sourceforge.net/projects/cardme/files/

这两个程序都无法实现,有没有比较完整的java读写程序呢

问题描述 程序1/**Tochangethislicenseheader,chooseLicenseHeadersinProjectProperties.*Tochangethistemplatefile,chooseTools|Templates*andopenthetemplateintheeditor.*//****@authorminer*/importjava.io.BufferedReader;importjava.io.BufferedWriter;importjava.io.Fi

java常用图片读写程序

package util; import java.io.File;   import java.io.FileOutputStream;   import java.awt.Graphics;   import java.awt.Image;   import java.awt.image.BufferedImage;   import com.sun.image.codec.jpeg.JPEGCodec;   import com.sun.image.codec.jpeg.JPEGImage

《NTFS文件系统扇区存储探秘》——1.4 文件分配表FAT

1.4 文件分配表FAT NTFS文件系统扇区存储探秘 FAT文件系统在管理磁盘上的用户文件时,使用了文件分配表的管理方式.不过系统引导所需要的数据,不在文件分配表的管理范围之内.在这一点上与NTFS文件系统的存储方式是完全不相同的,NTFS文件系统将磁盘上的所有事物都看作文件,不管是用户的还是系统的. 文件分配表在FAT文件系统中占有非常重要的地位,对文件的所有操作,包括读.写.修改和复制,都要依赖于文件分配表中的有关记录.正因为如此,当初设计者将文件分配表作了两份相同的拷贝存储在磁盘上. 1

《NTFS文件系统扇区存储探秘》——1.3 分区引导记录

1.3 分区引导记录 NTFS文件系统扇区存储探秘 硬盘的主引导记录只有一个,存储在硬盘的线性0号扇区上.而硬盘的分区引导记录不止一个,每一个逻辑驱动器都有一个分区引导记录.如果将一个硬盘分为C.D.E.F.G5个逻辑驱动器,就应该有5个分区引导记录,分别存储在各个逻辑驱动器的第1个逻辑扇区中. 分区引导记录主要由4部分组成. (1)BIOS参数记录块BPB(BIOS Parameter Block). (2)磁盘标志记录表. (3)分区引导记录代码区. (4)结束标志"55 AA".