Linked List : Insert Front ========================== .. tab-set:: .. tab-item:: Linked List : Insert Front * In this program, you are going to learn .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to insert the elments to rear end of the linked list ? .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow * How to use the below API's ? * `INIT_LIST_HEAD `_ * `list_add `_ * `list_for_each_entry `_ * `list_for_each_entry_safe `_ * `list_del `_ .. panels:: :container: container pb-4 :column: col-lg-12 p-2 :card: shadow Topics in this section, * :ref:`Explanation of Program part by part ` * :ref:`List of headers ` * :ref:`Modules macro ` * :ref:`Initialize function and variables ` * :ref:`Module init function ` * :ref:`Module exit function ` * :ref:`Linked list APIs ` * :ref:`Mention init and exit function ` * :ref:`See the full program below ` * :ref:`Makefile ` * :ref:`Compile and Load ` * :ref:`Summary of Linked List APIs ` .. _insert_front_4: .. tab-set:: .. tab-item:: Explanation of program part by part * In this example, we are going to insert the elements in the front end. .. _insert_front_5: .. tab-set:: .. tab-item:: List of headers * Add the list of header files to refer the APIs used in this program. .. code-block:: c #include #include #include #include #include .. _insert_front_6: .. tab-set:: .. tab-item:: Modules macro * Add the modules macro which lists the information about the license, author and description. .. code-block:: c MODULE_LICENSE("GPL"); MODULE_AUTHOR("linux_usr"); MODULE_DESCRIPTION("Linked List"); .. _insert_front_7: .. tab-set:: .. tab-item:: Initialize function and variables * ``list_head`` is used to initialize the list. .. code-block:: c static struct list_head my_list; * ``INIT_LIST_HEAD`` is used to initialize a list_head structure. .. code-block:: c INIT_LIST_HEAD(&my_list); INIT_LIST_HEAD(&new_node->list); .. _insert_front_8: .. tab-set:: .. tab-item:: Module init function * Add the module init function to execute the function once when the module is loaded to the linux kernel. .. code-block:: c static int __init linkedlist_init(void) { pr_info("Driver loaded\n"); INIT_LIST_HEAD(&my_list); insert_front(0); insert_front(1); insert_front(2); insert_front(3); pr_info("Linked list after insertion : \n"); display(); return 0; } .. _insert_front_9: .. tab-set:: .. tab-item:: Module exit function * Add module exit function which is executed once the module is unloaded from the kernel. .. code-block:: c static void __exit linkedlist_exit(void) { struct list_node *ptr, *next; list_for_each_entry_safe(ptr, next, &my_list, list) { list_del(&ptr->list); kfree(ptr); } pr_info("Driver unloaded\n"); } .. _insert_front_10: .. tab-set:: .. tab-item:: Linked List APIs * ``insert_front`` function inserts a new node at the beginning with the given ``value`` into the linked list. .. code-block:: c void insert_front(int value) { struct list_node * new_node; new_node = kmalloc(sizeof(struct list_node), GFP_KERNEL); if (!new_node) { pr_err("Memory allocation failed\n"); return; } new_node->data = value; INIT_LIST_HEAD(&new_node->list); list_add(&new_node->list, &my_list); } * ``display`` function iterates through the linked list using ``list_for_each_entry``. It prints the data in each node to the kernel log. .. code-block:: c void display(void) { struct list_node * ptr; pr_info("Linked list: "); list_for_each_entry(ptr, &my_list, list) { printk(KERN_CONT "%d -> ", ptr->data); } printk(KERN_CONT "NULL\n"); } .. _insert_front_11: .. tab-set:: .. tab-item:: Mention init and exit functions * Add the module init and exit which is called when the module is loaded and unloaded. .. code-block:: c module_init(linkedlist_init); module_exit(linkedlist_exit); .. _insert_front_0: .. tab-set:: .. tab-item:: See the full program below .. tab-set:: .. tab-item:: insert.c .. literalinclude:: insert_front/insert.c :language: c :linenos: :emphasize-lines: 16, 20, 22, 30, 31, 36, 39, 51, 59, 68, 69 .. _insert_front_1: .. tab-set:: .. tab-item:: Makefile .. literalinclude:: insert_front/Makefile :language: c :linenos: .. _insert_front_2: .. tab-set:: .. tab-item:: Compile and Load .. code-block:: c :linenos: :emphasize-lines: 1 $ make all .. _insert_front_3: .. tab-set:: .. tab-item:: Summary of Linked List APIs =============================== =========================================================================================== API Learning =============================== =========================================================================================== INIT_LIST_HEAD To initialize a list_head structure list_head To initialize the list list_for_each_entry To iterate over list of given type list_for_each_entry_safe To iterate over list of given type safe against removal of list entry list_add To insert a new entry after the specified head list_del To delete entry from list =============================== =========================================================================================== .. card:: See Also * Previous Chapters * :doc:`../chapter1_basics/chapter1_basics` * :doc:`../chapter2_kthreads/chapter2_kthreads` * :doc:`../chapter3_tasklets/chapter3_tasklets` * :doc:`../chapter4_workqueue/chapter4_workqueue` * :doc:`../chapter5_timer/chapter5_timer` * Other Linked List topics * :doc:`insert_rear` * :doc:`insert_at_pos` * :doc:`delete_rear` * :doc:`delete_front` * :doc:`delete_at_pos` * :doc:`list_splice` * :doc:`list_splice_init` * :doc:`list_splice_tail` * :doc:`list_splice_tail_init` * :doc:`list_cut_position` * :doc:`list_del_init` * :doc:`list_first` * :doc:`list_first_entry_or_null` * :doc:`list_for_each` * :doc:`list_for_each_entry_continue` * :doc:`list_for_each_entry_continue_reverse` * :doc:`list_for_each_entry_safe_reverse` * :doc:`list_is_singular` * :doc:`list_last` * :doc:`list_move` * :doc:`list_move_tail` * :doc:`list_replace` * :doc:`list_replace_init` * Next Chapter * :doc:`../chapter9_fileSystem/chapter9_fileSystem` * Other Chapter * :doc:`../chapter10_netlink/chapter10_netlink`