linux2.6硬盘扇区直接读写程序 分类: 磁盘的扇区读写 2015-04-29 10:37 317人阅读 评论(0) 收藏
2015-04-29 10:37
609 查看
下面的程序可以在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
有两个不是很明白的地方就是: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
相关文章推荐
- 硬盘的扇面、磁道、扇区 分类: VC++ 生活百科 磁盘的扇区读写 2015-04-29 09:49 408人阅读 评论(1) 收藏
- 不同WINDOWS平台下磁盘逻辑扇区的直接读写 分类: 磁盘的扇区读写 2015-04-29 10:48 341人阅读 评论(0) 收藏
- 使用CreateFile, ReadFile, WriteFile在Windows NT/2000/XP下读写绝对扇区的方法 分类: 磁盘的扇区读写 2015-04-29 10:50 358人阅读 评论(0) 收藏
- VC++信息安全编程(13)Windows2000/xp/vista/7磁盘扇区读写技术 分类: 磁盘的扇区读写 VC++ 2015-04-29 10:38 357人阅读 评论(0) 收藏
- RHEL64 缺少ISO 9660图像 安装程序试图挂载映像#1,在硬盘上无法找到该映像 分类: arm-linux-Ubuntu 2015-01-20 16:47 644人阅读 评论(0) 收藏
- linux2.6硬盘扇区直接读写程序
- linux2.6硬盘扇区直接读写程序
- linux2.6硬盘扇区直接读写程序
- linux下测试磁盘的读写IO速度 分类: arm-linux-Ubuntu 2015-05-07 11:18 326人阅读 评论(0) 收藏
- win9x_win2k下对物理磁盘的操作 分类: VC++ 磁盘的扇区读写 2014-08-27 09:55 421人阅读 评论(0) 收藏
- linux2.6硬盘扇区直接读写程序
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号应用实例 分类: Linux --- 应用程序设计 2014-11-09 11:33 66人阅读 评论(0) 收藏
- linux下mount/unmount命令 分类: arm-linux-Ubuntu 2015-05-08 11:54 317人阅读 评论(0) 收藏
- LINUX下java串口程序环境配置 分类: LINUX 2010-07-07 10:04 1571人阅读 评论(0) 收藏
- 分类: linux程序设计 2012-03-06 22:01 10646人阅读 评论(5) 收藏 举报 linux语言c工具gcc程序开发 调试是每个程序员都会面临的问题. 如何提高程序员的调
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 管道 分类: Linux --- 应用程序设计 2014-11-05 11:18 75人阅读 评论(0) 收藏
- linux下的c程序排版工具:indent 分类: linux 2014-06-14 20:05 720人阅读 评论(0) 收藏
- 中断处理程序不能使用printf的本质 分类: vxWorks arm-linux-Ubuntu 2014-06-20 10:32 529人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础 分类: Linux --- 应用程序设计 2014-11-11 13:08 51人阅读 评论(0) 收藏
- uboot启动后在内存中运行裸机程序hello 分类: HI3531 arm-linux-Ubuntu 2013-12-12 10:20 836人阅读 评论(0) 收藏