Skip to content

Instantly share code, notes, and snippets.

@knknkn1162
Last active May 10, 2019 04:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knknkn1162/c48cb5b2023276100dc3cfed7aa84954 to your computer and use it in GitHub Desktop.
Save knknkn1162/c48cb5b2023276100dc3cfed7aa84954 to your computer and use it in GitHub Desktop.
How to configure special root filesystem on boot( c.f) Understanding the Linux Kernel 2.6.11)
# start_kernel() -> vfs_caches_init() -> mnt_init() -> init_rootfs, init_mount_tree の中身
- init_rootfs(): register_filesystem(&rootfs_fs_type); append (struct file_system)rootfs_fs_type global variable to (struct file_system*)file_systems.
- find_filesystem("rootfs") and return the end of `(struct file_system*)file_systems`
- append (struct file_system)rootfs_fs_type to the previous result
- init_mount_tree: create `struct vfsmount` element
- vfsmount = do_kern_mount(fstype="rootfs", flags=0, name="rootfs", data=NULL)
- get_fs_type("rootfs"): get (struct file_system*)rootfs_fs_type
- vfsmount = alloc_vfsmnt("rootfs"): allocate&initialize `struct vfsmount` element
- vfsmount = kmem_cache_alloc(mnt_cache, GFP_KERNEL): allocate `struct vfsmount`
- initialize vfsmount->mnt_list: (later, link to `namespace.list` as the head)
- mnt->mnt_devname = "rootfs"
- super_block = type->get_sb(type, flags, name, data): (=rootfs_get_sb) allocate&configure `struct super_block` element
- get_sb_nodev(rootfs_fs_type, MS_NOUSER, NULL, ramfs_fill_super):
- super_block = sget(rootfs_fs_type, NULL, set_anon_super, NULL): alloc & configure`struct super_block`.
- super_block = alloc_super(): allocate and initialize `struct super_block`
- super_block = kmalloc(sizeof(struct super_block), GFP_USER): allocate `struct super_block`
- initialize super_block->s_(files|instances|inodes|anon) and so on
- set_anon_super(super_block, data: void*): fill in super_block->s_dev(device number).
- idr_pre_get(&unnamed_dev_idr, GFP_ATOMIC): unnamed_dev_idr is `struct idr`
- idr_layer = kmem_cache_alloc(idr_layer_cache, GFP_ATOMIC);
- free_layer(unnamed_dev_idr, idr_layer): link idr_layer to unnamed_dev_idr
- idr_get_new(&unnamed_dev_idr, NULL, &dev): get newid and put it in dev
- idr_get_new_above_int(unnamed_dev_idr, ptr, 0)
- unnamed_dev_idr->top = alloc_layer(unnamed_dev_idr)
- newid = sub_alloc(unnamed_dev_idr, NULL, &0): get unique id
- super_block->s_dev = MKDEV(major=0, minor=(dev & 0xFFF));
- super_block->s_type = rootfs_fs_type;
- list_add_tail(&super_block->s_list, &super_blocks); (struct list_head)super_blocks
- list_add(&super_block->s_instances, &rootfs_fs_type->fs_supers);
- ramfs_fill_super(super_block, (void*)data=NULL, (int)silent=0): (silent is not used)
- root_inode = ramfs_get_inode(super_block, S_IFDIR | 0755, 0): allocate & initialize `struct inode`
- root_inode = alloc_inode(super_block);
- root_inode = (struct inode *)kmem_cache_alloc(inode_cachep, SLAB_KERNEL);
- INIT_LIST_HEAD(&root_inode->i_dentry); && INIT_HLIST_NODE(&root_inode->i_hash): exec init_once() -> inode_init_once() as ctor
- root_inode->i_sb = super_block;
- root_inode->i_mapping = root_inode->i_data: root_inode->i_data is `struct address_space` object and initialize
- initialize inode object
- list_add(&root_inode->i_list, &inode_in_use);
- list_add(&root_inode->i_sb_list, &sb->s_inodes);
- struct dentry* dentry_root = d_alloc_root(root_inode): allocate & initialize `struct dentry`
- dentry_root = d_alloc(NULL, &name="/"):
- dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL):
- initialize dentry->(d_inode|d_parent|d_sb|d_hash|d_lru|d_subdirs|d_alias|dentry_child)
- dentry_root->d_sb = root_inode->i_sb(=super_block) && dentry_root->d_parent=dentry_root
- d_instantiate(dentry_root, root_inode):
- list_add(&dentry->d_alias, &inode->i_dentry): d_alias is “in use” dentry object
- entry->d_inode = root_inode: d_inode is "unused" dentry object
- super_block->s_root = (struct dentry*)root: (later, link to `vfsmount->mnt_root` which is the root directory of the filesystem)
- vfsmount->mnt_(sb|root|mount_point) = (super_block|super_block->s_root|super_block->s_root)
- vfsmount->mnt_namespace = init_task->namespace;
- namespace = kmalloc(sizeof(*namespace), GFP_KERNEL): alloc element of `struct namespace`
- link between vfsmount(root_mount) and namespace
- (struct task_struct)(init_task).namespace = namespace;
- (struct vfsmount)current->fs->pwdmnt = namespace->root
- (struct dentry)current->fs->pwd = namespace->root->mnt_root
@knknkn1162
Copy link
Author

This is a overview image!

IMG_0127

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment