http://www.hustyx.com/ubuntu/4/


下一个项目要做基于Linux的设备驱动开发,其实就是做Ophone的移植工作。刚找了本Linux设备驱动来学习学习。

首先就是学习Linux的模块编程,照着书上的例子实现Hello.ko也经历一番波折,凡事只有自己亲自尝试过,才知道个中细节如何啊。以下记录我完成这个简单模块的编写,加载,卸载的全过程及要注意的地方。

在任意一个地方创建一个hello.c文件,里面就写如下内容:

 
 
/* hello.c */ #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE ( "Dual BSD/GPL" ); static int hello_init ( void ) {      printk ( KERN_ALERT "Hello, World\n" );       return 0 ; } static int hello_exit ( void ) {      printk ( KERN_ALERT "Goodbye, cruel world\n" ); } module_init ( hello_init ); module_exit ( hello_exit );

这个模块什么也不干,只是在模块加载时打印一条信息,卸载时也打印一条信息。麻雀虽小,但五脏具全,MODULE_LICENSE()指明认证方式,现在支持的有:“GPL” “GPL v2" "GPL and additional rights" "Dual BSD/GPL" "Dual MIT/GPL" "Dual MPL/GPL" "Proprietary",这是内核2.6里新添加的,实验发现它不是必需的。module_init()指明模块的入口,这是必需的;module_exit()指明模块的出口,这也是必需的。

编译使用make的扩展功能,在与hello.c同一目录下创建一个Makefile文件,内容如下:

 
 
/* Makefile */ TARGET = hello KDIR =/ usr / src / linux - headers - 2.6 . 31 - 19 - generic PWD = $ ( shell pwd ) obj - m := $ ( TARGET ). o default :      make - C $ ( KDIR ) M = $ ( PWD ) modules

其中TARGET指明了目标文件的名字,KDIR指明了引用头文件的位置,请根据具体情况修改该文件。不过有几点要说明,模块的编译需要有一个内核源码的目录结构,如果有内核源码当然更好,直接把KDIR改为源码的路径就OK了。当然只有一个内核目录结构也就可以了,毕竟需要的只是头文件,及一些编译脚本,在Linux各发行版的/usr/src/下是有这样一个目录结构的,比如我的系统为Ubuntu9.10,内核为2.6.31-19的通用版,在/usr/src/下就有linux-headers-2.6.31-19-generic这样一个目录。所以我使用KDIR=/usr/src/linux-headers-2.6.31-19-generic。其实还有一个目录名为linux-headers-2.6.31-19,而且你会发现linux-headers-2.6.31-19-generic里的大部分文件只是指向linux-headers-2.6.31-19的一些链接,不过linux-headers-2.6.31-19里面默认缺少一些编译模块所需要的文件,不要使用它。

接下来,你只要使用make命令,就可以进行编译了,make会为你处理好一切,它会根据KDIR找到编译所需要的文件。如果你运气好的话,你的当前目录下就会成生hello.o hello.mod.o hello.mod.c modules.order Module.markers Module.symvers hello.ko,当然可爱的hello.ko就是我们想要的。到此你的模块已经成功生成了,接下来便可以加载这个模块看看效果了。

使用insmod ./hello.ko来加载模块,如果你遇到insmod: error inserting 'hello.o'  :-l invalid module format这样的错误,不用惊慌,并不是你的模块有问题,而是你当前运行的内核版本与你编译链接的头文件版本不一致,所以会出现格式不对的问题。此时,你可以更换系统内核,也可以下载一个与系统版本一致的内核源码重新编译该模块。如果你没有遇到任何问题,也没有打印出任何信息,那么恭喜你,你的内核加载成功了,你可以使用lsmod命令来罗列出当前你系统加载的所有模块,相信你在列表中会找到hello的。你可能会疑惑,为什么没有如我们想像中的那样,打印出"Hello, World"?呵呵,这是因为printk并不会把打印内容打印到你当面的终端,要知道模块是运行在内核态的,而你所能面对的是用户态,内核态的打印信息需要通过log或者dmesg命令来查看,想看到打印結果,最简单的方法是敲入dmesg命令,你就可以看到你所希望看到的信息了,同时,你也可以打开/var/log/message这个文件进行查看。

