天天看點

LKM -- load and unload process // My presentation

AUTHOR: Joseph Yang (楊紅剛) <[email protected]>

CONTENT: LKM -- load and unload process

NOTE: linux-3.0

LAST MODIFIED:09-27-2011

-----------------------------------------------------------------------------------------------------------

Distributed and Embedded System Lab (分布式嵌入式系統實驗室,蘭州大學)

===============================================================

                         LKM -- load and unload process

------------------------------------

contents:

1.  Brief introduction about    LKM.

2.  Short introduction of ELF

3.  Module loading   &  Module unloading

4.  Conclusion

5. REF

---------------------------------

1.  Brief  introduction about    LKM.

   1.1

     The Linux kernel is what's known as a monolithic kernel, which means that the majority of the

     operating system functionality is called the kernel and runs in a privileged mode. This differs from

     a micro-kernel, which runs only basic functionality as the kernel (inter-process communication [IPC],

     scheduling, basic input/output [I/O], memory management) and pushes other functionality outside

     the privileged space (drivers, network stack, file systems).

     Linux can be dynamically altered at run time through the use of Linux kernel modules (LKMs).

     Dynamically alterable means that you can load new functionality into the kernel, unload functionality

      from the kernel, and even add new LKMs that use other LKMs.

    1.2  A source view of LKM

             #include <linux/module.h>

            #include <linux/init.h>

            static int __init lkm_init(void)

            {

               printk("This will be called when module is loaded\n");

               return 0;

            }

            static void __exit lkm_exit(void)

            {

                printk(" This will be called when module is deleted\n");

            }

            MODULE_LICENSE("GPL");

            module_init(lkm_init);

            module_exit(lkm_exit);   

2.  Short introduction of ELF (abbreviation of Executable and Linkable Format)

           2.1 Intuitive view of ELF

           $ objdump -h hello.ko  // show  section headers

           .text    // instructions

           .init.text // init instructions

           .exit.text // exit instructions

           .rodata.str1.4 // read-only strings

           .modinfo // module macro text         // modinfo *.ko

           .data // Initialized data

           .bss // Uninitialized data

           .gnu.linkonce.this_module //  module's name, init & exit function's  addresses

                                                         //  vim *.mod.c                                                         

           2.2     tools  which can be helpful  

               objdump -h hello.ko

                readelf -p 17 hello.ko // read the contents of specified section

                readelf -s hello.ko // can read content of  '.symtab' section

                readelf -S hello.ko // read section headers

                readelf -e hello.ko // ELF header and section headers

           2.3 Link view of ELF

                    ----------

                    ELF header         

                    ----------

                    Program header table

                    ----------

                    section 1

                    --------

                    section 2

                    ...

                    -------

                    section header table

                    -----------

                  What every part used for ??  

                  Ans:  readelf -e hello.ko // ELF header and section headers

REF:  More information about the ELF, you can  refer 'TIS ELF Specification V 1.2'

3.  Module loading   &  Module unloading

    3.1  

           The process of module loading begins in user space with insmod (insert module).

    The insmod command defines the module to load and invokes the init_module user-space

    system call to begin the loading process.  The init_module function works through the system

    call layer and into the kernel to a kernel function called sys_init_module.

           Similarly, the rmmod command results in a system call for delete_module, which eventually

    finds its way into the kernel with a call to sys_delete_module to remove the module from the kernel.

     REF:  System call : http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN976

    3.2  Loading process

           sys_init_module():

               1> permission check          // capable(),modules_disabled

               2> Allocate, load module  and  create corresponding control files in sysfs //load_module() ***

               3> Call module notify list with state change (MODULE_STATE_COMING) //blocking_notifier_call_chain

               4> Set the property for 'core' and 'init' section: // set_section_ro_nx

                     Set RO for module text and RO-data and  Set NX permissions for module data.

               5> Call the module's init function.(mod->init()) // do_one_initcall  ++ Module is alive

               6> mod->state = MODULE_STATE_LIVE

               7> wake up all tasks waiting for the initialization of this module in queue 'module_wq'

               8> Call module notify list with state change(MODULE_STATE_LIVE)

               9> Unset the RO and NX property for 'init' section. //unset_module_init_ro_nx

               10> Free the memory related to 'module init'. //module_free

               Detail of function  load_module():

                        1> Allocate temporary memory for the module, copy the module image from userspace,

                              and do module checking. // copy_and_check

                        2> layout module allocate memory and copy corresponding sections to the final position.

                                                                          // layout_and_allocate

                        3> Init the unload section of the module.  //module_unload_init <two lists>

                        4> Find optional sections and set corresponding items in mod //find_module_sections

                        5> check_module_license_and_versions(mod)  

                        6> //setup_modinfo

                        7> Fix up syms, so that st_value is a pointer to location.  //simplify_symbols

                        8> Aplly relocations, copy relocated percpu area over. //apply_relocations, post_relocation

                        9> Flush the instruction cache // flush_module_icache

                        10> Copy the arguments from userspace to kernel space. //strndup_user

                        11> Set the module state to MODULE_STATE_COMING

                        12>  Verify there is no duplicate symbols. //verify_export_symbols

                        13>  Add the module to the global moudle list -- modules //list_add_rcu

                        14> //parse_args

                        15>  create corresponding control files in  sysfs //mod_sysfs_setup

                        16>     //kfree, free_copy

      Done!!!        

      3.3 Unloading process       

                 sys_delete_module():

                           1> permission check          // capable(),modules_disabled

                           2> Copy module name from userspace //strncpy_from_user

                           3>  Find the pointer to the module which should be unloaded // find_module

                           4> Make sure that no other modules are depend on this module //list_empty

                           5> Verify the module state, make sure the module is in MODULE_STATE_LIVE state

                           6>    //try_stop_module

                           7> Wait for the module's reference couter becoming 0 //wait_for_zero_refcount

                           8> Call the module's exit function // mod->exit()

                           9> Call module notify list with state change(MODULE_STATE_GOING)

                                                                                                       //blocking_notifier_call_chain

                           10>  Synchronize all asynchronous function calls          //async_synchronize_full

                           11>   //free_module      ****

                            Detail of free_module():

                                      1> Delete the corresponding control files under /sys     // mod_sysfs_teardown

                                      2> // module_arch_cleanup

                                      3> 

                                      4>  Unset the RO and NX property for 'init' section. //unset_module_init_ro_nx

                                      5>  Free the memory related to 'module init'. //module_free

                                      6>  kfree(mod->args)

                                      7>  Free the percpu variables //percpu_modfree

                                      8> 

                                              Unset the RO and NX property for 'core' section. //unset_module_init_ro_nx

                                              Free the memory related to 'module core'. //module_free

         OK!!!

4.  Conclusion

        This is a brief introduction of module load and unload. More detail information you can read

         the source code(kernel/module.c). Before reading the source code you'd better read the

         ELF format then you can get a better understanding of "why".

5. REF:

             http://www.ibm.com/developerworks/linux/library/l-lkm/?S_TACT=105AGX52&S_CMP=cn-a-l

             More information about the ELF, you can  refer 'TIS ELF Specification V 1.2'

             System call : http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN976

         Thank you!

繼續閱讀