由于嵌入式系统分层,应用层要想操作硬件需通过内核层。驱动对上提供系统调用函数,对下封装了对底层硬件的一些基本操作。笔者目前不了解驱动程序的编辑,所以本章是在已经有驱动程序(fs4412_led_drv.c)和对应的应用程序(fs4412_led_app.c),来实现黑盒子移植(不去理解驱动程序的细节),实现控制led灯的闪烁。

  • led驱动程序 fs4412_led_drv.c
  • led控制程序 fs4412_led_app.c

 

通过驱动模块的方式,每次运行应用程序前手动加载模块,减少内核的开支。

 

 

1.添加驱动程序到内核源码的一个路径 

root@linux:~# cp fs4412_led_drv.c /root/linux-4.19.1/drivers/char

 

2.配置同级目录下的Kconfig 和 Makefile文件

Kconfig

config  FS4412_LED
        tristate "FS4412 LED Driver Support"
        depends on ARCH_EXYNOS4
        help
                support led device on FS4412 develop board
 

Makefile

obj-$(CONFIG_FS4412_LED)        += fs4412_led_drv.o
 

3.make menuconfig 进行内核选配,把刚刚指定的驱动指定为模块方式添加(M)

 

4.到内核根目录,make modules 生成模块

 

5.make uImage 编译内核,将驱动编译生成的模块移动到nfs跟文件系统下

root@linux:~/linux-4.19.1/drivers/char# cp fs4412_led_drv.ko /nfs/rootfs

 

6.把内核覆盖到 tftp跟目录下

cp arch/arm/boot/uImage /tftpboot/
 

7.编译应用程序,并将应用程序移动到nfs跟文件系统下

root@linux:~# arm-none-linux-gnueabi-gcc fs4412_led_app.c

root@linux:~# cp a.out /nfs/rootfs

 

板子上电,运行内核,挂载成功nfs后,串口输入

[root@farsight ]# ls
[root@farsight ]# insmod fs4412_led_drv.ko
[root@farsight ]# mknod /dev/led c 500 0
[root@farsight ]# ./a.out

ps:insmod 加载模块;mknod 关联设备。500是主设备号  0此设备号,在驱动程序里可以找到;a.out 可执行文件。

 

 

为了方便,也可以把编译驱动,这个部分剥离出去。使用下面的Makefile文件编译

ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /root/linux-4.19.1
PWD := $(shell pwd)

all:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
        rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules* a.out

else
    obj-m := fs4412_led_drv.o
endif

 

ps:KERNELDIR ?= /root/linux-4.19.1 ,指定内核的路径,这里借用内核根目录的Makefile文件进行编译;

       obj-m := fs4412_led_drv.o ,fs4412_led_drv.o是指定目标文件

 

make 之后,将生成的fs4412_led_drv.o文件添加到内核源码,驱动模块 fs4412_led_drv.ko添加到nfs跟目录。