orangepi3 lts动态加载驱动

orangepi3 lts驱动编译

源码下载

按照手册指示从github下载或直接从百度网盘下载

git clone https://github.com/orangepi-xunlong/orangepi-build.git
# 百度网盘 https://pan.baidu.com/share/init?surl=vWQmCmSYdH7iCDFyKpJtVw
# 密码     zero
# 里面有几个源码文件
# orangepi-build是旧版本的源码文件
# orangepi-build-h6支持linux4.9,linux5.3,linux5.10三个版本,是相对稳定版本
# orangepi-build-new支持linux5.10,linux5.16是比较新的版本
# orangepi-build-rk3399是rk3399的源码,不是orangepi3 lts源码
# 推荐下载第二个或第三个

源码配置

下载完成后需要配置下,不然会有更新操作,国内的网络连github太费时间了。

# 解压
tar zxvf orangepi-build-h6
cd orangepi-build

# 不更新文件
cd userpatches
vi config-default.conf
# 关闭更新
IGNORE_UPDATES="yes"
# 不配置内核选项
KERNEL_CONFIGURE="no"

cd scripts
vi main.sh
# 搜索到 CTHREADS="-j1",改为-j8。强制使用多核心编译
CTHREADS="-j8"

内核编译

# 编译内核
sudo ./build.sh
# 1. 选Kernel package
# 2. 选主板orangepi3-lts
# 3. 选分支,根据自己情况选择
# 4. 等待编译生产debs文件,生成的dtb文件位置:output/debs
linux-dtb-current-sunxi64_2.1.6_arm64.deb
linux-headers-current-sunxi64_2.1.6_arm64.deb
linux-image-current-sunxi64_2.1.6_arm64.deb
# 这三个文件都传递到开发板,可以用ftp,scp

安装内核到开发板

登陆开发板,找到传递过去的三个deb包。先卸装旧版本的再安装新编译的。

# 卸装原来的
# 根据自己开发板上安装的包卸装
dpkg --list |grep linux-
sudo apt purge -y linux-dtb-current-sunxi64
sudo apt purge -y linux-headers-current-sunxi64
sudo apt purge -y linux-image-current-sunxi64
# 安装新编译的包
sudo dpkg -i linux-*

驱动编写

/*************** file: hello.c  ******************/
#include 
#include 


int __init hello_init(void);
void __exit hello_exit(void);

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

int __init hello_init(void){
        printk(KERN_INFO"hello init!!!\n");
        return 0;
}

void __exit hello_exit(void){
        printk(KERN_INFO"Hello exit!!!n");
}
/**************** end of hello.c **********************/

/**************** Makefile ****************************/
# 这里编译是直接在开发板上已经运行的系统上编译,所以不用指定ARCH和CROSS_COMPILE>选项
# 防止加载模块时:module verification failed : signature and/or required key missing - tainting kernel
CONFIG_MODULE_SIG=n
# 板子上的headers文件目录
KERNDIR:=/lib/modules/5.10.75-sunxi64/build
PWD:= $(shell pwd)

obj-m:= hello.o

all:
  make -C $(KERNDIR) M=$(PWD) modules

clean:
  make -C $(KERNDIR) M=$(PWD) clean
/******************* end of Makefile ******************/

编译驱动模块

其实正常外部编译驱动模块应该有2种方法:

  1. 使用linux相同版本的源码文件指定ARCH和CROSS_COMPILE编译
  2. 就是本文采用的方法,在已经运行的系统上编译,源码指向headers目录

开始我是想使用方法一编译的,其它板子大部份教程也是使用的方法一编译。但在orangepi3 lts上是有问题的,我经过测试发现的问题如下:

  • 内核单独编译只能生成Image格式文件,不能生成uImage和zImage
  • 内核编译要加上特定变量ARCH=arm LOCALVERSION="sun50iw6"。第一个选项没啥说的选
    arm平台,第二个选项我是自己查看它的编译脚本自己提取出来的。
  • 驱动模块编译时也要加入前面两个选项,orangepi-build-new源码下的linux5.16内核编译完成后,编译驱动模块依然会出错误:cc1: error: plugin arm_ssp_per_task_plugin should be specified before ‘-fplugin-arg-arm_ssp_per_task_plugin-offset=1088’ in the command line
  • 同一版本内核编译的驱动模块,依然不能加载`ERROR: could not insert module hello.ko: Operation not permitted`

