From http://z515256164.blog.163.com/blog/static/32443029201211362335184/
With the support of VFS, user-State processes can use read and write to read and write file systems of any type, but how can we operate files without such a system calling in the Linux kernel? We know that when read and write are in the kernel state, sys_read and sys_write are actually executed. However, when we look at the kernel source code, we find that the functions of these operation files are not exported (exported using EXPORT_SYMBOL ), that is to say, it cannot be used in the kernel module. How can this problem be solved?
Through viewing the source code of sys_open, we found that it mainly uses the do_filp_open () function, which is in fs/namei. c, and in the modified file, the filp_open function also calls the do_filp_open function, and the interface is very similar to the sys_open function. The call parameters are the same as those of sys_open, and EXPORT_SYMBOL is used to export the function, so we guess this function can open a file, which is the same as open. Using the same search method, we found a group of functions that operate files in the kernel, as shown below:
Function prototype
Open the file struct file * filp_open (const char * filename, int flags, int mode)
Read file ssize_t vfs_read (struct file * file, char _ user * buf, size_t count, loff_t * pos)
Write file ssize_t vfs_write (struct file * file, const char _ user * buf, size_t count, loff_t * pos)
Close file int filp_close (struct file * filp, fl_owner_t id)
We noticed that in the vfs_read and vfs_write functions, the buf parameter points to the memory address of the user space. If we use the pointer of the kernel space directly,-EFALUT is returned. So we need to use
Set_fs () and get_fs () macros are used to change the kernel's processing method for memory address check. Therefore, the file read/write process in the kernel space is as follows:
Mm_segment_t fs = get_fs ();
Set_fs (KERNEL_FS );
// Vfs_write ();
Vfs_read ();
Set_fs (fs );
The following is an example of file operations in the kernel:
# Include
# Include
# Include
# Include
Static char buf [] = "hello ";
Static char buf1 [10];
Int _ init hello_init (void)
{
Struct file * fp;
Mm_segment_t fs;
Loff_t pos;
Printk ("hello enter \ n ");
Fp = filp_open ("/home/niutao/kernel_file", O_RDWR | O_CREAT, 0644 );
If (IS_ERR (fp )){
Printk ("create file error \ n ");
Return-1;
}
Fs = get_fs ();
Set_fs (KERNEL_DS );
Pos = 0;
Vfs_write (fp, buf, sizeof (buf), & pos );
Pos = 0;
Vfs_read (fp, buf1, sizeof (buf), & pos );
Printk ("read: % s \ n", buf1 );
Filp_close (fp, NULL );
Set_fs (fs );
Return 0;
}
Void _ exit hello_exit (void)
{
Printk ("hello exit \ n ");
}
Module_init (hello_init );
Module_exit (hello_exit );
MODULE_LICENSE ("GPL ");