staticint__init init(void)
mm_segment_t old_fs;
printk("Hello, I'm the module that intends to write messages to file.\n");

printk("error occured while opening file %s, exiting...\n",MY_FILE);

sprintf(buf,"%s","The Messages.");



staticvoid__exit fini(void)


among :



basic thought :
One is to remember to add -D__KERNEL_SYSCALLS__
In addition, the source file should #include <linux/unistd.h>

If the report is wrong , Most likely because the buffer used exceeds the address range of the user space . General system calls require that the buffer you use should not be in the kernel . This can be used set_fs(),get_fs() To solve the problem . Get current before reading and writing files fs:
mm_segment_t old_fs=get_fs();
And set the current fs Is the kernel fs:set_fs(KERNEL_DS);
Restore the original file after reading and writing fs: set_fs(old_fs);
set_fs(),get_fs() Wait for related macro in file include/asm/uaccess.h Defined in .
Personally, this method is relatively simple .

The other is to use flip_open Function to open a file , obtain struct file
* Pointer to fp. Use pointer fp Carry out corresponding operations , For example, it can be used to read documents fp->f_ops->read. Last use filp_close() Function close file .
filp_open(),filp_close() Function in fs/open.c definition , stay include/linux/fs.h Statement in .

Explain a little :
system Unified calling is originally provided for program access in user space , therefore , For the parameters passed to it ( Like the one above buf), By default, it will be considered from user space , stay ->write() In function ,
To protect kernel space , Generally used get_fs() The resulting value is the sum of USER_DS Compare , To prevent user space programs “ deliberate ” Destroy kernel space ;

Now you need to use system calls in kernel space , Pass to ->write() The parameter address of is the address of kernel space , stay USER_DS above (USER_DS ~
KERNEL_DS), If you don't do anything else , stay write() In function , It will be considered that the address exceeds USER_DS Range , So it's user space “ Sabotage ”, from
And no further execution is allowed ; To solve this problem ;
set_fs(KERNEL_DS); Expand the space limit it can access to KERNEL_DS, In this way, system calls can be used smoothly in the kernel !

supplement :
I took a look at the source code , stay include/asm/uaccess.h in , There are the following definitions :
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define get_ds() (KERNEL_DS)
#define get_fs() (current->addr_limit)
#define set_fs(x) (current->addr_limit = (x))

And its notes are clear :
* The fs value determines whether argument validity checking should be
* performed or not. If get_fs() == USER_DS, checking is performed, with
* get_fs() == KERNEL_DS, checking is bypassed.
* For historical reasons, these macros are grossly misnamed.

So you can see ,fs The value of is used as a flag for parameter checking . Parameter requirements for system calls must come from user space , therefore , When using system calls in the kernel ,set_fs(get_ds()) Change the user space limit , That is, expand the user space , So you can use the parameters in the kernel .

©2019-2020 Toolsou All rights reserved,
First knowledge python Skills summary GDOI2019 travels c Linguistic 5 Three common sorting methods Python Basic knowledge and notes " Cephalosporin wine Say go and go "? DANGER ! Don't drink alcohol when taking these drugs Thorough explanation from Zhongtai vue The component page height is adaptive according to the screen size Classical algorithm - recursion ( The case of raw rabbit ) Big data tells you , How tired are Chinese women about keras use fit_generator Encountered in StopIteration