| A while ago i started fooling around with device-driver writing in plain assembly language. It seems that the programmers of *nix world have some ancestral fear of ASM and because i really wanted to understand the inner-workings of the linux kernel and i have some experience in writing programs using assembly i tried to find some good documents which could help me in this task. I managed to find a small source of a very simple "skeleton" module and i tried it to see how it works. Let me give you here the first version of that module : |
;----------------------------------------
; simple_module.asm
;----------------------------------------
section .text
global init_module
global cleanup_module
global kernel_version
extern printk
init_module:
push dword str1
call printk
pop eax
xor eax,eax
ret
cleanup_module:
push dword str2
call printk
pop eax
ret
str1 db "Skeleton module loaded",0ah,0
str2 db "Skeleton module unloaded",0ah,0
kernel_version db "2.4.19-16mdk",0
|
| Just replace the "kernel_version" string with your own kernel version and compile the program using : |
nasm -f elf -o simple_module.obj simple_module.asm ld -r -o simple_module.o simple_module.obj |
| After this you will have in the same directory as your source two more files. You can safely delete simple_module.obj from your folder and try to load your module now into the kernel space : |
insmod simple_module.o |
| Oooops :) This operation returns a warning message : |
Warning: loading simple_module.o will taint the kernel: no license See http://www.tux.org/lkml/#export-tainted for information about tainted modules Module tainted loaded, with warnings |
| Hmmm, this must be something you might think. But is my module loaded or not ? you might ask. Yes, it is. If you just try this you will see : |
tail /var/log/messages |
|
The last line (or one near by) will be : ....kernel: Skeleton module loaded WOW ! Ok, now what about that warning ? Well, you shoulf firstly go to that URL and try to understand what is written there. I will show you how can you fix your module so that it is recognised and loaded properly without any warnings. This message is printed whenever you try to load a binary module which is has no information about its license. Usually linux kernel modules are distributed along with the sources under some GPL-type license. All the valid and accepted by linux licenses are listed in linux/include/modules.h. I will quote here what is written in my modules.h file : |
/* * The following license idents are currently accepted as indicating free * software modules * * "GPL" [GNU Public License v2 or later] * "GPL and additional rights" [GNU Public License v2 rights and more] * "Dual BSD/GPL" [GNU Public License v2 or BSD license choice] * "Dual MPL/GPL" [GNU Public License v2 or Mozilla license choice] * * The following other idents are available * * "Proprietary" [Non free products] * * There are dual licensed components, but when running with Linux it is the * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL * is a GPL combined work. * * This exists for several reasons * 1. So modinfo can show license info for users wanting to vet their setup * is free * 2. So the community can ignore bug reports including proprietary modules * 3. So vendors can do likewise based on their own policies */ |
| Ok, now what ? :) Well, generally if you make a kernel module using "C" language you have MODULE_LICENSE macro and can set the license like this : |
MODULE_LICENSE("GPL");
|
| This is the C way of doing things but how can we implement this in assembly ? Let's take a little time and parse the code for this macro : |
#define MODULE_LICENSE(license) \
static const char __module_license[] __attribute__((section(".modinfo"))) = \
"license=" license
|
| This basically means that it adds a variable named __module_license which is actually a pointer to a string located in .modinfo section. So, the string should be "license=GPL" and it should be located in another section. Well, let's try to add that section. I will try to modify our basic skeleton module to fit our need : |
;----------------------------------------
; licensed_module.asm
;----------------------------------------
section .text
global init_module
global cleanup_module
global kernel_version
extern printk
init_module:
push dword str1
call printk
pop eax
xor eax,eax
ret
cleanup_module:
push dword str2
call printk
pop eax
ret
str1 db "Licensed module loaded",0ah,0
str2 db "Licensed module unloaded",0ah,0
kernel_version db "2.4.19-16mdk",0
__module_license dd lic_string
section .modinfo
lic_string db "license=GPL",0
|
| Let's try now and see if it works : |
nasm -f elf -o licensed_module.obj licensed_module.asm ld -r -o licensed_module.o licensed_module.obj insmod licensed_module.o |
| WOW ! No Warnings ! Let's see if it is really loaded |
tail /var/log/messages |
....kernel: Licensed module loaded
Perfect. Problem solved.
|