交叉编译和加载内核模块

http://blog.chinaunix.net/uid-20543672-id-2985498.html
https://bbs.csdn.net/wap/topics/391832781
https://www.ibm.com/developerworks/cn/linux/l-lkm/
https://blog.csdn.net/sailor_8318/article/details/2954380
https://blog.csdn.net/qianjin0703/article/details/8468326
https://zhuanlan.zhihu.com/p/32786076

Linux 内核的整体结构非常庞大,其包含的组件也非常多,把需要的组件包含在内核中有两种方法:

  • 一种是把所有需要的功能都编译到Linux 内核。这会导致编译出来的内核镜像比较大,以及如果要在现有的内核中新增或删除功能,将不得不重新编译内核。
  • 另一种机制是使得编译出的内核本身并不需要包含所有功能,而在这些功能需要被使用的时候,其对应的代码可被动态地加载到内核,Linux 提供了这样的一种机制,这种机制被称为模块(Module)。
    模块具有下特点:
    1 模块本身不被编译入内核映像,从而控制了内核的大小。
    2 模块一旦被加载,它就和内核中的其他部分完全一样。

内核模块的使用方式

  • 安装内核模块:
insmod modulename.ko
  • 卸载呢和模块:
rmmod modulename
  • 查看内核模块:
lsmod

内核模块的创建

编写内核模块代码

#include 
#include 
MODULE_LICENSE("Dual BSD/GPL");

static char *book_name = "dissecting Linux Device Driver";
static int num = 4000;

static int book_init(void)
{
	 printk(KERN_INFO " book name:%s\n",book_name);
	 printk(KERN_INFO " book num:%d\n",num);
	 return 0;
 }
 static void book_exit(void)
 {
	 printk(KERN_ALERT " Book module exit\n ");
 }
 module_init(book_init);
 module_exit(book_exit);
 module_param(num, int, S_IRUGO);
 module_param(book_name, charp, S_IRUGO);

 MODULE_AUTHOR("Song Baohua, [email protected]");
 MODULE_DESCRIPTION("A simple Module for testing module params");
 MODULE_VERSION("V1.0");

内核模块Makefile编写

obj-m := file.o
KDIR :=/home/arm/linux-mini2440
all: 
   make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
clean:
   rm -f *.o *.ko *.order

这是内核模块只有一个源文件的Makefile,如果源文件有多个,则采用如下版本:

obj-m := modulename.o

modulename-objs := file1.o file2.o file3.o  ......
KDIR :=/home/arm/linux-mini2440
all: 
   make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
clean:
   rm -f *.o *.ko *.order

然后回到代码所在目录执行make 命令,即可产生 .ko 文件。

你可能感兴趣的:(嵌入式linux驱动)