linux內核5.8中proc編程的學習
對著proc_fs.h的頭檔案,一點點學習
看到頭檔案里第一個結構體,/proc 目錄的操作結構體
struct proc_ops {
unsigned int proc_flags;
int (*proc_open)(struct inode *, struct file *);
ssize_t (*proc_read)(struct file *, char __user *, size_t, loff_t *);
ssize_t (*proc_write)(struct file *, const char __user *, size_t, loff_t *);
loff_t (*proc_lseek)(struct file *, loff_t, int);
int (*proc_release)(struct inode *, struct file *);
__poll_t (*proc_poll)(struct file *, struct poll_table_struct *);
long (*proc_ioctl)(struct file *, unsigned int, unsigned long);
#ifdef CONFIG_COMPAT
long (*proc_compat_ioctl)(struct file *, unsigned int, unsigned long);
#endif
int (*proc_mmap)(struct file *, struct vm_area_struct *);
unsigned long (*proc_get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
} __randomize_layout;
再看頭檔案中重要的函式
extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
struct proc_dir_entry *,
const struct proc_ops *,
void *);
好了寫下第一個demo
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h> /* copy_*_user */
#include <linux/slab.h>
int our_proc_open(struct inode *, struct file *);
ssize_t our_proc_read(struct file *, char __user *, size_t, loff_t *);
struct proc_ops ops = {
.proc_open = our_proc_open,
.proc_read = our_proc_read
};
int our_proc_open(struct inode *inode, struct file *file)
{
return 0;
};
ssize_t our_proc_read(struct file *file, char __user * buffer, size_t size, loff_t *off_t)
{
printk(KERN_ALERT "HELLO,our_proc_read\n");
return 0;
};
static int __init our_proc_init(void)
{
printk(KERN_ALERT "HELLO,KERNEL\n");
//掛載proc
proc_create_data("our_proc", 0644, NULL, &ops, NULL);
return 0;
}
static void __exit our_proc_exit(void)
{
printk(KERN_ALERT "HELLO,KERNEL BYE BYE\n");
remove_proc_entry("our_proc", NULL);
}
module_init(our_proc_init);
module_exit(our_proc_exit);
Makefile
obj-m:=proc.o
KERNELBUILD := /lib/modules/$(shell uname -r)/build
default:
make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
rm -rf *.o *.ko
執行命令
sudo make
sudo insmod proc.ko
sudo rmmod proc.ko
好了整個proc目錄崩了
ls /proc
電腦整個命令列崩潰,點擊關機按鈕,機器卡死,,,,,,
這是什么原因呢?引起了我的思考
vim prc_fs.h的頭檔案,我想我找到了原因
#define remove_proc_entry(name, parent) do {} while (0)
這個函式被注釋掉了,也就是說不再起作用了,然后在原始碼中找到了proc_remove 這個函式
但是看實作好像不會有作用,因為實作代碼中什么也沒有
static inline void proc_remove(struct proc_dir_entry *de) {}
然后再次修正demo
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h> /* copy_*_user */
#include <linux/slab.h>
#define MODULE_NAME "our_proc"
struct proc_dir_entry* proc_handle = NULL;
int our_proc_open(struct inode *, struct file *);
ssize_t our_proc_read(struct file *, char __user *, size_t, loff_t *);
struct proc_ops ops = {
.proc_open = our_proc_open,
.proc_read = our_proc_read
};
int our_proc_open(struct inode *inode, struct file *file)
{
return 0;
};
ssize_t our_proc_read(struct file *file, char __user * buffer, size_t size, loff_t *off_t)
{
printk(KERN_ALERT "HELLO,our_proc_read\n");
return 0;
};
static int __init our_proc_init(void)
{
printk(KERN_ALERT "HELLO,KERNEL\n");
//掛載proc
proc_handle = proc_create_data(MODULE_NAME, 0644, NULL, &ops, NULL);
return 0;
}
static void __exit our_proc_exit(void)
{
printk(KERN_ALERT "HELLO,KERNEL BYE BYE\n");
if (proc_handle) {
proc_remove(proc_handle);
}
}
module_init(our_proc_init);
module_exit(our_proc_exit);
再次執行命令
sudo make
sudo insmod proc.ko
cat /proc/our_proc
dmesg
在除錯的環形緩沖區中看到了
[ 1212.214871] HELLO,KERNEL
[ 1227.271966] HELLO,our_proc_read
[ 1250.484078] HELLO,KERNEL BYE BYE
[ 1305.898772] HELLO,KERNEL
[ 1342.722686] HELLO,KERNEL BYE BYE
[ 1649.965351] HELLO,KERNEL
[ 1656.079254] HELLO,our_proc_read
[ 1657.011422] HELLO,our_proc_read
卸載驅動
sudo rmmod proc.ko
看到/proc/our_proc沒了,一切恢復了正常
這就是proc新的函式api,主要是用來動態查詢驅動資訊的,當然我們呼叫
glibc 經典的api read write ioctl lseek等等都會觸發相應的鉤子
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/252242.html
標籤:其他