最后,使用rmmod hello来卸载模块,同样,使用dmesg可以看到打印出的"Goodbye, cruel world"。


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

http://www.idevlife.com/183563/

Linux Kernel Module Programming

The first is to learn Linux module programming, according to the book's examples the Hello.ko experienced some twists and turns, everything only personally tried, only to know in detail how ah. The following records to complete the preparation of this simple module, load, unload the whole process and must pay attention to.

A hello.c file created in any one place, which wrote the following:

 
 
 
  
  
/ * Hello.c * /   # Include <linux/init.h>   # Include <linux/module.h> MODULE_LICENSE ("Dual BSD / GPL");     static the int hello_init (void)   {Printk (KERN_ALERT "Hello, World / n");         return 0;   }     static the int hello_exit (void)   {Printk (KERN_ALERT "Goodbye, cruel world / n");   } Module_init (hello_init); module_exit (hello_exit);  

This module is to do nothing, just prints a message when the module is loaded, uninstall also prints a message. Though small, but with all MODULE_LICENSE () specified authentication method now supports: "GPL" GPL v2 "GPL and Additional Rights" Dual BSD / GPL "Dual MIT / GPL Dual MPL / GPL "" Proprietary ", which is the kernel 2.6 added, and found that it is not required. specified module_init () module entrance, which is required Home; the module_exit () specified module export, which is required.

Compiler extensions, use make to create a Makefile in the same directory with the hello.c, as follows:

 
 
 
  
  
/ * Makefile * / TARGET = Hello KDIR = / usr / src / linux - headers - 2.6. 31 - 19 - generic PWD = $ (shell pwd) obj - m: = $ (TARGET). o default: make - C $ (KDIR) M = $ (PWD) modules

Indicates the name of the target file, which target KDIR pointed out the reference to the location of the header files, modify the file, depending on the circumstances. There are several things to note, the module compiler needs to have a kernel source directory structure, if there is a kernel source is certainly better, directly change KDIR to the source path on OK. Of course, there is only one kernel directory structure will be, after all, just need the header files, and build scripts, there is such a directory structure in Linux release the / usr / src / under like my system Ubuntu9. 10, the kernel 2.6.31-19 generic version in / usr / src / under there linux-headers-2.6.31-19-generic such a directory. So I use KDIR = / usr/src/linux-headers-2.6.31-19-generic. In fact, there is a directory called linux-headers-2.6.31-19, and you will find that most of the files are just the linux-headers-2.6.31-19-generic linux-headers-2.6.31-19 some point link, but the default linux-headers-2.6.31-19 inside the compiled module file is missing, do not use it.

Next, as long as you use the make command, you can compile and make for you everything, it will according to KDIR find compile the required documentation. If your luck is good, your current directory will mature hello.o hello.mod.o hello.mod.c modules.order Module.markers Module.symvers hello.ko, of course, cute is what we want to hello.ko want. This module has been successfully generated, the next will be able to load the module to see the effect.

Use the insmod. / Hello.ko to load the module, if you encounter insmod: error inserting 'hello.o':-l invalid module format this error, do not panic, not your module, but you are currently running The kernel version is inconsistent with the first version of the file that you compile and link, so there will be the problem of the wrong format. At this point, you can replace the system kernel, recompile the module can also download a system version of the kernel source. If you do not encounter any problems, did not print out any information, then congratulations, your kernel loaded successfully, you can use the lsmod command to list all the modules loaded your system, I believe you will find in the list hello. You may be wondering, why did not as we think of it, print out "Hello, World"? Oh, this is because the the printk will not print the contents of the print to the terminal you face to face, to know the module is running in kernel mode, you can face the user mode, kernel mode print information need to log or dmesg command to see, want to see the print results, the easiest way is typing dmesg command, you can see the information you want to see, you can open this file in / var / log / message view .

Finally, to use rmmod hello to uninstall module, the same, using the dmesg you can see the print out "Goodbye, cruel world".


GitHub 加速计划 / li / linux-dash
6
1
下载
A beautiful web dashboard for Linux
最近提交(Master分支:4 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