接之前的(5)_1. mount函数的分析。
如果找到了rtems_filesystem_fsmount_me_t类型的该文件系统的处理函数,那么下面就可以继续安装了,接下来是alloc_mount_table_entry,该函数在在cpukit/libcsupport/src/mount.c中定义,该函数主要是分配内存,多是字符串的处理。
rtems_filesystem_mount_table_entry_t *mt_entry = alloc_mount_table_entry(
source,
target,
filesystemtype,
&target_length
);
这个函数返回类型是rtems_filesystem_mount_table_entry_t在
cpukit/include/rtems/fs.h
struct rtems_filesystem_mount_table_entry_tt;
typedef struct rtems_filesystem_mount_table_entry_tt
rtems_filesystem_mount_table_entry_t;
可见
rtems_filesystem_mount_table_entry_t是rtems_filesystem_mount_table_entry_tt的别名。
而rtems_filesystem_mount_table_entry_tt在cpukit/libcsupport/include/rtems/libio.h中定义
/*** @brief Mount table entry.
*/
struct rtems_filesystem_mount_table_entry_tt {
rtems_chain_node mt_node;
void *fs_info;
const rtems_filesystem_operations_table *ops;
const void *immutable_fs_info;
rtems_chain_control location_chain;
rtems_filesystem_global_location_t *mt_point_node;
rtems_filesystem_global_location_t *mt_fs_root;
bool mounted;
bool writeable;
const rtems_filesystem_limits_and_options_t *pathconf_limits_and_options;
/*
* The target or mount point of the file system.
*/
const char *target;
/*
* The type of filesystem or the name of the filesystem.
*/
const char *type;
/*
* When someone adds a mounted filesystem on a real device,
* this will need to be used.
*
* The lower layers can manage how this is managed. Leave as a
* string.
*/
char *dev;
/**
* The task that initiated the unmount process. After unmount process
* completion this task will be notified via the transient event.
*
* @see ClassicEventTransient.
*/
rtems_id unmount_task;
};
上述结构体中定义了挺多东西。
那么这个分配函数就是对这个类型的对象分配空间并填入对应的值。
static rtems_filesystem_mount_table_entry_t *alloc_mount_table_entry(
const char *source_or_null,
const char *target_or_null,
const char *filesystemtype,
size_t *target_length_ptr
)
{
//前面就是计算各种size
const char *target = target_or_null != NULL ? target_or_null : "/";
size_t filesystemtype_size = strlen( filesystemtype ) + 1;
size_t source_size = source_or_null != NULL ?
strlen( source_or_null ) + 1 : 0;
size_t target_size = strlen( target ) + 1;
//最后分配按照这个size,最后还包含了rtems_filesystem_global_location_t类型的size
size_t size = sizeof( rtems_filesystem_mount_table_entry_t )
+ filesystemtype_size + source_size + target_size
+ sizeof( rtems_filesystem_global_location_t );
rtems_filesystem_mount_table_entry_t *mt_entry = calloc( 1, size );
if ( mt_entry != NULL ) {
//这里就是将mt_fs_root变量指向刚分配的mt_entry地址偏移 sizeof( *mt_entry )的地方,也就是在
//rtems_filesystem_mount_table_entry_t类型后面的地方
rtems_filesystem_global_location_t *mt_fs_root =
(rtems_filesystem_global_location_t *)
((char *) mt_entry + sizeof( *mt_entry ));
//这一句是移动指针到后面
char *str = (char *) mt_fs_root + sizeof( *mt_fs_root );
memcpy( str, filesystemtype, filesystemtype_size );
mt_entry->type = str;
str += filesystemtype_size;
if ( source_or_null != NULL ) {
memcpy( str, source_or_null, source_size );
mt_entry->dev = str;
str += source_size;
}
memcpy( str, target, target_size );
mt_entry->target = str;
mt_entry->mounted = true;
mt_entry->mt_fs_root = mt_fs_root; //把后面分配的空间挂到mt_entry的指针上
mt_entry->pathconf_limits_and_options = &rtems_filesystem_default_pathconf;
mt_fs_root->location.mt_entry = mt_entry; //反过来,mt_entry也挂到mt_fs_root对应的地方。
mt_fs_root->reference_count = 1;
rtems_chain_initialize(
&mt_entry->location_chain,
mt_fs_root,
1,
sizeof(*mt_fs_root)
);
}
*target_length_ptr = target_size - 1;
return mt_entry;
}
这个函数还会返回target_length_ptr ,最后初始化一个链表。rtems_chain_initialize
接下来,调用rtems_filesystem_fsmount_me_t类型的函数。这个函数是上一篇中说的,从rtems_filesystem_table中找到的或者时chain中找到的函数 比如IMFS_initialize_support,应该是进行一些初始化的操作吧,
最后就是注册,根据是否是根文件系统进行区分为两种注册方式如下
1:register_root_file_system
2:register_subordinate_file_system
注册就是向chain中增加的过程。
最后说明一下IMFS_initialize。在cpukit/libfs/src/imfs/imfs_init.c中定义。 可见imfs相关的都在cpukit/libfs/src/imfs
中定义。因此我可以单独跟踪这整个初始化挂载imfs作为root文件系统的过程。