因此就只能直接在开发板的linux系统上编译,指定源码目录为/lib/modules/5.10.75-sunxi64/build。不用指定ARCH和CROSS_COMPILE变量。
编译好后使用insmod, modinfo,rmmod

最后用dmesg -C先清理一下系统日志,再用insmod加载,查看dmesg可以看到模块正常加>载了。

失败的探索

最开始我是按大多数驱动编写教程的方式,编译驱动模块只加入ARCH,CROSS_COMPILE和内核
目录位置三个参数,无论如何都不能编译通过,后来实在没有办法自己查看build.sh等脚本
文件才完成了单独内核文件编译。过程如下:

# 进入内核文件位置
cd orangepi-build/kernel/orange-pi-5.10
# 复制配置文件
make ARCH=arm sunxi_defconfig
# 编译
make ARCH=ARM -j8 CROSS_COMPILE=源码目录下toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/arm-none-linux-gnueabihf- LOCALVERSION="sun50iw6" Image modules

前面的Makefile文件也要加入ARCH,CROSS_COMPILE,KERNEL_SRC目录位置,变成好下形式:

/**************** Makefile ****************************/
# 这里编译是直接在开发板上已经运行的系统上编译,所以不用指定ARCH和`CROSS_COMPILE`选项
# 防止加载模块时:module verification failed : signature and/or required key missing - tainting kernel
CONFIG_MODULE_SIG=n
# 板子上的headers文件目录
KERNDIR:=orangepi-build(所在目录)/kernel/orange-pi-5.10
CROSS_COMPILE=源码目录下toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/arm-none-linux-gnueabihf-

obj-m:= hello.o

all:
  make -C $(KERNDIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) LOCALVERSION="sun50iw6" M=$(PWD) modules

clean:
  make -C $(KERNDIR) M=$(PWD) clean
/******************* end of Makefile ******************/

然后就是make生成hello.ko,但传递到开发板上后insmod加载就会出现问题。确定源码和开
发板运行的版本是一致的。目前未找到解决方法,希望那个谁能解下惑。

另外用最新的orangepi-build-new最新分支编译的linux-headers-next-sun50iw6_3.0.4_arm64.deb安装时报如下错误:

Selecting previously unselected package linux-headers-next-sun50iw6.
(Reading database ... 66857 files and directories currently installed.)
Preparing to unpack linux-headers-next-sun50iw6_3.0.4_arm64.deb ...
Unpacking linux-headers-next-sun50iw6 (3.0.4) ...
Setting up linux-headers-next-sun50iw6 (3.0.4) ...
Compiling headers - please wait ...
/bin/sh: 1: scripts/basic/fixdep: Exec format error
make[1]: *** [scripts/Makefile.host:112: scripts/kconfig/conf.o] Error 2
make[1]: *** Deleting file 'scripts/kconfig/conf.o'
make: *** [Makefile:621: oldconfig] Error 2
/bin/sh: 1: scripts/basic/fixdep: Exec format error
make[2]: *** [scripts/Makefile.host:112: scripts/kconfig/util.o] Error 2
make[2]: *** Deleting file 'scripts/kconfig/util.o'
make[2]: *** Waiting for unfinished jobs....
/bin/sh: 1: scripts/basic/fixdep: Exec format error
make[2]: *** [scripts/Makefile.host:112: scripts/kconfig/conf.o] Error 2
make[2]: *** Deleting file 'scripts/kconfig/conf.o'
/bin/sh: 1: scripts/basic/fixdep: Exec format error
make[2]: *** [scripts/Makefile.host:112: scripts/kconfig/confdata.o] Error 2
make[2]: *** Deleting file 'scripts/kconfig/confdata.o'
make[1]: *** [Makefile:621: syncconfig] Error 2
make: *** [Makefile:734: include/config/auto.conf.cmd] Error 2
make: *** [include/config/auto.conf.cmd] Deleting file 'include/generated/autoconf.h'

  ERROR: Kernel configuration is invalid.
         include/generated/autoconf.h or include/config/auto.conf are missing.
         Run 'make oldconfig && make prepare' on kernel src to fix it.

make: *** [Makefile:742: include/config/auto.conf] Error 1

因此目前使用最新的linux5.16分支安装header还是不行的,只能使用linux5.10分支编译的内核能完成驱动模块编译和动态安装

你可能感兴趣的:(orangepi,stm32,linux,linux,arm,stm32,物联网)