The following program can be directly read and written to the hard disk in the linux2.6 kernel sector, but also according to the practice of a friend on the internet has been modified;
There are two areas that are not very clear: 1, the use of the Bd_claim function, this is a recursive function, such as matching memory pointers and devices, but the call will return an error; 2, Bdev = Open_by_devnum (0x00800000, Fmode_read | Fmode_write); 0x00800000 the confirmation of the number, I do not know where to come from:
#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 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 < 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 < 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 < 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 hard disk Sector direct read-write program