Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to initialize virtual file system based on linux

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.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report