linux驱动程序直接读写扇区,linux2.6硬盘扇区直接读写程序

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

有两个不是很明白的地方就是:1、bd_claim函数的使用,这个是个递归函数,像是匹配内存指针和设备,但是调用会返回错误;2、bdev

= open_by_devnum(0x00800000, FMODE_READ | FMODE_WRITE);

中0x00800000数字的确认,不知从何而来:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值