文章目录
- 目的:
- 为什么编译驱动程序之前要先编译内核?
- 编译内核
- 编译设备树
- 编译安装内核模块
- 编译内核模块
- 安装内核模块到 Ubuntu 的NFS目录下备用
- 安装内核和模块到开发板上
- 编译 led 驱动
- 在开发板安装驱动模块
- 下载驱动程序
- 安装驱动模块
目的:
- 在ubuntu环境下编译开发板的某个驱动,并挂载在开发板上运行
为什么编译驱动程序之前要先编译内核?
- 驱动程序要用到内核文件:
比如驱动程序中这样包含头文件:#include <asm/io.h>,其中的 asm 是一个链接文件,指向 asm-arm 或 asm-mips,这需要先配置、编译内核
才会生成 asm 这个链接文件。【内核、设备树、驱动】 - 编译驱动时用的内核、开发板上运行到内核,要一致:开发板上运行到内核是出厂时烧录的,你编译驱动时用的内核是你自己编译的,这两个内核不一致时会导致一些问题。所以我们编译驱动程序前,要把自己编译出来到内核放到板子上去,替代原来的内核。
更换板子上的内核后,板子上的其他驱动也要更换
:板子使用新编译出来的内核时,板子上原来的其他驱动也要更换为新编译出来的。所以在编译我们自己的第 1 个驱动程序之前,要先编译内核、安装内核模块、设备树,并且放到板子上去。
编译内核
- 不 同 的 开 发 板 对 应 不 同 的 配 置 文 件 , 配 置 文 件 位 于 内 核 源 码arch/arm/configs/目录。kernel 的编译过程如下:
cd 100ask_stm32mp157_pro-sdk/Linux-5.4/
make 100ask_stm32mp157_pro_defconfig
编译内核
make uImage LOADADDR=0xC2000040 -j8
编译设备树
make dtbs
编译完成后,在 arch/arm/boot 目录下生成 uImage 内核文件
, 在arch/arm/boot/dts 目录下生成设备树的二进制文件 stm32mp157c-100ask-512d-v1.dtb
。把这 2 个文件复制到/home/book/nfs_rootfs 目录下
cp arch/arm/boot/uImage ~/nfs_rootfs/
cp arch/arm/boot/dts/stm32mp157c-100ask-512d-v1.dtb ~/nfs_rootfs/
编译安装内核模块
编译内核模块
进入内核源码目录后,就可以编译内核模块了:
cd /home/book/100ask_stm32mp157_pro-sdk/Linux-5.4
make ARCH=arm CROSS_COMPILE=arm-buildroot-linux-gnueabihf- modules -j8
会生成ko驱动文件
安装内核模块到 Ubuntu 的NFS目录下备用
后面会使用 tree 命令查看目录结构,如果提示没有该命令,需要执行以下命令安装 tree 命令:
sudo apt install tree
cd /home/book/100ask_stm32mp157_pro-sdk/Linux-5.4
make ARCH=arm INSTALL_MOD_PATH=/home/book/nfs_rootfs INSTALL_MOD_STRIP=1 modules_install
安装好驱动后的/home/book/nfs_rootfs/目录结构如图所示
安装内核和模块到开发板上
接下来要把这些文件复制到开发板上。假设 Ubuntu IP 为 192.168.5.11,在开发板上执行以下命令:
mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt
mount /dev/mmcblk2p2 /boot #内核设备树放在/dev/mmcblk2p2分区,需要挂载在开发板的boot
cp /mnt/uImage /boot #拷贝内核到boot目录
cp /mnt/*.dtb /boot #拷贝设备树到boot目录
cp /mnt/lib/modules /lib -rfd #拷贝模块到lib目录,r是递归复制,f是保持链接属性
sync #强制刷新到flash中
reboot
最后重启开发板,输入uname -a
查看内核是否改变,发现使用新的 zImage、dtb、模块了。
编译 led 驱动
从 Windows 上通过 filezilla 把源码传到 Ubuntu的nfs共享文件夹中。
首先,进入上传文件夹的目录,修改 Makefile 文件“KERN_DIR”为自己的内核所在路径:
KERN_DIR = /home/book/100ask_stm32mp157_pro-sdk/Linux-5.4
在makefile目录的路径下执行“make ”命令就可以编译,编译完成后会生成 led_drv.ko 和ledtest 两个文件。
在开发板安装驱动模块
下载驱动程序
将驱动程序从nfs文件夹下拷贝出来
cp /mnt/led_drv.ko ./
cp /mnt/ledtest ./
安装驱动模块
在开发板串口终端上执行如下命令,即可安装相应的驱动模块。
insmod led_drv.ko
安装完成后可以执行 lsmod 命令来查看是否安装成功,如果有led drv则表示成功
lsmod
执行结果
执行测试程序
驱动模块安装成功后,就可以使用测试程序来控制 led 灯的状态,如图所示,操作 led 灯时可同时观察开发板串口旁的灯是否有亮灭的变化。
chmod +x ./ledtest
./ledtest /dev/myled on // 打开 led0 灯
./ledtest /dev/myled off // 关闭 led0 灯
开发板上的绿色 LED 就是/dev 下的 myled,默认是开启了呼吸功能的,需要使用下面的命令关掉此功能:
echo none > /sys/class/leds/heartbeat/trigger
关闭呼吸灯再用驱动程序控制
echo none > /sys/class/leds/heartbeat/trigger
./ledtest /dev/myled on // 打开 led0 灯
./ledtest /dev/myled off // 关闭 led0 灯