下面的程序可以在linux2.6内核直接读写硬盘的指定扇区,也是根据网上1个朋友的做法做了修改的; 有两个不是很明白的地方就是: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 = ⑴; struct buffer_head *bh; if (!bdev || !page_addr) { printk("%s error ",__func__); return ⑴; } bh = __getblk(bdev,blocknr,PAGE_SIZE); if (!bh) { printk("get blk failed "); return ⑴; } 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,__func__); return ⑴; } bh = __getblk(bdev,PAGE_SIZE); if (!bh) { printk("get blk failed "); return ⑴; } if (!buffer_uptodate(bh)) { ll_rw_block(READ,&bh); wait_on_buffer(bh); if (!buffer_uptodate(bh)) { ret = ⑴; 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 --------⑵010-03⑵2
"); //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,(void *)pages_write_addr); if (ret) printk("blk write failed "); #endif { printk("nr=%d
",nr); ret = bdev_read_one_page(bdev,(void *)pages_addr); if (ret) printk("blk read failed "); 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⑵.6.33 # KDIR = /usr/src/kernels/2.6.9⑸.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 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|