赞
踩
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)驱动源码一般都是从设备厂商处获取; (2)设备厂商给的驱动源码大体上是没有问题的,能加载但是效果不一定好,需要根据自己的板子进行适配;
(1)直接编译进内核:内核启动时自动加载,无须在启动脚步中用insmod加载驱动。坏处是默认加载,没法使之不加载,不灵活,适合一些必须加载的驱动; (2)单独编译成ko文件:需要内核启动后,用insmod命令手动加载驱动,好处是十分灵活,可以根据需要去选择是否加载驱动;
驱动调试阶段,推荐使用.ko文件方便。深入了解内核驱动加载机制,是另一门学问了。
(1)将驱动代码放到内核源码中合适路径下。内核源码是十分复杂的,源码都按照功能进行了分类,要按照分类来选择驱动代码存放的位置,不要破坏内核源码的结构,便于后期维护; (2)将驱动源码添加到Makefile中,使之能被编译链接; (3)在Kbuild体系中添加驱动代码的选项,也就是在"make menuconfig"中能对驱动代码进行配置; (4)分别测试直接编译进内核和单独编译成ko文件,两种方式是否都能正常工作;
要做好笔记,对于如何使用Makefile,修改Makefile(尤其是其中的路径等环境变量的配置)。重点中的重点!
编译好可用的镜像后进行烧录,首先查找相关的驱动:
lsmod | grep mii
lsmod | grep ax_usb_nic.ko
// 确实没有
查看驱动的Makefile文件,发现是用于编译机x86架构的编译,编译后的驱动文件只能用于编译机,嵌入式设备上一定是无法安装。因此要修改makefile。这一步很有讲究。
编译内核代码。
驱动文件在编译的过程中,包含和链接了大量的内核头文件、功能库。当本机编译x86的主机版时不需要先编译内核是因为系统本身自带自身系统的内核头文件和可供链接的库,且默认的Makefile文件指向了这些路径。所以可以在Makefile中看到使用了原系统上build中的Makefile。而在交叉编译时,编译机上并没有嵌入式的内核相关文件供包含供链接,因此需要先编译嵌入式版本的内核。
从厂家官网下载的驱动文件目录内的Makefile文件默认用于编译运行X86架构的系统上,要想在交叉编译嵌入式版本并在板子上运行,需要修改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 = nobj-m := $(TARGET).o
$(TARGET)-objs := ax_main.o ax88179_178a.o ax88179a_772d.o
EXTRA_CFLAGS = -fno-pie
TOOL_EXTRA_CFLAGS = -Werrorifeq ($(ENABLE_IOCTL_DEBUG), y)
EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
TOOL_EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
endififeq ($(ENABLE_AUTODETACH_FUNC), y)
EXTRA_CFLAGS += -DENABLE_AUTODETACH_FUNC
endififeq ($(ENABLE_MAC_PASS), y)
EXTRA_CFLAGS += -DENABLE_MAC_PASS
endififeq ($(ENABLE_DWC3_ENHANCE), y)
EXTRA_CFLAGS += -DENABLE_DWC3_ENHANCE
ifeq ($(ENABLE_INT_POLLING), n)
EXTRA_CFLAGS += -DENABLE_INT_POLLING
endif
endififeq ($(ENABLE_AUTOSUSPEND), y)
EXTRA_CFLAGS += -DENABLE_AUTOSUSPEND
endififeq ($(ENABLE_TX_TASKLET), y)
EXTRA_CFLAGS += -DENABLE_TX_TASKLET
endif
ifeq ($(ENABLE_RX_TASKLET), y)
EXTRA_CFLAGS += -DENABLE_RX_TASKLET
endifEXTRA_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
endifall:
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 axcmdinstall:
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 -auninstall:
ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko))
rm -f /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko
endif
depmod -aclean:
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中指定,但是因为后续每次编译都要使用,所以很不推荐)。
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 = nobj-m := $(TARGET).o
$(TARGET)-objs := ax_main.o ax88179_178a.o ax88179a_772d.o
EXTRA_CFLAGS = -fno-pie
TOOL_EXTRA_CFLAGS = -Werrorifeq ($(ENABLE_IOCTL_DEBUG), y)
EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
TOOL_EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
endififeq ($(ENABLE_AUTODETACH_FUNC), y)
EXTRA_CFLAGS += -DENABLE_AUTODETACH_FUNC
endififeq ($(ENABLE_MAC_PASS), y)
EXTRA_CFLAGS += -DENABLE_MAC_PASS
endififeq ($(ENABLE_DWC3_ENHANCE), y)
EXTRA_CFLAGS += -DENABLE_DWC3_ENHANCE
ifeq ($(ENABLE_INT_POLLING), n)
EXTRA_CFLAGS += -DENABLE_INT_POLLING
endif
endififeq ($(ENABLE_AUTOSUSPEND), y)
EXTRA_CFLAGS += -DENABLE_AUTOSUSPEND
endififeq ($(ENABLE_TX_TASKLET), y)
EXTRA_CFLAGS += -DENABLE_TX_TASKLET
endif
ifeq ($(ENABLE_RX_TASKLET), y)
EXTRA_CFLAGS += -DENABLE_RX_TASKLET
endifEXTRA_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
endifall: // 这里是重点!!!
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 axcmdinstall:
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 -auninstall:
ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko))
rm -f /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko
endif
depmod -aclean:
make -C $(KDIR) M=$(PWD) clean
rm -rf *_programmer *_ieee axcmd .tmp_versions
调用真正的执行编译任务的Makefile时直接指定使用的ARCH,CC(编译器),LD(链接器)即可。注意KDIR要修改为内核源码目录。
也就是主要修改的地方
ARCH=arm64 CC=aarch64-none-linux-gnu-gcc LD=aarch64-none-linux-gnu-ld
// 放置位置视不同的厂家Makefile源码而定。
# 修改前:
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
# 修改前:
DEST = /lib/modules/$(CURRENT)/kernel/$(MDIR)
# 修改后:
DEST = ..
// 很多其实可以不用动
Makefile中设定了一些变量,比如"-C"指定了源文件路径,"-M"制定了模块的目录,又调用了kernel源码中的Makefile进行modules进行编译。
编译好的 .ko 文件复制到板子上,执行如下命令:
insmod 即可.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。