Learning Objectives • Practice writing and using kernel modules on the Linux operating system • Practice utilizing command-line utilities to observe the actions and status of kernel modules • Review the common operating system data structure circular double-linked list Assignment Description Part 1 The first task is to implement the Kernel Data Structures assignment on page 99-101 of the textbook using the Linux include files, macros, and sample code provided as a reference. You should output to the kernel module a simple statement of ‘Adding Birthday Day:# Month:# Year:#’ each time you create a new node on the linked list. The # should be the same as what is in the example figure below. Ensure that your code is working properly by checking the contents of the kernel buffer for the appropriate output messages. When deleting the nodes from the linked list you should similarly output a message for each deleted node of ‘Deleting Birthday Day:# Month:# Year:#’. For deleting the elements from the list, you should do this in reverse order, instead of the way the book does it. See the figure below for an example of what your kernel buffer should look like after loading and removing your kernel module. I have provided a Makefile to help you to build your kernel module. Place the provided Makefile into your work directory and update it with the appropriate object file name for your submission. Assignment Description Part 2 The second task for your assignment is to repeat the first task, but to instead implement your own versions of the functions for building a linked list. You must replace any functions/macros that come from the types.h or lists.h with your own functions. Your second solution should build a circular doubly-linked list and repeat the same process of adding five elements and traversing those elements when the kernel module is loaded and traversing the list and removing the elements in reverse order when the kernel module is removed. Be sure to remember to free the kernel memory in each task