开发者学堂课程【物联网开发-Linux 驱动开发实操演练:内核模块3】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/657/detail/10871
内核模块3
内容介绍:
一、编译工具
二、如何进行编译
三、内核编译的几种方法
四、外部编译
五、编译说明文档的介绍
六、编译 Makefile,并进行编译
一、编译工具
c 语言是一种编译型语言,c 语言源码写完之后,需要进行编译。在 Linux 里面,使用的是 gcc 编译器或交叉编译工具。
二、如何进行编译
编译内核代码需要使用内核的构建方法来构建内核模块,因为内核模块是基于内核来编写。
内核模块里面调用的函数,涉及的内容是由内核提供的,因此需要用到编写编译内核模块的 Makefile。
三、内核模块编译的几种方法
1. 内部编译
写的内核模块的源文件放在内核源码中进行编译。
2. 外部编译
将内核模块的源文件放在外面进行编译
3. 动态编译
编译生成动态模块xxx.ko
4. 静态编译
将内核模块编译进uImage中
5、几种方法的对比
用的较多的为外部编译,因为现在正处于开发阶段,编写完之后的理想状态是可以动态的加载和卸载。
如果将编译放在 uimage 里面,当需要进行调试的时候,就需要用到 uimage 倾向,操作更加繁琐。
如果编译生成一个模块,这样会更加灵活。例如,在调试的时候加载到内核,将内核卸载出来,再重新对这个内核进行编译,编译完在插入到内核里面,进行测试,更加符合当前的实际。
静态编译和内部编译需要修改里面的 Kconfig Makefile。修改完成后,需要去配置make menuconfig。
编译内核模块:
编译器:gcc 交叉编译工具
编写编译内核模块的 Makefile
内部编译:将内核模块源文件放在内核源码中进行编译
静态编译:将内核模块编译进 uImage 中
外部编译:将内核模块源文件放在内核源码外进行编译
动态编译:编译生成动态模块 xxx.ko
四、外部编译
关于内核如何编写,提供了一个说明文档,即内核源码:
进入内核源码之后,进入 document 之后,有一个文档目录:
文档里面有一个 kbuilds ls 的目录,有一个 modules.txt 文档:
此文档描述的是,在外部构建时,如何构建一个内核模块:
l Building External_Modules
3This document describes how to build an out-of-tree kernel module.
5 ===Table of Contents
7 === 1 Introduction
8 === 2 How to Build External Modules
9 --- 2.1 Command Syntax
0 --- 2.2 Options
1 --- 2.3 Targets
2 --- 2.4 Building Separate Files
3 === 3. Creating a Kbuild File for an External Module
4 --- 3.1 Shared Makefile
5 --- 3.2 Separate Kbuild file and Makefile
6 --- 3.3 Binary Blobs
7 --- 3.4 Building Multiple Modules
8 === 4. Include Files
9 --- 4.1 Kernel Includes
0 --- 4.2 Single Subdirectory
1 --- 4.3 Several Subdirectories
2 === 5. Module Installation
34 --- 5.1 INSTALL MOD PATH
--- 5.2 INSTALL MOD DIR
5 === 6. Module Versioning
6 --- 6.1 Symbols From the Kernel (vmlinux + modules)
78 --- 6.2 Symbols and External Modules
--- 6.3Symbols From Another External Module
9 ===7.Tips & Tricks
里面包含了介绍和每个命令的说明,最后也列举了一些例子。因此,可以根据说明文档去编译一个内核模块。
五、编译说明文档的介绍
例如语句:
54 NOTE:"modules prepare" will not build Module.symvers even if
55 CONFIG MODVERSIONSis set;therefore, a full kernel build needs to be
56executed to make module versioning work.
57
58---2.1 Command Syntax
59
10 The command to build an external module is:
$ make -Ckpath to_kernel Src> M=SPWD
13
74 The kbuild system knows that an external module is being built
15 due to the "M=
" option given in the command.
16
17 To build against the running kernel use:
18
19 s make -C /1ib/modules/`uname -r /build M=SPWD
30
31 Then to install the module(s) just built, add the target
32 "modules_install" to the command:
33
34 s make -C /lib/modules/ uname -r /build M=SPWD modules_install
35
36---2.2 Options
37
38 (SKDIR refers to the path of the kernel source directory.)
19
例如语句“”72 $ make -e M=$pwd”
此语句是要执行一个 Makefile,-c 指的是到指定的路径下,去执行该路径的Makefile,M=$pwd 指向的是当前的路径。
79 $ make -c /lib/modules/uname -r
’
/build > M=$pwd
lib/modules/uname -r
’
/build
为一个命令置换。将此条语句执行完之后,将输出结果放在此处。
3.2.0-29是当前版本,进入3.2.0-29,发现里面有一个 build。进入 build 之后,里面有一个目录:
上面为内核的目录结构。
如果需要将其编译到具体的平台上,用得到的内核源码,应该指定 /kernel-3.4-3.9
。
该文档中,还有许多的内核源码,都做了详细的说明。
六、编写Makefile,并进行编译
进行编译之后,生成一个.ko的模块,并测试能否使用。
1. 编写Makefile
编写一个目标,相当于一个伪目标,接下来编写规则,指定内核的路径:kernel.dir,制定M=$(PWD),执行PWD的命令,将结果赋值给当前变量。
编译目标,这个目标为 modules 的目标和一个 clear 的目标,使用内核的目录下去清除,即在 kernel 的命令去执行。
指定.to 是依赖于哪一个.o生成。此处为依赖于 demo.o 生成的文件。
1
2KERNDIR:= /lib/modules/3.2.0-29-generic-pae/build/
3 PWD:=$(shell pwd)
5 obi-m:=demo.o
7 all:
8 make -C $(KERNDIR) M=$(PWD) modules
10 clean:
11 make -C $(KERNDIR) M=$(PWD) clean
12
2. 编译Makefile
将 demo.c 复制后进行编译:
edu@edu-T:~/work/test$ 1s
demo.c Makefile
edu@edu-T:-/work/test make
make -C /lib/modules/3.2.0-29-generic-pae/build/ M=/home/edu/work/test modulesmake[1]:
正在进入目录
/usr/src/linux-headers-3.2.0-29-generic-pae
CC [M]/home/edu/work/test/demo.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/edu/work/test/demo.mod.o
LD [M] /home/edu/work/test/demo.ko
make 1]:
正在离开目录
/usr/src/iinux-headers-3.2.0-29-generic-pae'
edu@edu-T:~/work/test$
在当前目录下查看 demo.ko 的文件:
edu@edu-T:~/work/test 15:39 edu
edu@edu-T:-/work/test$ 1s
demo.c demo.ko demo.mod.c demo.mod.o demo.o Makefile modules.order Module.symvers
edu@edu-T:-/work/test$
对于当前的 demo.ko 来说,可以插入到当前乌班图的内核里面,和乌班图形成整体来运行。