In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "how to realize virtual file system initialization based on linux score". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to initialize the virtual file system based on linux.
From the main function to the initialization of the virtual file system, the path is init ()-> setup ()-> syssetup (); sys_setup mainly registers all the file systems under the virtual file system. Then mount the root file system. Here is the initialization code.
Asmlinkage int sys_setup (void)
{
Static int callable = 1
If (! callable)
Return-1
Callable = 0
Device_setup ()
# ifdef CONFIG_MINIX_FS
Register_filesystem (& (struct file_system_type))
{minix_read_super, "minix", 1, NULL})
# endif
# ifdef CONFIG_EXT_FS
Register_filesystem (& (struct file_system_type))
{ext_read_super, "ext", 1, NULL})
# endif
.
Mount_root ()
}
Let's take a look at the basic data structure.
Struct file_system_type {
Struct super_block * (* read_super) (struct super_block *, void *, int)
Char * name
Int requires_dev
Struct file_system_type * next
}
This is the representation structure of a specific file system when it is registered with a virtual file system. Then take a look at the function that registers the file system.
Int register_filesystem (struct file_system_type * fs)
{
Struct file_system_type * * tmp
If (! fs)
Return-EINVAL
If (fs- > next)
Return-EBUSY
/ / tmp is a secondary pointer to the address of the header pointer of the file system linked list
Tmp = & file_systems
/ / iterate through the linked list until the tail, and insert a new node
While (* tmp) {
/ / determine whether the file system has been registered
If (strcmp ((* tmp)-> name, fs- > name) = 0)
Return-EBUSY
/ / points to the address of the next field of the current node, and * tmp gets the next node to be compared.
Tmp = & (* tmp)-> next
}
/ / use the secondary pointer to modify the contents of the next field without using the form-> next = fs
* tmp = fs
Return 0
}
Is to insert a file_system_type structure into a linked list. Registering the file system is really just building a single linked list. Then take a look at mounting the root file system. Here is a general analysis of the process. We'll talk more about it when we have time.
Void mount_root (void)
{
Struct file_system_type * fs_type
Struct super_block * sb
Struct inode * inode, d_inode
Struct file filp
Int retval
/ / empty the array of super blocks
Memset (super_blocks, 0, sizeof (super_blocks))
# ifdef CONFIG_BLK_DEV_FD
If (MAJOR (ROOT_DEV) = = FLOPPY_MAJOR) {
Printk (KERN_NOTICE "VFS: Insert root floppy and press ENTER\ n")
Wait_for_keypress ()
}
# endif
Memset (& filp, 0, sizeof (filp))
Memset (& d_inode, 0, sizeof (d_inode))
/ / Root device number
D_inode.i_rdev = ROOT_DEV
Filp.f_inode = & d_inode
/ / Mount read-only
If (root_mountflags & MS_RDONLY)
Filp.f_mode = 1; / * read only * /
Else
Filp.f_mode = 3; / * read write * /
/ / ignore temporarily
Retval = blkdev_open (& d_inode, & filp)
If (retval = =-EROFS) {
Root_mountflags | = MS_RDONLY
Filp.f_mode = 1
Retval = blkdev_open (& d_inode, & filp)
}
For (fs_type = file_systems; fs_type; fs_type = fs_type- > next) {
If (retval)
Break
/ / if it is not associated with a device, it does not need to be executed further. Some file systems do not have a corresponding underlying device.
If (! fs_type- > requires_dev)
Continue
/ / read the super block of the root device. The first sector of the device is the partition table, followed by the super block.
Sb = read_super (ROOT_DEV,fs_type- > name,root_mountflags,NULL,1)
/ / read successfully
If (sb) {
/ / Root node
Inode = sb- > s_mounted
Inode- > i_count + = 3; / * NOTE! It is logically used 4 times, not 1 * /
Sb- > s_covered = inode
Sb- > s_flags = root_mountflags
/ / the root directory and working directory of the current process (init process) are set as the root node
Current- > fs- > pwd = inode
Current- > fs- > root = inode
Printk ("VFS: Mounted root (% s filesystem)% s.\ n"
Fs_type- > name
(sb- > s_flags & MS_RDONLY)? "readonly": ")
/ / return directly, that is, the first file system read successfully becomes the root file system
Return
}
}
Panic ("VFS: Unable to mount root fs on XRX"
MAJOR (ROOT_DEV), MINOR (ROOT_DEV))
}
Reads the super block contents of the root device and, if successful, becomes the root file system. And set the working directory and root directory of the current init process to be the inode corresponding to the root node of the root file system. Let's see how to read the super block.
/ / read the super block corresponding to the device
Static struct super_block * read_super (dev_t dev,char * name,int flags
Void * data, int silent)
{
Struct super_block * s
Struct file_system_type * type
If (! dev)
Return NULL
Check_disk_change (dev)
/ / return directly if yes, but not yet at initialization
S = get_super (dev)
If (s)
Return s
/ / otherwise, according to name, find the corresponding file system node in the file system linked list (established during system initialization), in which there is a read_super function
If (! (type = get_fs_type (name) {
Printk ("VFS: on device% dash% d: get_fs_type (% s) failed\ n"
MAJOR (dev), MINOR (dev), name)
Return NULL
}
/ / find a slot in the super block array
For (s = 0+super_blocks;; swarm +) {
If (s > = NR_SUPER+super_blocks)
Return NULL
If (! s-> s_dev)
Break
}
/ / Fields assigned to the super block node
S-> s_dev = dev
S-> s_flags = flags
/ / call the underlying file system to the hard disk to read super block content, such as ext file system, ext2 file system and so on.
If (! type- > read_super (silent data, silent) {
S-> s_dev = 0
Return NULL
}
S-> s_dev = dev
S-> s_covered = NULL
S-> s_rd_only = 0
S-> s_dirt = 0
S-> s_type = type
Return s
}
The main thing is to get a super block structure, and then call the read_super of the underlying file system. Then set the properties of the super block. Here's a look at the read_super of the ext file system.
Struct super_block * ext_read_super (struct super_block * sjade void * data
Int silent)
{
Struct buffer_head * bh
Struct ext_super_block * es
Int dev = s-> swarms devign block
Lock_super (s)
Set_blocksize (dev, BLOCK_SIZE)
/ / read the contents of the device, that is, the contents of the super block
If (! (bh = bread (dev, 1, BLOCK_SIZE)) {
S-> s_dev=0
Unlock_super (s)
Printk ("EXT-fs: unable to read superblock\ n")
Return NULL
}
/ / some properties of file system
Es = (struct ext_super_block *) bh- > b_data
S-> s_blocksize = 1024
S-> s_blocksize_bits = 10
S-> u.ext_sb.s_ninodes = es- > s_ninodes
S-> u.ext_sb.s_nzones = es- > s_nzones
S-> u.ext_sb.s_firstdatazone = es- > s_firstdatazone
S-> u.ext_sb.s_log_zone_size = es- > s_log_zone_size
S-> u.ext_sb.s_max_size = es- > s_max_size
S-> s_magic = es- > s_magic
S-> u.ext_sb.s_firstfreeblocknumber = es- > s_firstfreeblock
S-> u.ext_sb.s_freeblockscount = es- > s_freeblockscount
S-> u.ext_sb.s_firstfreeinodenumber = es- > s_firstfreeinode
S-> u.ext_sb.s_freeinodescount = es- > s_freeinodescount
Brelse (bh)
If (s-> s_magic! = EXT_SUPER_MAGIC) {
S-> s_dev = 0
Unlock_super (s)
If (! silent)
Printk ("VFS: Can't find an extfs filesystem on dev 0xx.\ n"
Dev)
Return NULL
}
If (! s-> u.ext_sb.s_firstfreeblocknumber)
S-> u.ext_sb.s_firstfreeblock = NULL
Else
If (! (s-> u.ext_sb.s_firstfreeblock = bread (dev)
S-> u.ext_sb.s_firstfreeblocknumber, BLOCK_SIZE)) {
Printk ("ext_read_super: unable to read first free block\ n")
S-> s_dev = 0
Unlock_super (s)
Return NULL
}
If (! s-> u.ext_sb.s_firstfreeinodenumber)
S-> u.ext_sb.s_firstfreeinodeblock = NULL
Else {
Block = 2 + (s-> u.ext_sb.s_firstfreeinodenumber-1) / EXT_INODES_PER_BLOCK
If (! (s-> u.ext_sb.s_firstfreeinodeblock = bread (dev, block, BLOCK_SIZE)) {
Printk ("ext_read_super: unable to read first free inode block\ n")
Brelse (s-> u.ext_sb.s_firstfreeblock)
S-> s_dev = 0
Unlock_super (s)
Return NULL
}
}
Unlock_super (s)
/ * set up enough so that it can read an inode * /
S-> s_dev = dev
/ / set of operation functions
S-> s_op = & ext_sops
/ / read the root node
If (! (s-> s_mounted = iget (smenade Extensible ROOTIMINO)) {
S-> s_dev=0
Printk ("EXT-fs: get root inode failed\ n")
Return NULL
}
Return s
}
The main work is to read the super block information of the hard disk to memory, and finally read the inode corresponding to the root node.
At this point, I believe you have a deeper understanding of "how to achieve virtual file system initialization based on linux". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.