Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

This part of the project involves modifying the kernel module so that it uses th

ID: 3877455 • Letter: T

Question

This part of the project involves modifying the kernel module so that it uses the kernel linked-list data structure. In Section 1.10, we covered various data structures that are common in operating systems (At the bottom of this document).The Linux kernel provides several of these structures.Here, we explore using the circular, doubly linked list that is available to kernel developers. Much of what we discuss is available in the Linux source code— in this instance, the include le <linux/list.h>—and we recommend that you examine this le as you proceed through the following steps. Initially, you must dene a struct containing the elements that are to be inserted in the linked list.The following C struct denes birthdays:

struct birthday {

int day;

int month;

int year;

struct list_head list;

}

Notice the member struct list head list. The list head structure is dened in the include le <linux/types.h>. Its intention is to embed the linked lis twithin the nodesthat comprise the list.This list head structure is quite simple—it merely holds two members, next and prev,that point to the next and previous entries in the list. By embedding the linked list within the structure,Linux makes it possible to manage the data structure with a series of macro functions.


Inserting Elements into the Linked List
We can declare a list head object,which we use as a reference to the head of the list by using the LIST_HEAD() macro
static LIST_HEAD(birthday list);
This macro denes and initializes the variable birthday list,which is of type struct list head.
We create and initialize instances of struct birthday as follows:
struct birthday *person;
person = kmalloc(sizeof(*person), GFP KERNEL);

person->day = 2;

person->month= 8;

person->year = 1995;

INIT LIST_HEAD(&person->list);
The kmalloc() function is the kernel equivalent of the user-level malloc() function for allocating memory,except that kernel memory is being allocated. (TheGFP KERNELag indicates routine kernel memory allocation.)The macro INIT LIST HEAD() initializes the list member in struct birthday.Wecan then add this instance to the end of the linked list using the list add tail() macro:
list_add_tail(&person->list, &birthday list);
Traversing the LinkedList
Traversing the list involves using the list_for_each_entry() Macro, which accepts three parameters:

• A pointer to the structure being iterated over

• A pointer to the head of the list being iterated over

• The name of the variable containing the list head structure
Thefollowingcode illustrates this macro:
struct birthday *ptr;

list_for_each_entry(ptr, &birthday list, list) {

/* on each iteration ptr points */

/* to the next birthday struct */

}

Removing Elements from the Linked List
Removing elements from the list involves using the list_del() macro,which is passed a pointer to struct list_head
list_del(struct list_head *element)
This removes element from the list while maintaining the structure of the remainder of the list. Perhaps the simplest approach for removing all elements from a linked list is to remove each element as you traverse the list. The macro list for each entry safe() behaves much like list for each entry()
except that it is passed an additional argument that maintains the value of the next pointer of the item being deleted. (This is necessary for preserving the structure of the list.)

The following code example illustrates this macro:
struct birthday *ptr, *next

list_for_each_entry_safe(ptr,next,&birthday list,list) {

/* on each iteration ptr points */

/* to the next birthday struct */

list del(&ptr->list);

kfree(ptr);

}

Notice that after deleting each element,were turn memory that was previously allocated with kmalloc() back to the kernel with the call to kfree(). Careful memory management—which includes releasing memory to prevent memory leaks—is crucial when developing kernel-level code.


Part II Assignment
In the module entry point,create a linked list containing ve struct birthday elements.Traverse the linked list and output its contents to the kernel log buffer. Invoke the dmesg command to ensure the list is properly constructed once the kernel module has been loaded. In the module exit point,delete the elements from the linked list and return the free memory back to the kernel.Again, invoke the dmesg command to check that the list has been removed once the kernel module has been unloaded.

Kernel module simple.c

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/module.h>

/* This function is called when the module is loaded. */

int simple init(void) {

printk(KERN INFO "Loading Module ");

return 0;

}

/* This function is called when the module is removed. */

void simple exit(void) {

printk(KERN INFO "Removing Module ");

}

/* 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")

Explanation / Answer

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>

#define NUM_OF_PERSON 5

/* Example struct we will use. */
typedef struct _birthday {
int day;
int month;
int year;
struct list_head list;
}birthday;

/* Declare and init the head of the linked list. */
LIST_HEAD(birthday_list);

/* This function is called when the module is loaded. */
int List_init(void)
{
printk(KERN_INFO “Loading Module ”);

/* Allocate 5 birthdays from kernel */
birthday *person;
int i = 0;
for(i = 0; i < NUM_OF_PERSON; i++)
{
/* Request malloc to the kernel. */
person = kmalloc(sizeof(*person), GFP_KERNEL);
/* Assign value to the struct. */
person->day = i+1;
person->month = i+1;
person->year = i+1;
/* Init the list within the struct. */
INIT_LIST_HEAD(&person->list);
/* Add this struct to the tail of the list. */
list_add_tail(&person->list, &birthday_list);
}

printk(KERN_INFO “Display the list: ”);

/* Go thru the list and print. */
birthday *ptr;
list_for_each_entry(ptr, &birthday_list, list)
{
printk(KERN_INFO “day: %d, month: %d, year: %d ”,
ptr->day,
ptr->month,
ptr->year);
}

printk(KERN_INFO “Display done ”);

return 0;
}

/* This function is called when the module is removed. */
void List_exit(void)
{
printk(KERN_INFO “Removing Module ”);

/* Go thru the list and free the memory. */
birthday *ptr, *next;
list_for_each_entry_safe(ptr, next, &birthday_list, list)
{
printk(KERN_INFO “Removing – day: %d, month: %d, year: %d ”,
ptr->day,
ptr->month,
ptr->year);
list_del(&ptr->list);
kfree(ptr);
}

printk(KERN_INFO “Memory free done ”);
}

/* Macros for registering module entry and exit points. */
module_init( List_init );
module_exit( List_exit );

MODULE_LICENSE(“GPL”);
MODULE_DESCRIPTION(“BirthdayList Module”);
MODULE_AUTHOR(“daveti”);

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote