当前位置:   article > 正文

内核添加驱动——USB转网口驱动

内核添加驱动——USB转网口驱动
共享文件夹如何挂载

sudo umount /mnt/hgfs // 显示没有就创建
sudo /usr/bin/vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other -o uid=0 -o gid=0 -o umask=022

最近遇到了板端不方便(或者很麻烦)编译驱动进行挂载的问题,这边想学习一下如何将一些常用的驱动直接编译进入内核。

这边不负责编写,主要负责探讨如何添加驱动这个问题。也就是将大体流程梳理清除。(当然,能梳理清楚就已经很不错了。。。)

添加驱动的步骤详解

 

1. 获取驱动源码

(1)驱动源码一般都是从设备厂商处获取; (2)设备厂商给的驱动源码大体上是没有问题的,能加载但是效果不一定好,需要根据自己的板子进行适配;

2. 驱动在内核中的两种形式

(1)直接编译进内核:内核启动时自动加载,无须在启动脚步中用insmod加载驱动。坏处是默认加载,没法使之不加载,不灵活,适合一些必须加载的驱动; (2)单独编译成ko文件:需要内核启动后,用insmod命令手动加载驱动,好处是十分灵活,可以根据需要去选择是否加载驱动;

驱动调试阶段,推荐使用.ko文件方便。深入了解内核驱动加载机制,是另一门学问了。

3. 添加驱动步骤

(1)将驱动代码放到内核源码中合适路径下。内核源码是十分复杂的,源码都按照功能进行了分类,要按照分类来选择驱动代码存放的位置,不要破坏内核源码的结构,便于后期维护; (2)将驱动源码添加到Makefile中,使之能被编译链接; (3)在Kbuild体系中添加驱动代码的选项,也就是在"make menuconfig"中能对驱动代码进行配置; (4)分别测试直接编译进内核和单独编译成ko文件,两种方式是否都能正常工作;

USB转网口驱动

1. 思路一:优先选择交叉编译环境生成 .ko 文件,进行挂载使用。(还可以集成到内核中)over,已经可以使用

要做好笔记,对于如何使用Makefile,修改Makefile(尤其是其中的路径等环境变量的配置)。重点中的重点!

1. 检查驱动

编译好可用的镜像后进行烧录,首先查找相关的驱动:

 lsmod | grep mii
lsmod | grep ax_usb_nic.ko
// 确实没有

查看驱动的Makefile文件,发现是用于编译机x86架构的编译,编译后的驱动文件只能用于编译机,嵌入式设备上一定是无法安装。因此要修改makefile。这一步很有讲究。  

2. 检查和安装交叉编译环境

编译内核代码。

安装驱动,为什么要先编译内核?

驱动文件在编译的过程中,包含和链接了大量的内核头文件、功能库。当本机编译x86的主机版时不需要先编译内核是因为系统本身自带自身系统的内核头文件和可供链接的库,且默认的Makefile文件指向了这些路径。所以可以在Makefile中看到使用了原系统上build中的Makefile。而在交叉编译时,编译机上并没有嵌入式的内核相关文件供包含供链接,因此需要先编译嵌入式版本的内核。

3. 修改驱动的Makefile

从厂家官网下载的驱动文件目录内的Makefile文件默认用于编译运行X86架构的系统上,要想在交叉编译嵌入式版本并在板子上运行,需要修改Makefile文件。

厂家Makefile源码:( 其实大多数都没用 ...)

TARGET    = ax_usb_nic
KDIR    := /lib/modules/$(shell uname -r)/build
PWD    = $(shell pwd)

ENABLE_IOCTL_DEBUG = n
ENABLE_AUTODETACH_FUNC = n
ENABLE_MAC_PASS = n
ENABLE_DWC3_ENHANCE = n
ENABLE_INT_POLLING = n
ENABLE_AUTOSUSPEND = n
ENABLE_TX_TASKLET = n
ENABLE_RX_TASKLET = n

obj-m := $(TARGET).o
$(TARGET)-objs := ax_main.o ax88179_178a.o ax88179a_772d.o
EXTRA_CFLAGS = -fno-pie
TOOL_EXTRA_CFLAGS = -Werror

