1、为什么要配置树莓派的Linux内核
为了驱动代码的编写,驱动代码的编译需要一个提前编译好的内核,编译内核就必须配置,配置的最终目标会生成 .config文件,该文件指导Makefile去把有用东西组织成内核。
2、准备工作,配置环境,下载内核
到https://github.com/raspberrypi/下载对应版本的Linux内核源码拷贝到Ubuntu,下载交叉编译工具安装到Ubuntu并配置环境变量
详细步骤参考博文:
交叉编译工具链安装与应用、带wiringPi库的交叉编译_◣星河◢的博客-CSDN博客
3、 如何配置Linux内核
配置内核源码有三种方式。一般我们购买芯片,厂家会配linux内核源码,比如说买了树莓派,就提供树莓派linux内核源码。
第一种方式:
cp 厂家.config .config (树莓派1的工程是bcmrpi_defconfig,树莓派2、3的工程是bcm2709_defconfig)
查找厂家config指令:find . -name *_defconfig
获取bcm2709_defconfig的配置到 .config里
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
- ARCH=arm:指定为RAM架构
- CROSS_COMPILE=arm-linux-gnueabihf- :指定编译器
- KERNEL=kernel7:指定内核版本,指明kernel类型,树莓派1设置为kernel,树莓派2、3设置为kernel7
- make bcm2709_defconfig (make为配置命令)
也可以使用cp arch/arm/configs/bcm2709_defconfig .config
然后去使用这个.config
第二种方式:
make menuconfig 一项项配置,通常是基于厂家的config来配置 (需要安装相关库,命令和方式一一样)
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
#指定ARM架构 指定编译器 树莓派内核 主要核心指令
安装相关库
sudo apt-get install bc
sudo apt-get install libncurses5-dev libncursesw5-dev
sudo apt-get install zlib1g:i386
sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5
General setup —>(通用选项)
[ * ] Enable loadable module support —> 内核模块选项
[ * ]Enable the block layer —> 块设备逻辑层选项(大文件支持、分区、I/O调度)
System Type —>(平台选项)
Bus support —> 总线选项
Kernel Features —>内核特征
Boot options —> 引导选项
CPU Power Management —> CPU电源管理选项
Floating point emulation —> 浮点运算
Userspace binary formats —> 用户程序格式
Power management options —> 电源管理选项
[*] Networking support —> 网络协议选项
Device Drivers —> 设备驱动
Firmware Drivers ---- 驱动固件选项
File systems —> 文件系统选项
Kernel hacking —> 内核调试选项
Security options —> 安全模块选项
Enter进入下一个子菜单(末尾带箭头的会有子菜单
[ * ] :编译进内核 (* 代表Y,编译进内核 zImage文件包含了驱动)
[ M ]:编译成模块 (以模块的方式生成驱动文件xxx.ko 系统启动后,通过命令inmosd xxx.ko 加载驱动)
[ ] : 表示不需要的部分
——使用空格可以切换[ ]里面的模式
第三种方式:
自己配置
4、Linux内核编译
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs
make -j4 zImage modules dtbs
- -j4 用多少电脑资源进行编译 (4核)
- zImage 生成内核镜像
- modules 要生成的驱动模块
- dtbs 要生成的配置文件
执行后等待编译成功,可能时间会比较久,完成后查看是否编译成功。
1.首先看看编译过程有没有报错
2.源码目录树文件是否生成 vmlinux 文件,有就成功,失败则无此文件
我们所需要的生成的目标内核镜像文件 ZImage
将zImage内核镜像打包成为树莓派可用的xxx.img
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
5、挂载树莓派SD卡,并进行数据拷贝
dmesg
查看打印内核的一些信息
如图显示连接成功,没有此选项则没有连接到虚拟机Ubuntu系统
把树莓派的sd卡插入ubuntu系统电脑,树莓派的sd卡有两个分区:
一个fat分区,是boot相关的内容,kernel的img文件就放在这个分区里;(操作系统内核)
一个是ext4分区,也就是系统的根目录分区。
创建两个文件夹
data1–>fat分区–>放置镜像文件
data2–>ext4分区–>放置根目录文件
挂载sdb1和sdb2 到 data1 data2
sudo mount /dev/sdb1 data1 挂载U盘里sdb1文件分区到当前目录data1文件夹,fat分区(是存放boot相关的内容,kernel的img)
sudo mount /dev/sdb2 data2 挂载U盘里sdb2文件分区到当前目录data2文件夹,ext4分区(根目录分区)
为什么要挂载
比如mount /dev/sdb1 ~/Share/ ,把新硬盘的区sdb1挂载到工作目录的~ /Share/文件夹下,之后访问这个~/Share/文件夹就相当于访问这个硬盘的sdb1分区了,对/Share/的任何操作,都相当于对sdb1里文件的操作。
所以Linux下,mount挂载的作用,就是将一个设备(通常是存储设备)挂接到一个已存在的目录上。访问这个目录就是访问该存储设备。
安装modules(设备驱动文件: hdmi usb wifi io …
modules安装在ext4分区也就是我们的data2分区
安装modules的路径是我们源码的路径
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=/home/lth/SYSTEM/data2 modules_install
INSTALL_MOD_PATH:这里用的绝对路径避免出错
操作ext4(data2)分区,需要root权限。
安装更新 kernel.img 文件,注意镜像名字是kernel7.img(kernel是特殊的,官方给的)
避免刷机失败我们把kernel7.img备份一下
再把直接编译新生成的kernel_new.img拷贝到data1,取名kernel7.img(覆盖之前的)
cp kernel_new.img /home/lth/SYSTEM/data1/kernel7.img
查看镜像文件md5值(这步很重要),如果两次值不同,则需要重新拷贝
拷贝其他配置文件
cp arch/arm/boot/dts/.*dtb* /home/lth/SYSTEM/data1
cp arch/arm/boot/dts/overlays/.*dtb* /home/lth/SYSTEM/data1/overlays/
cp arch/arm/boot/dts/overlays/README /home/lth/SYSTEM/data1/overlays/
注意路径问题,这里是我的路径,要根据自己的路径来,不要出错
6、断开SD开的连接 把SD开的连接接到电脑上
修改codline.txt文件,让树莓派以串口方式登录验证
7、用串口登录连接树莓派查看是否成功
修改完后将SD卡插到树莓派,USB转串口连接树莓派,选择串口登录,树莓派通电。
.查看内核的版本是否和我们开始下载的一致
和我们下载的内核版本一致