开机读取/sdcard
有些驱动需要开机读取/sdcard中的文件, 比如配置以及升级用的.fw, .bin等等.
我们可以采用等待/sdcard挂载, 路径未知时可遍历文件夹查找文件, 已知时则直接filp_open进行调用.
模块加载采用线程方式
- module_init -> late_initcall
- func方式 -> thread方式
static int my_check_fs_mounted(char *path_name)
{
struct path root_path;
struct path path;
int err;
int i;
for (i = 0; i < 50; i++) {
msleep(500);
err = kern_path("/", LOOKUP_FOLLOW, &root_path);
if (err) {
pr_err("\"/\" not mounted: %d\n", i);
continue;
}
err = kern_path(path_name, LOOKUP_FOLLOW, &path);
if (err) {
pr_err("%s not mounted: %d\n", path_name, i);
msleep(500);
continue;
}
if (path.mnt->mnt_sb == root_path.mnt->mnt_sb) {
return -EINVAL;
}
pr_err("%s mounted!\n", path_name);
break;
}
return 0;
}
static int my_module_init_thread(void *dir)
{
int ret = 0;
pr_info("%s\n", __func__);
ret = my_check_fs_mounted("/sdcard/");
if (ret) {
pr_err("wait for /sdcard/ mount failed!\n");
return -EIO;
}
return ret;
}
static int __init my_module_init(void)
{
struct task_struct *thread;
thread = kthread_run(my_module_init_thread, (void*)NULL, "my_thread");
if (IS_ERR(thread)) {
pr_err("failed to create thread for my module init\n");
return -EIO;
}
return 0;
}
static void __exit my_module_exit(void)
{
pr_err("my_module_exit\n");
}
//module_init(my_module_init);
late_initcall(my_module_init);
module_exit(my_module_exit);
以下是文件和文件夹打开情况,遇到的情况总结:
filp_open | Linux 3.4,L | Linux 3.18, M |
---|---|---|
文件 | OK | OK |
文件夹 | 可访问,可遍历 | drwxrwx–x: 不可访问; drwxrwxr-x: 可访问,不可遍历1 |
Android | 启动OK | Launcher Stopped!2 |
1: 关闭SELinux是一种解决方法:
CONFIG_SECURITY_SELINUX: y->n
2: 可能是因为my_check_fs_mounted()
导致文件系统异常
解决方法:
frameworks\base\core\java\android\view\View.java:
@Override
protected void onRestoreInstanceState(Parcelable state) {
try {
super.onRestoreInstanceState(state);
} catch (Exception e) {
}
state=null;
}
遍历文件夹
请参考我的博文: Linux driver 遍历指定文件夹查找文件