summaryrefslogtreecommitdiffstats
path: root/md/notes/kernel/create_procfs_entry.md
blob: 03d186f0d11753256c6a8bb9f56e5a7c778acf74 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
title:Create procfs entry
keywords:kernel,linux,threads

# Create procfs entry

Lets extend hello world driver. 


__Makefile__
```Makefile
obj-m += procfs_entry.o

KDIR ?= /lib/modules/$(shell uname -r)/build

all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	make -C $(KDIR) M=$(PWD) clean
```

__procfs_entry.c__
```c
#include <linux/module.h>  /* Needed by all modules */
#include <linux/kernel.h>

int procfs_entry_init( void )
{
	printk(KERN_DEBUG "Hello Procfs!\n");
	return 0;
}

void procfs_entry_exit( void )
{
	printk(KERN_DEBUG "Exit Procfs!\n");
}

module_init( procfs_entry_init );
module_exit( procfs_entry_exit );

MODULE_LICENSE("GPL");
```


Create proc directory with

```c
dir = proc_mkdir(DIR_NAME, PARENT_DIR);
```

under the directory create file that will contain data

```c
proc_create("file", MODE, PARENT_DIR, PROC_FOPS)
```

Lets create /proc/secret/file. And define basic read/write operations. That at this 
stage will do nothing.

```c
#include <linux/proc_fs.h>

static struct proc_dir_entry *procdir, *procfile;

static int secret_open(struct inode *inode, struct file *file) {
        return 0;
}

static int secret_release(struct inode *inode, struct file *file) {
        return 0;
}

static ssize_t secret_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) {
        return 0;
}

static ssize_t secret_write(struct file *file, const char *buffer, size_t length, loff_t *offset) {
        return 0;
}

static struct proc_ops procfs_ops = {
        .proc_open = secret_open,
        .proc_read = secret_read,
        .proc_write = secret_write,
        .proc_release = secret_release
};


int procfs_entry_init( void ) {
...
procdir = proc_mkdir("secret", NULL);
if (procdir == NULL) {
	pr_err("Cant create secret directory\n");
	return -1;
}

procfile = proc_create("file", 0644, procdir, &procfs_ops);
if (procfile == NULL) {
	pr_err("Cant create file under the secret\n");
	return -1;
}
...
}

void procfs_entry_exit( void )
{
	...
	//remove entries after unloading module
	proc_remove(procdir);
	proc_remove(procfile);
	...
}
```

Next step add data to read from file entry




## List of procfs functions used

| Function name | Note |
|---|---|
| proc_mkdir | Create procfs directory |
| proc_create | Create procfs file |
| proc_remove | Remove procfs entry |

## Final result

__Makefile__
```Makefile
```

__procfs_entry.c__
```c
```

## Links

https://elixir.bootlin.com/linux/v6.1.21/source/include/linux/proc_fs.h