★树莓派目标系统配置:
① 下载最新的官方镜像文件,用Win32DiskImager软件制作TF系统盘(否则后面的操作有可能不会太顺利)。
镜像文件的官网下载页面 https://www.raspberrypi.org/downloads/raspbian/
镜像文件读写工具下载页面 https://sourceforge.net/projects/win32diskimager/
② 第一次启动后,第一件事是进行TF卡扩容。
由于官方镜像文件针对是4GB的TF卡,如果你使用的是4G以上的,那么剩余空间是没办法用的。
可以手工用fdisk进行处理,也可以使用官方的命令:raspi-config进行自动全量扩充,然后重启机器即可。
③ 执行rpi-update更新内核与固件。(即使当前系统是官方最新的镜像,也未必是最新版本)
rpi-update是Raspbian内置的更新内核和相关固件的脚本,它的逻辑是去 https://github.com/Hexxeh/rpi-firmware 这个仓库下载最新的内核和固件,替换现有的版本。更新完成后会更新/boot/.firmware_revision,记下最新版本对应的Git Hash,以后rpi-update或rpi-source都会根据这个Hash去GitHub找对应文件
可以在目标系统中,通过rpi-source获取与内核匹配的源码。
④ 检查当前gcc版本与生成当前内核所用的gcc的版本是否一致(如果不需要在目标系统上编译内核,可跳过此步骤)。
查看当前gcc的版本号:gcc --version
查看生成当前内核所用的gcc的版本:cat /proc/version(显示当前内核版本以及编译所用gcc的版本)
如果当前gcc版本为4.6,而当前内核编译所用的gcc版本是4.9,则最好升级当前的gcc版本到4.9:
可以直接sudo apt-get install gcc-4.9 g++-4.9,然后用update-alternatives设置优先级即可[1]:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 50
★上位机交叉编译环境配置:
●㈠ 安装交叉编译的操作系统
通过vmware搭建ubuntu虚拟机。
后面的操作默认都是在ubuntu虚拟机上完成。
●㈡ 安装git工具
$ sudo apt-get install git
●㈢下载安装交叉编译器(toolchain)
$ git clone --depth 1 git://github.com/raspberrypi/tools.git
克隆后,在本地得到一个tools目录。
安装工具链,实际上只要设置下路径的环境变量:
在~/.bashrc加入交叉编译工具的路径到环境变量,然后重启终端命令行(本人电脑是64位):
export PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
测试交叉编译环境是否配置成功:
输入命令$ arm-linux-gnueabihf-gcc -v 是否看到交叉编译器的版本信息。
●㈣下载编译linux内核源码
下载最新版本的树莓派系统内核:
$ git clone --depth 1 git://github.com/raspberrypi/linux.git
如果不需要升级更新目标系统的内核,只是为了开发设备驱动模块的话,那就要下载与目标系统内核版本一致的内核源码:
例如,直接获取具体内核版本 $ wget https://github.com/raspberrypi/linux/archive/rpi-4.1.y.tar.gz
如何查看当前树莓派内核版本,在树莓派系统中,通过命令cat /proc/version来查看当前raspbian(linux)内核版本。
源码下载后,配置/编译步骤如下:
① 进入内核源码目录
$ cd linux-src #假定linux-src为下载的源码目录
② 设置环境变量
$ KERNEL=kernel7
③ 配置内核(生成.config文件)
Δ生成默认的内核配置文件
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
参数说明:ARCH=arm 指令架构为arm;
编译器为arm-linux-gnueabihf-;
内核源码配置为bcm2709_defconfig;
Δ通过菜单互动进行配置
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
通过此命令也可以查看当前配置(确认时选择Cancel)
④ 正式编译内核(并生成 zImage modules dtbs)
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs
如果能够成功编译内核,说明内核模块的交叉编译环境搭建成功了。
⑤优化Makefile文件
可以修改Makefile,直接指定ARCH、CROSS_COMPILE这两个参数的值,简化make操作。
●㈤更新树莓派目标板内核
①将一张TF卡(必须已安装树莓派的系统镜像)通过读卡接入到PC上。
②将TF卡加载到ubuntu系统
$ lsblk #查看所有块设备
$ mkdir /mnt/fat32
$ mkdir /mnt/ext4
$ sudo mount /dev/sdb1 /mnt/fat32
$ sudo mount /dev/sdb2 /mnt/ext4
$ sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=/mnt/ext4 modules_install
$ sudo cp /mnt/fat32/$KERNEL.img /mnt/fat32/$KERNEL-backup.img
$ sudo scripts/mkknlimg arch/arm/boot/zImage /mnt/fat32/$KERNEL.img
$ sudo cp arch/arm/boot/dts/*.dtb /mnt/fat32/
$ sudo cp arch/arm/boot/dts/overlays/*.dtb* /mnt/fat32/overlays/
$ sudo cp arch/arm/boot/dts/overlays/README /mnt/fat32/overlays/
$ sudo umount /mnt/fat32
$ sudo umount /mnt/ext4
最后把TF卡插回到树莓派的卡槽,上电。
★交叉编写驱动模块
㈠ 示例Hello world模块的代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{ printk(KERN_ALERT"Hello, world\r\n");
return 0;
}
static void hello_exit(void)
{ printk(KERN_ALERT"Goodbye, cruel world\r\n");
}
module_init(hello_init);
module_exit(hello_exit);
㈡ 编写Makefile
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KDIR := ~/raspberrypi/linux_src
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*
endif
㈢ 执行make编译
会在当前目录下生成hello.ko文件。
必须确保内核源码版本以及内核配置文件信息与目标系统一致。
否则编译出的模块可能无法正确加载到目标系统中去运行。
一了百了的方法是,编译内核并更新目标系统。
㈣ 将hello.ko上传到嵌入式目标系统
树莓派系统默认会开启SSH服务,以及其附带的SFTP服务。
在PC上通过FTP软件(支持SFTP协议的FTP工具有FLXFTP、FileZilla等)传输文件。
目标主机填:sftp://192.168.1.102(换成您的树莓派的IP地址。前面的sftp://一定要加)。用户名和密码照实填(Raspbian默认是pi/raspberry)。