-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathlinux_kernel_linked_list.c
77 lines (73 loc) · 2.6 KB
/
linux_kernel_linked_list.c
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
/* NOTE: Makefile contains "make" to compile */
#include <linux/list.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#define BIRTHDAYS_NUM 5
/* Define the birthday struct below */
struct birthday {
int day;
int month;
int year;
struct list_head list;
};
/* LIST_HEAD is defined in list.h. We declare and initialize linked list head below. */
LIST_HEAD(birthday_list);
/* Function 1 - main function that loads birthdays*/
int load_birthdays(void){
/* Allocate memory for 5 birthday elements in the linked list */
struct birthday *person;
int i = 0;
for(i = 0; i < BIRTHDAYS_NUM; i++){
/* kmalloc is the normal method of allocating memory in the kernel. slab.h is needed to use kmalloc. GFP_KERNEL allocates normal kernel ram. */
person = kmalloc(sizeof(*person), GFP_KERNEL);
person->day = 2 + i;
person->month = 7 + i;
person->year = 1995 + i;
/* INIT_LIST_HEAD is from list.h */
INIT_LIST_HEAD(&person->list);
list_add_tail(&person->list, &birthday_list);
}
/* Traverse linked list and print each birthday to the kernel log */
// birthday *person;
// list_for_each_entry is from list.h and it iterates over a list of given type
list_for_each_entry(person, &birthday_list, list) {
printk(KERN_INFO "Birthday: %d/%d/%d\n", person->month, person->day, person->year);
}
return 0;
}
/* Function 2 - called when the module is loaded */
int simple_init(void) {
printk(KERN_INFO "Loading Module\n");
// Call main function that loads birthdays
load_birthdays();
return 0;
}
/////////////////////////////
/* Function 3 - main function to delete linked list from kernel memory */
int remove_birthdays(void) {
/* Traverse the linked list and delete its elements. */
struct birthday *ptr, *next;
// list_for_each_entry_safe is from list.h and it iterates over list of given type safe against removal of list entry
list_for_each_entry_safe(ptr, next, &birthday_list, list) {
printk(KERN_INFO "Removing Birthday: %d/%d/%d\n", ptr->month, ptr->day, ptr->year);
list_del(&ptr->list);
kfree(ptr);
}
return 0;
}
/* Function 4 - called when the module is removed */
void simple_exit(void) {
printk(KERN_INFO "Removing module\n");
remove_birthdays();
printk(KERN_INFO "Freed memory\n");
}
/////////////////////////////
/* Macros for registering module entry and exit points */
module_init(simple_init);
module_exit(simple_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("SGG");