{"id":446,"date":"2020-08-18T19:23:47","date_gmt":"2020-08-18T20:23:47","guid":{"rendered":"http:\/\/www.linux-tutorial.info\/?page_id=77"},"modified":"2020-08-22T19:26:16","modified_gmt":"2020-08-22T20:26:16","slug":"this-is-the-page-title-toplevel-279","status":"publish","type":"page","link":"http:\/\/www.linux-tutorial.info\/?page_id=446","title":{"rendered":"Loading a Module"},"content":{"rendered":"\n<title>Loading a Module<\/title>\n<img decoding=\"async\" src=\"modules.gif\"><br \/>\n<p>\nFigure: The List of Kernel Modules\n<p>There are two ways that a <glossary>kernel<\/glossary> module can be loaded.\nThe first way is to use the <command>insmod<\/command> command to manually insert the\nmodule into the kernel.\n<p>\nThe second, and much more clever way, is to load the module as it is needed; this\nis known as demand loading.\n<p>\nWhen the <glossary>kernel<\/glossary> discovers the need for a module, for example when the user mounts\na file system that is not in the kernel, the kernel will request that the kernel daemon\n(<command>kerneld<\/command>) attempts to load the appropriate module.\n<p>\nThe <glossary>kernel<\/glossary> daemon is a normal user process albeit with super user privileges.\nWhen it is started up, usually at system boot time, it opens up an Inter-Process\nCommunication (IPC) channel to the kernel.\nThis link is used by the kernel to send messages to the <command>kerneld<\/command> asking for\nvarious tasks to be performed.\n<p>\n<tt>Kerneld<\/tt>&#8216;s major function is to load and unload <glossary>kernel<\/glossary> modules but it is also\ncapable of other tasks such as starting up the PPP link over serial line when it\nis needed and closing it down when it is not.\n<tt>Kerneld<\/tt> does not perform these tasks itself, it runs the neccessary programs\nsuch as <command>insmod<\/command> to do the work.\n<tt>Kerneld<\/tt> is just an agent of the kernel, scheduling work on its behalf.\n<p>\nThe <command>insmod<\/command> utility must  find the requested\n<glossary>kernel<\/glossary> module that it is to load.\nDemand loaded kernel modules are normally kept in <directory>\/lib\/modules\/kernel-version<\/directory>.\nThe kernel modules are linked object files  just like other programs in the system\nexcept that they are linked as a relocatable images.\nThat is, images that are not linked to run from a particular address.\nThey can be either  a.out or elf format object files.\n<command>insmod<\/command> makes a privileged system call to find the kernel&#8217;s exported symbols.\n<p>\nThese are kept in pairs containing the symbol&#8217;s name and its value, for example its\naddress.\nThe <glossary>kernel<\/glossary>&#8216;s exported symbol table is held in the first <tt>module<\/tt> data structure\nin the list of modules maintained by the kernel and pointed at by the <tt>module_list<\/tt>\npointer.\n<p>\nOnly specifically entered symbols are added into the table, which is built when the\nkernel is compiled and linked, not <em>every<\/em> symbol in the <glossary>kernel<\/glossary> is exported to\nits modules.\nAn example symbol is <tt>``request_irq''<\/tt> which is the <glossary>kernel<\/glossary> routine that must\nbe called when a driver wishes to take control of a particular system interrupt.\nIn my current kernel, this has a value of <em>0x0010cd30<\/em>.\nYou can easily see the exported <glossary>kernel<\/glossary> symbols and their values by looking at\n<tt>\/proc\/ksyms<\/tt> or by using the <font face=\"helvetica\">ksyms<\/font> utility.\nThe <command>ksyms<\/command> utility can either show you all of the exported kernel symbols or only\nthose symbols exported by loaded modules.\n<command>insmod<\/command> reads the module into its virtual memory and fixes up its unresolved\nreferences to kernel routines and resources using the exported symbols from the\nkernel.\nThis fixing up takes the form of patching the module image in memory.\n<command>insmod<\/command> physically writes the address of the symbol into the appropriate\nplace in the module.\n<p>\nWhen <command>insmod<\/command> has fixed up the module&#8217;s references to\nexported kernel symbols,it asks the <glossary>kernel<\/glossary> for enough space to hold\nthe new kernel, again using a privileged system call.\nThe <glossary>kernel<\/glossary> allocates a new <tt>module<\/tt> data structure and enough\nkernel memory to hold the new module and puts it at the end of the kernel modules list.\nThe new module is marked as <tt>UNINITIALIZED<\/tt>.\n<p>\nFigure&nbsp;<a href=\"#modules-figure\"> 12.1<\/a> shows the list of <glossary>kernel<\/glossary> modules after two\nmodules,<tt>VFAT<\/tt> and <tt>VFAT<\/tt> have been loaded into the kernel.\nNot shown in the diagram is the first module on the list, which is a pseudo-module that is only\nthere to hold the kernel&#8217;s exported symbol table.\nYou can use the command <command>insmod<\/command> to list all of the loaded\n<glossary>kernel<\/glossary> modules and their interdependencies.\n<font face=\"helvetica\">lsmod<\/font> simply reformats <tt>\/proc\/modules<\/tt> which is built from the list of kernel\n<tt>module<\/tt> data structures.\nThe memory that the <glossary>kernel<\/glossary> allocates for it is mapped into the <command>insmod<\/command> process&#8217;s\naddress space so that it can access it.\n<command>insmod<\/command> copies the module into the allocated space and relocates it so\nthat it will run from the <glossary>kernel<\/glossary>\n<glossary>address<\/glossary> that it has been allocated.\nThis must happen as the module cannot expect to be loaded at the same address\ntwice let alone into the same <glossary>address<\/glossary> in two different Linux systems.\nAgain, this relocation involves patching the module image with the appropriate\naddresses.\n<p>\nThe new module also exports symbols to the <glossary>kernel<\/glossary> and\n<command>insmod<\/command> builds a table\nof these exported images.\nEvery kernel module must contain module initialization and module cleanup\nroutines and these symbols are deliberately not exported but <command>insmod<\/command> must\nknow the addresses of them so that it can pass them to the kernel.\nAll being well, <command>insmod<\/command> is now ready to initialize the module and it makes\na privileged system call passing the <glossary>kernel<\/glossary> the addresses of the module&#8217;s initialization\nand cleanup routines.\n<p>\nWhen a new module is added into the <glossary>kernel<\/glossary>, it must update the kernel&#8217;s set of symbols\nand modify the modules that are being used by the new module.\nModules that have other modules dependent on them must maintain a list of references\nat the end of their symbol table and pointed at by their <tt>module<\/tt> data structure.\nFigure&nbsp;<a href=\"#modules-figure\"\n> 12.1<\/a> shows that the <tt>VFAT<\/tt> file system module is dependent on the\n<tt>FAT<\/tt> file system module.\nSo, the <tt>FAT<\/tt> module contains a reference to the <tt>VFAT<\/tt> module; the reference\nwas added when the <tt>VFAT<\/tt> module was loaded.\nThe kernel calls the modules initialization routine and, if it is successful it\ncarries on installing the module.\nThe module&#8217;s cleanup routine <glossary>address<\/glossary> is stored in it&#8217;s <tt>module<\/tt> data structure and\nit will be called by the kernel when that module is unloaded.\nFinally, the module&#8217;s state is set to <tt>RUNNING<\/tt>.\n<p>\n","protected":false},"excerpt":{"rendered":"<p>Loading a Module Figure: The List of Kernel Modules There are two ways that a kernel module can be loaded. The first way is to use the insmod command to manually insert the module into the kernel. The second, and &hellip; <a href=\"http:\/\/www.linux-tutorial.info\/?page_id=446\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-446","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/446","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=446"}],"version-history":[{"count":1,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/446\/revisions"}],"predecessor-version":[{"id":610,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/446\/revisions\/610"}],"wp:attachment":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}