Differences

This shows you the differences between two versions of the page.

Link to this comparison view

isc:labs:kernel:tasks:02 [2021/11/24 15:35]
radu.mantu created
— (current)
Line 1: Line 1:
-==== 02. [??p] Kernel modules ==== 
  
-Way back when, kernels used to be monolithic, meaning that adding new functionality required recompiling and installing it, followed by a reboot. Today, things are much easier. By using the **kmod** daemon (''​man 8 kmod''​),​ users are allowed to load and unload __modules__ (i.e.: kernel object files) on demand, without all the fuss. These modules are C programs that must implement initialization and removal functions that are called automatically. Usually, these functions register / unregister other functions contained in your object with core kernel systems. 
- 
-We can use **lsmod** to get a list of all present modules, and **modinfo** to obtain detailed information about a specific module. 
- 
-<code bash> 
-$ lsmod 
-ecdh_generic ​          ​16384 ​ 1 bluetooth 
- 
-$ modinfo ecdh_generic | grep description 
-description: ​   ECDH generic algorithm 
- 
-$ modinfo bluetooth | grep description ​ 
-description: ​   Bluetooth Core ver 2.22 
-</​code>​ 
- 
-What we can understand from this is that the [[https://​elixir.bootlin.com/​linux/​latest/​source/​crypto/​ecdh.c|Elliptic Curve Diffie-Hellman]] module is 16384 bytes in size and is used by one other module, via the [[https://​elixir.bootlin.com/​linux/​latest/​source/​net/​bluetooth/​ecdh_helper.c|bluetooth ECDH helper]]. As you probably noticed, [[https://​elixir.bootlin.com/​linux/​latest/​source|elixir.bootlin.com]] is a critical resource in navigating the kernel code. 
- 
-=== [??p] Task A - Our first module === 
- 
-Looking in the //​%%skel/​01/​%%//​ directory from our code skeleton, we will find a minimal build environment for our first module. Alas, compiling a kernel module differs from compiling a user space program. But just slightly: kernel-specific headers must be used, user space-specific libraries (e.g.: **libc**) are generally unavailable (so no **printf()**) and lastly, the same options that were used to compile the kernel itself must be specified. To this end, the **kbuild** system was introduced. As you can see, our //​Makefile//​ invokes its correpsondent from the kernel source directory in //​%%/​lib/​modules/​...%%//,​ which in turn uses the configuration in our //Kbuild// file. The **obj-m** variable specifies the name of the final output object file (in this case, //​test.o//​). **test-objs** contains a sequence of dependent object files, so if you split your code across multiple sources, just add them to **test-objs**. If you have a single source, you can drop **test-objs** but the **kbuild** system will expect a //test.c// file to be present. 
- 
-Now, let's compile our module, upload it into the kernel, and see what happens: 
-<code bash> 
-$ make 
- 
-$ sudo insmod test.ko 
-$ sudo dmesg 
-... 
-[ 6348.461247] my-first-module:​ Hello world! 
- 
-$ sudo rmmod test 
-$ sudo dmesg 
-... 
-[ 6348.461247] my-first-module:​ Hello world! 
-[ 6366.635090] my-first-module:​ Goodbye cruel, cruel world! 
-</​code>​ 
- 
-Here, we used **insmod** to upload a //%%.ko%%// kernel object file into the kernel proper and **rmmod** to remove it. **dmesg** is a tool that prints the kernel message buffer. Note that there are multiple [[https://​www.kernel.org/​doc/​html/​latest/​core-api/​printk-basics.html|log levels]] ranging from **debug** to **emergency**. **pr_info()** is the kernel'​s **printf()** variant that corresponds to one of the less urgent levels. **dmesg** can be configured to squelch messages under a certain level but depending on how your kernel was compiled, some of the more important messages will also be echoed to your terminal. 
isc/labs/kernel/tasks/02.1637760902.txt.gz ยท Last modified: 2021/11/24 15:35 by radu.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0