ifeq ($(ENABLE_IOCTL_DEBUG), y)
    EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
    TOOL_EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
endif

ifeq ($(ENABLE_AUTODETACH_FUNC), y)
    EXTRA_CFLAGS += -DENABLE_AUTODETACH_FUNC
endif

ifeq ($(ENABLE_MAC_PASS), y)
    EXTRA_CFLAGS += -DENABLE_MAC_PASS
endif

ifeq ($(ENABLE_DWC3_ENHANCE), y)
    EXTRA_CFLAGS += -DENABLE_DWC3_ENHANCE
ifeq ($(ENABLE_INT_POLLING), n)
    EXTRA_CFLAGS += -DENABLE_INT_POLLING
endif
endif

ifeq ($(ENABLE_AUTOSUSPEND), y)
    EXTRA_CFLAGS += -DENABLE_AUTOSUSPEND
endif

ifeq ($(ENABLE_TX_TASKLET), y)
    EXTRA_CFLAGS += -DENABLE_TX_TASKLET
endif
ifeq ($(ENABLE_RX_TASKLET), y)
    EXTRA_CFLAGS += -DENABLE_RX_TASKLET
endif

EXTRA_CFLAGS += -DENABLE_AX88279

ifneq (,$(filter $(SUBLEVEL),14 15 16 17 18 19 20 21))
MDIR    = kernel/drivers/usb/net
else
MDIR    = kernel/drivers/net/usb
endif

all:
    make -C $(KDIR) M=$(PWD) modules
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179_programmer.c -o ax88179_programmer
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_programmer.c -o ax88179b_179a_772e_772d_programmer
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_ieee.c -o ax88179b_179a_772e_772d_ieee
    $(CC) $(TOOL_EXTRA_CFLAGS) axcmd.c -o axcmd

install:
ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/ax88179_178a.ko))
    gzip /lib/modules/$(shell uname -r)/$(MDIR)/ax88179_178a.ko
endif
    make -C $(KDIR) M=$(PWD) INSTALL_MOD_DIR=$(MDIR) modules_install
    depmod -a

uninstall:
ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko))
    rm -f /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko
endif
    depmod -a

clean:
    make -C $(KDIR) M=$(PWD) clean
    rm -rf *_programmer *_ieee axcmd .tmp_versions

 可以看出,仅仅设置了一些最基本的路径相关的环境变量。这是因为这个Makefile不是最终控制编译过程的Makefile,针对不同的kernel编译驱动的时候,其实最终引用的是kernel源码中的Makefile,而这个Makfile主要作用在这里。

all:
    make -C $(KDIR) M=$(PWD) modules
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179_programmer.c -o ax88179_programmer
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_programmer.c -o ax88179b_179a_772e_772d_programmer
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_ieee.c -o ax88179b_179a_772e_772d_ieee
    $(CC) $(TOOL_EXTRA_CFLAGS) axcmd.c -o axcmd

 调用kernel中的Makefile中的modules部分,借助kernel源码中的库文件来编译驱动。所以后续设置交叉编译工具就直接在这个make 指令后添加才可以,在源Makfile中指定是没有用的(应该也可以在kernel中的Makfile中指定,但是因为后续每次编译都要使用,所以很不推荐)。

 

修改后的Makefile源码

TARGET    = ax_usb_nic
KDIR    := /home/xhz/Neardi/Neardi-3588-SDK-Linux-V3.0/kernel
PWD    = $(shell pwd)

CROSS_COMPILE = aarch64-none-linux-gnu-
CC = $(aarch64-none-linux-gnu)gcc
ARCH = arm64


ENABLE_IOCTL_DEBUG = n
ENABLE_AUTODETACH_FUNC = n
ENABLE_MAC_PASS = n
ENABLE_DWC3_ENHANCE = n
ENABLE_INT_POLLING = n
ENABLE_AUTOSUSPEND = n
ENABLE_TX_TASKLET = n
ENABLE_RX_TASKLET = n

