0%

字符设备驱动代码添加到内核源码树

字符设备驱动代码添加到内核源码树

1 静态加载

1.1 移动驱动设备源码文件

1
$ cp hello_dev.c ~/workspace/c/src/linux-4.9.229/drivers/char/
  • 将字符设备驱动源码文件拷贝到 linux 内核源码的 drivers/char 目录下

1.2 修改 Kconfig 文件

  • 在 drivers/char 目录下的 Kconfig 文件中添加如下几行,
1
2
3
4
5
config HELLO_DEV
tristate "hello device"
default y
help
hello device
  • config 关键字后面跟着的是在 make menuconfig 中的配置项名称
  • 关于 tristate ,前缀 tri- 表示“三”,state 表示“状态”,也就是说这个模块可以有三种状态:y(编译进内核)、m(作为独立模块编译)、n(不被编译)
  • 如果是 bool 则说明这个模块只有两种状态:y(编译进内核)、n(不被编译)
  • default 后面跟着模块的默认状态,当前是 y(编译进内核)
  • help 后面的内容是此模块的帮助信息

1.3 查看修改后的配置

  • 执行 make menuconfig 命令可视化查看配置信息,
1
$ make menuconfig

img

选择 Device Drivers 进入,

img

选择 Character devices 进入,

img

字符设备驱动模块 hello device 确实出现在列表中,左侧的 “*” 表示 built-in,即将此模块编译到内核中,如果是 “M” 表示作为独立模块编译,“[]” 表示不编译此模块

  • 选择 Help 进入,

img

可以看到 hello_dev 模块的帮助信息

1.4 修改 Makefile 文件

  • 在 drivers/char 目录下的 Makefile 文件添加以下内容,
1
obj-$(CONFIG_HELLO_DEV)   += hello_dev.o

1.5 编译 linux 内核

  • 在 linux 内核源码根目录下执行 make 命令,
1
$ make -j4

2 动态加载

2.1 静态加载、动态加载的区别

  • 静态加载:驱动源码被编译到内核里面,随着内核启动,不需要手动通过 insmod 命令加载
  • 动态加载:驱动作为独立模块编译,生成 .ko 文件,需要在内核启动后,手动或者通过脚本的形式执行 insmod 命令加载设备驱动模块

2.2 修改编译配置文件

  • 执行 make menuconfig,
1
$ make menuconfig

依次选择 Device Drivers -> Character devices 进入,

img

配置 hello device 驱动作为独立模块编译,

img

2.3 编译 linux 内核

  • 在 linux 内核源码根目录下执行 make 命令,
1
$ make -j4

2.4 查看编译产物

  • 切换到 hello_dev 驱动源码所在目录,
1
$ cd drivers/char/

确认是否存在对应的 .ko 文件,

1
2
$ ll hello_dev.ko
-rw-rw-r-- 1 lnhoo lnhoo 5535 Nov 13 20:51 hello_dev.ko