390 likes | 669 Views
Kernel Module. 2009/04/06 ------------------------------------------------------------- 941540 王孟婷 9762517 王紹仲 9762570 陳奕廷. Linux Module. Add new functionality to the Linux kernel. Nearly every higher-level component of the Linux kernel can be compiled as a module
E N D
Kernel Module 2009/04/06 ------------------------------------------------------------- 941540 王孟婷 9762517 王紹仲 9762570 陳奕廷
Linux Module Add new functionality to the Linux kernel. Nearly every higher-level component of the Linux kernel can be compiled as a module Filesystems, device drivers, executable formates, network layers, and so on.
Module Implementation For each module, kernel allocates a memory to store: A null-terminated string that represents the name of the module (unique) A module object structure The code that implements the functions of the module Modules are stored in the file system as ELF(Executable and Linking Format) object files.
ELF Introduction ELF 支援 dynamic linking dynamic loading 對程式的 runtime control
Types of ELF files ELF 檔案有三種主要的類型: executable file 可執行檔, 包含 OS create process image 所需的資訊 relocatable file .o 檔 可以用來和其他 object file link 成 executable 或 shared object file shared object file .so 檔 包含 static 和 dynamic linking 所需的資訊
ELF Linking View ELF object file format linking view 檔案在硬碟裡的樣子 ELF header Program header table (optional) Section 1 … Section n Section header table ELF linking view Elf_Ehdr 描述 object file 的 layout segment 的描述, create process image 用 • 每個 section 由唯一的一個 section header 描述 • section header 可能描述一個不存在 object file 中的 section (例如 BSS) • 每個 section 不會重疊 描述 section 的資訊, linking 用
ELF Execution View ELF object file format execution view 檔案在記憶體裡執行的樣子 ELF header Elf_Ehdr 描述 object file 的 layout Program header table segment 的描述, create process image 用 Segment 1 一個 segment 可能由多個 section 組成 … Segment n Section header table (optional) 描述 section 的資訊, linking 用 ELF execution view
Link a Module into Kernel >>> insmod Reads from the command line the name of the module Locates the file containing the module's object code in the system directory tree. …/lib/modules. Reads the module's object code from disk . Invokes the sys_init_module( ) system call Module name Address of the User Mode buffer to contain the module's object code Terminates.
Kernel Module Structure struct modulekernel_module ={ size_of_struct: sizeof(struct module), name: "", uc: {ATOMIC_INIT(1)}, flags: MOD_RUNNING, syms: __start___ksymtab, ex_table_start: __start___ex_table, ex_table_end: __stop___ex_table, kallsyms_start: __start___kallsyms, kallsyms_end: __stop___kallsyms, }; struct module *module_list = &kernel_module;
sys_init_module( ) Checks whether the user is allowed to link the module security CAP_SYS_MODULE capability Allocates a temporary memory area for the module's object code; then, copies the module from the User Mode buffer Checks that the data in the memory area effectively represents a module's ELF object; otherwise, returns an error code.
sys_init_module( ) Allocates a memory area for the parameters passed to the insmod program, and fills it with the data in the User Mode buffer Walks the modules list to verify that the module is not already linked. Allocates a memory area for the core executable code of the module, and fills it with the contents of the relevant sections of the module. Allocates a memory area for the initialization code of the module, and fills it with the contents of the relevant sections of the module.
sys_init_module( ) Determines the address of the module object for the new module. An image of this object is included in the gnu.linkonce.this_module section of the text segment of the module's ELF file. Stores in the module_code and module_init fields of the module object the addresses of the memory areas allocated in steps 6 and 7. Initializes the modules_which_use_me list in the module object, and sets to zero all module's reference counters except the counter of the executing CPU, which is set to one. Sets the license_gplok flag in the module object according to the type of license specified in the module object.
sys_init_module( ) Using the kernel symbol tables and the module symbol tables, relocates the module's object code. Initializes the syms and gpl_syms fields of the module object The exception table of the module is contained in the ex_table section of the module's ELF file, stores its address in the ex_table field of the module object. Parses the arguments of the insmod program, and sets the value of the corresponding module variables accordingly.
sys_init_module( ) Registers the kobject included in the mkobj field of the module object. Frees the temporary memory area allocated in step 2. Adds the module object in the modules list. Sets the state of the module to MODULE_STATE_COMING. If defined, executes the init method of the module object. Sets the stateof the module to MODULE_STATE_LIVE. Terminates by returning zero (success).
Unlink a Module off the Kernel >>> rmmod Reads from the command line the name of the module to be unlinked. Opens the /proc/modules file, which lists all modules linked into the kernel, and checks that the module to be removed is effectively linked. Invokes the delete_module( ) system call passing to it the name of the module. Terminates.
sys_delete_module( ) Checks whether the user is allowed to unlink the module (the current process must have the CAP_SYS_MODULE capability). Copies the module's name in a kernel buffer. Walks the modules list to find the module object of the module.
sys_delete_module( ) Checks the modules_which_use_me dependency list of the module; if it is not empty, the function returns an error code. Checks the state of the module; if it is not MODULE_STATE_LIVE, returns an error code.
sys_delete_module( ) If the module has a custom init method, the function checks that it has also a custom exit method To avoid race conditions, stops the activities of all CPUs in the system, except the CPU executing the sys_delete_module( ) service routine. Sets the state of the module to MODULE_STATE_GOING.
sys_delete_module( ) If the sum of all reference counters of the module is greater than zero, returns an error code. If defined, executes the exit method of the module. Removes the module object from the modules list, and de-registers the module from the sysfs special filesystem.
sys_delete_module( ) Removes the module object from the dependency lists of the modules that it was using. Frees the memory areas that contain the module's executable code, the module object, and the various symbol and exception tables. Returns zero (success).
static noinline struct module *load_module(void __user *umod , ….) insmod System Call sys_init_module • Copying module data from user space into a temporary memory location in kernel address space and rewriting section address • Finding the position of the section • find_sec(Elf_Ehdr *hdr, …….) • Splitting the section into two parts : core and init • layout_sections(struct module *mod, ……) • Allocating the module memory • module_alloc(unsigned long size) • Querying the module license • set_license(struct module *mod, ……) • Resolving references and relocation • Processing the arguments of the module SYSCALL_DEFINE3(init_module,….) Checks whether the user is allowed to link the module Load module Executes the init method of the module object static int simplify_symbols(Elf_Shdr *sechdrs, …) Using the kernel symbol tables and the module symbol tables, relocates the module‘s object code. Undefined symbol be reserve by the function resolve_symbol NEXT PAGE
static unsigned long resolve_symbol(Elf_Shdr *sechdrs, ….. • Resolving the undefined symbol reference • find_symbol(const char *name, ……) • Determining whether the checksums match • check_version(Elf_Shdr *sechdrs , ….) • If the symbol used originates from another module ,a dependency between two modules is established • use_module(struct module *a, struct module *b)
linux/kernel/sys_ni.c linux/include/linux/syscalls.h …
linux/kernel/module.c linux/include/linux/capability.h …
… linux/include/linux/module.h …
… … … …
rmmod System Call sys_delete_module SYSCALL_DEFINE2(delete_module, ….) • Search for module by name • *find_module(const char *name) • Ensure module is not use • !list_empty(&mod-> modules_which_use_me) • Executes the exit method of the module • free memory space occupied by module data • static void free_module(struct module *mod)