在/protect_f/、 /protect_f/,这两个目录下的文件在恢复出厂设置后不会被清除
恢复出厂设置后会清除创建的文件,
1. 打开文件
strcut file* filp_open(const char* filename, int open_mode, int mode);
open_mode:O_CREAT,O_RDWR,O_RDONLY等
mode: 创建文件时使用,设置创建文件的读写权限,其它情况可以匆略设为0
2. 读写
ssize_t vfs_read(struct file* filp, char __user* buffer, size_t len, loff_t* pos);
ssize_t vfs_write(struct file* filp, const char __user* buffer, size_t len, loff_t* pos);
第二个参数buffer,前面都有__user修饰符,这就要求这两个buffer指针都应该指向用户空间的内存,如果对该参数传 递kernel空间的指针,这两个函数都会返回失败-EFAULT。但在Kernel中,我们一般不容易生成用户空间的指针,或者不方便独立使用用户空间 内存。要使这两个读写函数使用kernel空间的buffer指针也能正确工作,需要使用set_fs()函数。
len:为要读写的长度。
pos:为从文件当前位置向前或向后偏移多少开始。
3. 设置kernel对内存地址检查的处理方式,参数为USER_DS、KERNEL_DS,表示用户空间和内核空间。kernel默认的是用户空间,固在内核驱动中要使用文件系统需要修改为内核空间检查的方式。
void set_fs(mm_segment_t fs);
例子:
#include <linux/file.h>
#include <linux/fs.h>
struct file* file_id = NULL;
char default_lcm[20] = "dfsdf";
mm_segment_t fs;
loff_t pos = 0;
u32 file_size = 0;
file_id = filp_open("/data/lcminfo.txt", O_CREAT | O_RDWR, 0);
if(NULL == file_id)
return 0;
else
{
fs = get_fs(); kernel对内存地址检查的处理方式// 保留原来kernel对内存地址检查的处理方式
set_fs(KERNEL_DS); //设置kernel对内存地址检查的处理方式为内核空间检查
memset(default_lcm, 0, sizeof(default_lcm));
file_size = vfs_llseek(file_id, 0, SEEK_END); // 查看并保留文件的大小
if(vfs_read(file_id, default_lcm, file_size, &pos) <= 0 )
{
seq_printf(m, "LCM:%s\n", lcm_driver_list[lcm_proc_i]->name);
if(vfs_write(file_id, lcm_driver_list[lcm_proc_i]->name, (sizeof(lcm_driver_list[lcm_proc_i]->name)/sizeof(char)), &pos) <= 0)
printk("------> vfs_write failed\n");
}
else
seq_printf(m, "LCM:%s\n", default_lcm);
filp_close(file_id, NULL);
set_fs(fs); // 恢复原来kernel对内存地址检查的处理方式
}
参考:http://blog.youkuaiyun.com/iiprogram/article/details/2792243
http://blog.youkuaiyun.com/ozhengsfo/article/details/77428860
http://blog.chinaunix.net/uid-20764801-id-3234542.html
Android客制化------恢复出厂设置但保留文件:
http://blog.youkuaiyun.com/baifaqingsi/article/details/70224979