关于文件系统,这确实是个大工程,前面对ramfs中的read,write之类的进行了,极为简略的分析,还是有点诚惶诚恐,觉得有必要再进行一次更为深入的分析。
好了,那就从最原始的start_kernel开始。(手上代码为2.6.19mips内核)
vfs_caches_init_early
void __init vfs_caches_init_early(void)
{
dcache_init_early();
inode_init_early();
}
这个代码的作用是
dentry_hashtable
[]
和
inode_hashtable
[]
初始化。
接下来是最最重要的vfs_caches_init
void __init vfs_caches_init(unsigned long mempages)
{
unsigned long reserve;
/* Base hash sizes on available memory, with a reserve equal to
150% of current kernel size */
reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);
mempages -= reserve;
names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
dcache_init(mempages); //dentry_cache初始化
inode_init(mempages); //inode
files_init(mempages); //file,包括max和fdt
mnt_init(mempages); //sysfs 、rootfs初始化
bdev_cache_init(); //块设备描述符
chrdev_init(); //字符设备描述符
}
dcache_init 初始化dentry_cache,dentry_hashtable[]
inode_init 初始化indoe_cache,inode_hashtable[]
files_init 初始化fdtable_defer_list,files_stat.max_files
mnt_init 重头戏,这里初始化了sysfs和vfs
void __init mnt_init(unsigned long mempages)
{
struct list_head *d;
unsigned int nr_hash;
int i;
int err;
init_rwsem(&namespace_sem);
mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL, NULL);
mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);
if (!mount_hashtable)
panic("Failed to allocate mount hash table\n");
/*
* Find the power-of-two list-heads that can fit into the allocation..
* We don't guarantee that "sizeof(struct list_head)" is necessarily
* a power-of-two.
*/
nr_hash = PAGE_SIZE / sizeof(struct list_head);
hash_bits = 0;
do {
hash_bits++;
} while ((nr_hash >> hash_bits) != 0);
hash_bits--;//有多少位
/*
* Re-calculate the actual number of entries and the mask
* from the number of bits we can fit.
*/
nr_hash = 1UL << hash_bits; //对齐,大小可以被一页整除
hash_mask = nr_hash - 1;
printk("Mount-cache hash table entries: %d\n", nr_hash);
/* And initialize the newly allocated array */
d = mount_hashtable;
i = nr_hash;
do {
INIT_LIST_HEAD(d);
d++;
i--;
} while (i); //初始化一页中所有的链表,所有的mount_hashtable
err = sysfs_init(); //初始化sysfs,sysmount这个全局参数
if (err)
printk(KERN_WARNING "%s: sysfs_init error: %d\n",
__FUNCTION__, err);
err = subsystem_register(&fs_subsys); //sys/fs,注册子系统
if (err)
printk(KERN_WARNING "%s: subsystem_register error: %d\n",
__FUNCTION__, err);
init_rootfs(); //注册rootfs文件系统,rootfs注册至file_systems
init_mount_tree(); //初始化rootfs,其实就是vfs
}