kernel裡讀寫一個分割槽 函式定義
阿新 • • 發佈:2019-01-04
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm-generic/uaccess.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/delay.h>
#define NODE "/dev/block/mmcblk0p48"
#define PAGE_ODM_SIZE 2048
#define READ_FLAG 0
#define WRITE_FLAG 1
#define SN_NUM_OFFSET 0
#define SNU_ADDR_OFFSET 512
#define DSI_CONF_OFFSET 1024
#define MAC_ADDR_OFFSET 1536
#define RESERVE_OFFSET 2048
#define CONFIG_PARTITION_DBG
#ifdef CONFIG_PARTITION_DBG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
#else
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#endif
static struct kobject *k_obj = NULL;
int get_partition_info(const char *filename, char *buf, loff_t offset, int length, bool flag)
{
struct file *filep;
mm_segment_t old_fs;
filep= filp_open(filename, O_RDONLY, 0);
if(IS_ERR(filep))
{
CDBG("%s:%d open %s err!\n",__func__,__LINE__,filename);
return -ENODEV;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
CDBG("%s:%d offset:%d\n",__func__,__LINE__, (int)offset);
filep->f_op->llseek(filep, offset, SEEK_CUR);
if(flag==READ_FLAG)
length=filep->f_op->read(filep, buf, length, &filep->f_pos);
else
length=filep->f_op->write(filep, buf, length, &filep->f_pos);
set_fs(old_fs);
filp_close(filep, 0);
return length;
}
static ssize_t meig_iopartition_show(struct device *dev, struct device_attribute *attr, char *buf)
{
int i,size;
char val[PAGE_ODM_SIZE] ={0};
size = get_partition_info(NODE,val,SN_NUM_OFFSET,PAGE_ODM_SIZE,READ_FLAG);
CDBG("%s:%d buf size= %d\n",__func__, __LINE__, size);
for(i=0; i<sizeof(val);i++)
CDBG("val[%d]=%c \t", i, val[i]);
return snprintf(buf,PAGE_ODM_SIZE,"%s\n", val);
}
/*
* Parse user specified options (`video=controlfb:')
*/
static ssize_t meig_iopartition_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
char input[PAGE_ODM_SIZE/2] ={0};
char options[PAGE_ODM_SIZE/2] ={0};
char *sptr, *this_opt;
CDBG("%s:%d buf size= %d\n",__func__, __LINE__, (int)size);
sscanf(buf, "%s", options);
memcpy(input, options, sizeof(options));
sptr = options;
CDBG("%s:%d the partition info is %s\n",__func__,__LINE__,input);
while ((this_opt = strsep(&sptr, ":")) != NULL) {
if (!strncmp(this_opt, "snu#", 4)) {
get_partition_info(NODE,input,DSI_CONF_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
} else if (!strncmp(this_opt, "dsi#", 4)) {
get_partition_info(NODE,input,SN_NUM_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
} else if (!strncmp(this_opt, "mac#", 4)) {
get_partition_info(NODE,input,MAC_ADDR_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
}else {
get_partition_info(NODE,input,SN_NUM_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
}
}
CDBG("%s:%d end",__func__,__LINE__);
return size;
}
static DEVICE_ATTR(iopartition, 0644 , meig_iopartition_show, meig_iopartition_store);
static struct attribute *sysfs_demo_attributes[] = {
&dev_attr_iopartition.attr,
//&dev_attr_kickstate.attr,
NULL
};
static const struct attribute_group sysfs_demo_attr_group = {
.attrs = sysfs_demo_attributes,
};
static int __init partition_init(void)
{
CDBG("%s:%d init\n",__func__,__LINE__);
if ((k_obj = kobject_create_and_add("iopartition", NULL)) == NULL ) {
pr_err("sysfs_create_group sys node create error \n");
return -ENODEV;
}
if(sysfs_create_group(k_obj, &sysfs_demo_attr_group)) {
pr_err("sysfs_create_group failed\n");
return -ENODEV;
}
return 0;
}
static void __exit partition_exit(void)
{
CDBG("%s,%s,%d exit\n",__FILE__,__func__,__LINE__);
}
late_initcall(partition_init);
module_exit(partition_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("the dead warker");
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm-generic/uaccess.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/ctype.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/delay.h>
#define NODE "/dev/block/mmcblk0p48"
#define PAGE_ODM_SIZE 2048
#define READ_FLAG 0
#define WRITE_FLAG 1
#define SN_NUM_OFFSET 0
#define SNU_ADDR_OFFSET 512
#define DSI_CONF_OFFSET 1024
#define MAC_ADDR_OFFSET 1536
#define RESERVE_OFFSET 2048
#define CONFIG_PARTITION_DBG
#ifdef CONFIG_PARTITION_DBG
#define CDBG(fmt, args...) pr_err(fmt, ##args)
#else
#define CDBG(fmt, args...) pr_debug(fmt, ##args)
#endif
static struct kobject *k_obj = NULL;
int get_partition_info(const char *filename, char *buf, loff_t offset, int length, bool flag)
{
struct file *filep;
mm_segment_t old_fs;
filep= filp_open(filename, O_RDONLY, 0);
if(IS_ERR(filep))
{
CDBG("%s:%d open %s err!\n",__func__,__LINE__,filename);
return -ENODEV;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
CDBG("%s:%d offset:%d\n",__func__,__LINE__, (int)offset);
filep->f_op->llseek(filep, offset, SEEK_CUR);
if(flag==READ_FLAG)
length=filep->f_op->read(filep, buf, length, &filep->f_pos);
else
length=filep->f_op->write(filep, buf, length, &filep->f_pos);
set_fs(old_fs);
filp_close(filep, 0);
return length;
}
static ssize_t meig_iopartition_show(struct device *dev, struct device_attribute *attr, char *buf)
{
int i,size;
char val[PAGE_ODM_SIZE] ={0};
size = get_partition_info(NODE,val,SN_NUM_OFFSET,PAGE_ODM_SIZE,READ_FLAG);
CDBG("%s:%d buf size= %d\n",__func__, __LINE__, size);
for(i=0; i<sizeof(val);i++)
CDBG("val[%d]=%c \t", i, val[i]);
return snprintf(buf,PAGE_ODM_SIZE,"%s\n", val);
}
/*
* Parse user specified options (`video=controlfb:')
*/
static ssize_t meig_iopartition_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
char input[PAGE_ODM_SIZE/2] ={0};
char options[PAGE_ODM_SIZE/2] ={0};
char *sptr, *this_opt;
CDBG("%s:%d buf size= %d\n",__func__, __LINE__, (int)size);
sscanf(buf, "%s", options);
memcpy(input, options, sizeof(options));
sptr = options;
CDBG("%s:%d the partition info is %s\n",__func__,__LINE__,input);
while ((this_opt = strsep(&sptr, ":")) != NULL) {
if (!strncmp(this_opt, "snu#", 4)) {
get_partition_info(NODE,input,DSI_CONF_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
} else if (!strncmp(this_opt, "dsi#", 4)) {
get_partition_info(NODE,input,SN_NUM_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
} else if (!strncmp(this_opt, "mac#", 4)) {
get_partition_info(NODE,input,MAC_ADDR_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
}else {
get_partition_info(NODE,input,SN_NUM_OFFSET,size, WRITE_FLAG);
CDBG("%s:%d this_opt:%s\n",__func__,__LINE__,this_opt);
break;
}
}
CDBG("%s:%d end",__func__,__LINE__);
return size;
}
static DEVICE_ATTR(iopartition, 0644 , meig_iopartition_show, meig_iopartition_store);
static struct attribute *sysfs_demo_attributes[] = {
&dev_attr_iopartition.attr,
//&dev_attr_kickstate.attr,
NULL
};
static const struct attribute_group sysfs_demo_attr_group = {
.attrs = sysfs_demo_attributes,
};
static int __init partition_init(void)
{
CDBG("%s:%d init\n",__func__,__LINE__);
if ((k_obj = kobject_create_and_add("iopartition", NULL)) == NULL ) {
pr_err("sysfs_create_group sys node create error \n");
return -ENODEV;
}
if(sysfs_create_group(k_obj, &sysfs_demo_attr_group)) {
pr_err("sysfs_create_group failed\n");
return -ENODEV;
}
return 0;
}
static void __exit partition_exit(void)
{
CDBG("%s,%s,%d exit\n",__FILE__,__func__,__LINE__);
}
late_initcall(partition_init);
module_exit(partition_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("the dead warker");