0.准备条件

操作系统:VMware虚拟机中运行的Debian 9
采用的内核:linux4.9

1.下载linux源代码

debian或ubuntu下,使用apt工具下载linux源码(或只下载头文件也可以)
centos使用yum

su
apt-get install -y linux-source

安装完成后应当能够在/usr/src中看到如下3个文件或文件夹:

dts@debian:~$ ls /usr/src/
linux-config-4.9 linux-patch-4.9-rt.patch.xz linux-source-4.9.tar.xz

2.将代码编译源代码

先解压源码包,并将合适的配置文件复制到源码文件夹下并重命名为.config

tar -xvf linux-source-4.9.tar.xz
xz -d linux-config-4.9/config.amd64_none_amd64.xz
mv linux-config-4.9/config.amd64_none_amd64 linux-source-4.9/.config

编译一遍源码,以确定没有问题。(至少要编译scripts运行脚本)

cd linux-source-4.9
make -j4

cd linux-source-4.9
make scripts/

3.了解Linux驱动相关命令和头文件

(1) 命令

#用于安装或删除一个模块 insmod rmmod

(2)obj-m makefile 符号, 内核建立系统用来决定当前目录下的哪个模块应当被建立

(3) linux/init.h

//用于指定模块的初始化和清理函数的宏定义. module_init(init_function); module_exit(cleanup_function);(3)struct task_struct *current

(4)linux/module.h

模块相关宏定义的头文件

(5)关于模块信息的常用宏

MODULE_AUTHOR(author); MODULE_DESCRIPTION(description); MODULE_VERSION(version_string); MODULE_DEVICE_TABLE(table_info); MODULE_ALIAS(alternate_name);

(6)int printk(const char * fmt, );//将字符串输出到内核调试信息

4.编写hello_world驱动

驱动文件hello_mod.c示例:

#include<linux/init.h>
 #include<linux/module.h>
MODULE_LICENSE("GPL");

static int hello_init(void)
{
    printk(KERN_ALERT "Hello,world\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT "Goodbye,world\n");
}

module_init(hello_init);
module_exit(hello_exit);

对应的makefile示例:

obj-m := hello_mod.o

KERNEL_DIR := /usr/src/linux-source-4.9
PWD := $(shell pwd)

all:
    make -C $(KERNEL_DIR) SUBDIRS=$(PWD) modules
clean:
    rm *.o *.ko

.PHONY:clean

5.编译(在makefile和hello.c)

root@debian:/home/dts/公共# make
make -C /usr/src/linux-source-4.9 SUBDIRS=/home/dts/公共 modules
make[1]: Entering directory '/usr/src/linux-source-4.9'

  WARNING: Symbol version dump ./Module.symvers
           is missing; modules will have no dependencies and modversions.

  CC [M]  /home/dts/公共/hello_mod.o
  Building modules, stage 2.
  MODPOST 1 modules
  LD [M]  /home/dts/公共/hello_mod.ko
make[1]: Leaving directory '/usr/src/linux-source-4.9'

6.安装和卸载

安装模块hello_mod
insmod hello_mod.ko
卸载模块
rmmod hello_mod

7.在内核调试信息中查看安装和卸载hello_mod时输出的调试信息

使用dmesg查看内核调试信息,可以发现末尾是hello_mod安装和卸载时的输出信息
╰─$ dmesg | tail
[17961.689403] cfg80211: (5170000 KHz - 5250000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2300 mBm), (N/A)
[17961.689406] cfg80211: (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2300 mBm), (0 s)
[17961.689408] cfg80211: (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 3000 mBm), (N/A)
[17961.689411] cfg80211: (57240000 KHz - 59400000 KHz @ 2160000 KHz), (N/A, 2800 mBm), (N/A)
[17961.689413] cfg80211: (59400000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 4400 mBm), (N/A)
[17961.689415] cfg80211: (63720000 KHz - 65880000 KHz @ 2160000 KHz), (N/A, 2800 mBm), (N/A)
[17961.835073] userif-2: sent link down event.
[17961.835078] userif-2: sent link up event.
[18024.538743] Hello,world
[18030.683052] Goodbye,world

 

提示:

1.编译时如果觉得在虚拟机中编译慢,可以多开几个核。开始只给了虚拟机一个核,结果编译的时候死机了…

2.insmod: ERROR: could not insert module hello_mod.ko: Invalid module format 出现该错误时,请检查当前系统内核和使用的源码是否为一个版本。

3.Makefile:671: scripts/Makefile.gcc-plugins: 没有那个文件或目录 编译时出现该类错误,请在源码目录下执行make scripts/

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