随着Android大版本的不断迭代,原本的外置存储基本上都没有了,取而代之的是内置sdcard,即系统根目录下的sdcard/目录。那/sdcard/目录在系统启动过程中什么时间、被谁创建、实际对应的分区又是哪个呢?本片文章将来介绍下sdcard目录与实际分区的关系。
首先来看下用到的文件目录:
system/core/rootdir/init.rc
system/core/init/
frameworks/base/services/core/java/com/android/server/StorageManagerService.java
system/vold/
既然要查找sdcard的创建历程,先来看看该文件在系统中的表现形式。
lrwxrwxrwx 1 root root 21 1970-01-01 08:00 /sdcard -> /storage/self/primary
lrwxrwxrwx 1 root root 19 1972-12-17 02:19 /storage/self/primary -> /mnt/user/0/primary
lrwxrwxrwx 1 root root 19 2020-02-21 10:31 /mnt/user/0/primary -> /storage/emulated/0
通过ls -al xxx 命令查看,基本都是软链接的形式存在,直到最后的/storage/emulated/0才是实际的存储空间,直接进入了对应的目录。
首先来看下第一个软链接/sdcard -> /storage/self/primary ,在init.rc中,可以找到下面的代码片段,发现sdcard目录被link到/storage/self/primary上,此过程是通过init来触发。
on init
...
# Symlink to keep legacy apps working in multi-user world
symlink /storage/self/primary /sdcard
symlink /storage/self/primary /mnt/sdcard
symlink /mnt/user/0/primary /mnt/runtime/default/self/primary
init.rc中的命令会通过builtins.cpp中的映射表去解析,symlink会对应do_symlink函数,最终还是通过Linux symlink函数执行,而/sdcard即是形参中的linkpath,对应的/mnt/sdcard和/mnt/runtime/default/self/primary也是一样的道理,此处可以看到/mnt/sdcard和/sdcard其实都是同一个对象的软链接,所以访问的内容也是一样的。
static int MakeSymlink(const std::string& target, const std::string& linkpath) {
std::string secontext;
// Passing 0 for mode should work.
if (SelabelLookupFileContext(linkpath, 0, &secontext) && !secontext.empty()) {
setfscreatecon(secontext.c_str());
}
int rc = symlink(target.c_str(), linkpath.c_str());
if (!secontext.empty()) {
int save_errno = errno;