The common debugging methods of kernel include JTAG, printk, Proc, sys, debugfile... for these comparison preparations, I will write a special one. Here I will mainly introduce the debugging methods of Proc.
The/proc file system is a special file system created by the software. The kernel uses it to export information to the outside world. Each file under/proc is bound with a kernel function. When you read the file, the function dynamically generates the "content" of the file ".
This actually gives us a function interface. In this interface, we can call the driver function written by ourselves at the underlying layer, and add the desired printing in it. With this interface, we can output the median generated by the driver running and local variables for debugging. Its disadvantage is that there are already a large number of files, and the file printing function that cannot be called too large must be written into the driver to be debugged. Comparing and generating these shortcomings, the debugging method still has value. After all, an interface for upper-and lower-layer connections is provided.
Proc defines read/write functions and register functions, which are global.
INT (* read_proc) (char * Page, char ** start, off_t offset, int count,
Int * EOF, void * data );
Parameter description:
Page: the buffer used to write data. That is to say, all data read from the/proc file is written to the buffer pointed to by page.
Start: Specifies the location of the Memory Page to which the actual data is written to the page.
Offset: The value is the same as that in the read parameter.
Count: the parameter in the READ function has the same meaning.
EOF: when no data is returned, you must set this parameter to an integer, for example, * EOF = 1;
Data: this parameter is a dedicated pointer provided by the kernel to the driver and can be used for internal record
* Function for creating read-only/proc files
Struct proc_dir_entry * create_proc_read_entry (const char * Name,
Mode_t mode, struct proc_dir_entry * base,
Read_proc_t * read_proc, void * Data)
Parameter description:
Name: name of the file under/proc to be created
Mode: the mask of the created File Permission. If it is 0, the default permission is used.
Base: the parent directory of the file. If this parameter is set to null, the file will be created under the root directory of/proc.
Read_proc: The function called when reading files under/proc, that is, the function described above.
Data: The kernel ignores data, but passes this parameter to the read_proc function.
Delete functions of/proc system files
Void remove_proc_entry (const char * Name, struct proc_dir_entry * parent)
Parameter description:
Name: file name created in the/proc file system
Parent: parent directory name
By referring to the above introduction, we can see that we have created our own proc/proc_test.
// Test proc
# Include <Linux/module. h>
# Include <Linux/kernel. h>
# Include <Linux/proc_fs.h>
Int proc_read_memory_drv (char * Page, char ** start, off_t off, int count,
Int * EOF, void * data );
Void memory_drv_exit (void );
Int memory_drv_init (void );
Module_init (memory_drv_init );
Module_exit (memory_drv_exit );
Struct proc_dir_entry * memory_drv_file;
Int proc_read_memory_drv (char * Page, char ** start, off_t off, int count,
Int * EOF, void * Data)
{
Int Len;
Len = sprintf (page, "test OK ");
Return Len;
}
Int memory_drv_init (void)
{
Memory_drv_file = create_proc_entry ("proc_test", s_irugo, null );
Memory_drv_file-> read_proc = proc_read_memory_drv;
Return 0;
}
Void memory_drv_exit (void)
{
Remove_proc_entry ("proc_test", null );
}
This completes the creation of the proc/proc_test file.
In this way, we can add it to the driver file we want to debug.
Then enter rootfs
Enter proc
CD proc
List objects
Ll
You can see proc_test
Cat proc_test
The printed content is displayed.
Test OK
The driver is loaded to the proc file.