obj-m := $(TARGET).o
$(TARGET)-objs := ax_main.o ax88179_178a.o ax88179a_772d.o
EXTRA_CFLAGS = -fno-pie
TOOL_EXTRA_CFLAGS = -Werror

ifeq ($(ENABLE_IOCTL_DEBUG), y)
    EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
    TOOL_EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
endif

ifeq ($(ENABLE_AUTODETACH_FUNC), y)
    EXTRA_CFLAGS += -DENABLE_AUTODETACH_FUNC
endif

ifeq ($(ENABLE_MAC_PASS), y)
    EXTRA_CFLAGS += -DENABLE_MAC_PASS
endif

ifeq ($(ENABLE_DWC3_ENHANCE), y)
    EXTRA_CFLAGS += -DENABLE_DWC3_ENHANCE
ifeq ($(ENABLE_INT_POLLING), n)
    EXTRA_CFLAGS += -DENABLE_INT_POLLING
endif
endif

ifeq ($(ENABLE_AUTOSUSPEND), y)
    EXTRA_CFLAGS += -DENABLE_AUTOSUSPEND
endif

ifeq ($(ENABLE_TX_TASKLET), y)
    EXTRA_CFLAGS += -DENABLE_TX_TASKLET
endif
ifeq ($(ENABLE_RX_TASKLET), y)
    EXTRA_CFLAGS += -DENABLE_RX_TASKLET
endif

EXTRA_CFLAGS += -DENABLE_AX88279

ifneq (,$(filter $(SUBLEVEL),14 15 16 17 18 19 20 21))
MDIR    = kernel/drivers/usb/net
else
MDIR    = kernel/drivers/net/usb
endif

all:    // 这里是重点!!!
    make ARCH=arm64 CC=aarch64-none-linux-gnu-gcc LD=aarch64-none-linux-gnu-ld    -C $(KDIR) M=$(PWD) modules
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179_programmer.c -o ax88179_programmer
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_programmer.c -o ax88179b_179a_772e_772d_programmer
    $(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_ieee.c -o ax88179b_179a_772e_772d_ieee
    $(CC) $(TOOL_EXTRA_CFLAGS) axcmd.c -o axcmd

install:
ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/ax88179_178a.ko))
    gzip /lib/modules/$(shell uname -r)/$(MDIR)/ax88179_178a.ko
endif
    make -C $(KDIR) M=$(PWD) INSTALL_MOD_DIR=$(MDIR) modules_install
    depmod -a

uninstall:
ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko))
    rm -f /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko
endif
    depmod -a

clean:
    make -C $(KDIR) M=$(PWD) clean
    rm -rf *_programmer *_ieee axcmd .tmp_versions

 

 

重点在这里

 调用真正的执行编译任务的Makefile时直接指定使用的ARCH,CC(编译器),LD(链接器)即可。注意KDIR要修改为内核源码目录。

总结一下大体步骤

也就是主要修改的地方

1. 添加编译器、链接器

ARCH=arm64 CC=aarch64-none-linux-gnu-gcc LD=aarch64-none-linux-gnu-ld 
// 放置位置视不同的厂家Makefile源码而定。 

2. 修改KDIR指定的Linux内核路径为嵌入式LInux内核路径

# 修改前:
KDIR    = /lib/modules/$(CURRENT)/build
SUBLEVEL= $(shell uname -r | cut -d '.' -f 3 | cut -d '.' -f 1 | cut -d '-' -f 1 | cut -d '_' -f 1)

# 修改后
KDIR = /home/xhz/Neardi/Neardi-3588-SDK-Linux-V3.0/kernel

 3. 修改编译后的目标路径

# 修改前:
DEST = /lib/modules/$(CURRENT)/kernel/$(MDIR)
# 修改后:
DEST = ..
// 很多其实可以不用动

4. 编译驱动
Makefile中设定了一些变量,比如"-C"指定了源文件路径,"-M"制定了模块的目录,又调用了kernel源码中的Makefile进行modules进行编译。
5. 安装驱动

编译好的 .ko 文件复制到板子上,执行如下命令:

insmod 即可.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/982553
推荐阅读
相关标签
  

闽ICP备14008679号