1.简述第三方驱动移植的方法(可以举例说明)

第三方驱动移植大体可分两种,第一种是直接编译进内核,第二种是以模块化的方式动态加载。
下面分别阐述两种移植方式:

第三方驱动移植流程--直接编译

  1. 将 fs4412_led_drv.c 保存到 linux-5.4.79/drivers/char 字符驱动文件夹中。
  2. 修改 Makefile
  3. 编译内核,获取uImage文件,
make -j6 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
mkimage -A arm -O linux -T kernel -C none -a 0x41000000 -e 0x41000040 -n "aaa" -d zImage uImage

观察现象

linux@ubuntu:~/Level10/day6/linux-5.4.79$ make -j6 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
  CALL    scripts/atomic/check-atomics.sh
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  CC      drivers/char/fs4412_led_drv.o                 //发现已经被编译进去
drivers/char/fs4412_led_drv.c:81:8: warning: return type defaults to 'int' [-Wreturn-type]
  AR      drivers/char/built-in.a
  AR      drivers/built-in.a
  GEN     .version
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  AR      init/built-in.a
  LD      vmlinux.o
  MODPOST vmlinux.o
WARNING: "return_address" [vmlinux] is a static EXPORT_SYMBOL_GPL
  MODINFO modules.builtin.modinfo
  LD      .tmp_vmlinux.kallsyms1
  KSYM    .tmp_vmlinux.kallsyms1.o
  LD      .tmp_vmlinux.kallsyms2
  KSYM    .tmp_vmlinux.kallsyms2.o
  LD      vmlinux
  SORTEX  vmlinux
  SYSMAP  System.map
  Building modules, stage 2.
  MODPOST 105 modules
  OBJCOPY arch/arm/boot/Image
  Kernel: arch/arm/boot/Image is ready
  GZIP    arch/arm/boot/compressed/piggy_data
  AS      arch/arm/boot/compressed/piggy.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready

  1. fs4412_led_app.c 交叉编译
arm-none-linux-gnueabi-cc fs4412_led_app.c
  1. 开发板上运行创建字符设备指令
mknod /dev/led c 501 0

  1. 开发板上运行a.out文件,观察结果:
[root@farsight ]# ./a.out
[  301.024579] led_open
[  301.025926] led on ..
open led ok
[  301.127968] led off ..
[  301.228970] led on ..
[  301.329883] led off ..
[  301.430882] led on ..
[  301.531795] led off ..
[  301.632796] led on ..
[  301.733709] led off ..
[  301.834709] led on ..
[  301.935623] led off ..

灯闪烁,运行正常。

图像化配置Kconfig

一般来讲每个文件夹下 都会有一个Makefile 对应一个Kconfig,二者之间必须联动,才能取得想要的效果。

  1. 修改 drivers/char/Kconfig,

  2. 执行命令 ,观察效果

linux@ubuntu:~/Level10/day6/linux-5.4.79$ make menuconfig


发现找到了刚添加进去的led选项,但现在更改此选项内核也不会发生改变,因为没有和Makefile形成联动

  1. 修改 drivers/char/Makefile

  2. 重新编译uImage,观察效果

[root@farsight ]# mknod /dev/led c 501 0
[root@farsight ]# ./a.out
open: No such device or address

取消led选中过后,再次执行,发现led的驱动的确没有编译进内核。

第三方驱动移植流程--编译驱动为独立的模块

  1. 编译模块 方式1
    独立创建个文件夹,把驱动 和 模块的Makefile复制过去,更改模块的Makefile适配驱动文件。
linux@ubuntu:~/develop/led$ make -j6 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

linux@ubuntu:~/develop/led$ ls
fs4412_led_drv.c  fs4412_led_drv.ko  fs4412_led_drv.mod  fs4412_led_drv.mod.c 
fs4412_led_drv.mod.o  fs4412_led_drv.o  Makefile  modules.order  Module.symvers
linux@ubuntu:~/develop/led$ 

fs4412_led_drv.ko文件 就是要的模块文件
  1. 编译模块 方式2
    到linux-5.4.79/drivers/char 目录下,找到 Kconfig 将该驱动模块的属性改成 tristate。
linux@ubuntu:~/Level10/day6/linux-5.4.79/drivers/char$ vim Kconfig

linux@ubuntu:~/Level10/day6/linux-5.4.79$ make modules -j6 ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

生成.ko模块文件(本方式是驱动放在内核文件夹下的生成.ko文件的方法,也可用 1. 配置为模块方式 中的的形式生成.ko文件)

  1. 加载驱动
[root@farsight ]# insmod fs4412_led_drv.ko
[  140.582962] fs4412_led_drv: loading out-of-tree module taints kernel.
[  140.589011] Led init  5
  1. 运行测试驱动的应用程序
[root@farsight ]# mknod /dev/led c 501 0
[root@farsight ]# ./a.out