树莓派Linux内核开发
一、下载linux源码、交叉编译工具链
树莓派的github主页: https://github.com/raspberrypi,里面包含了linux源码、交叉编译工具链等内容。
对于我们要用到的有两个仓库:
https://github.com/raspberrypi/linux 内核源码
https://github.com/raspberrypi/tools 交叉编译工具链(仅在交叉编译时用到)
二、ubuntu里交叉编译
1.交叉编译工具链的安装
- 从共享文件夹拷贝到工作目录
cp /mnt/hgfs/share/tools-master.zip . - 解压
unzip tools-master.zip - cd /home/CLC/lessonPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
- pwd获得路径
2.配置环境变量:
- 修改工作目录下的.bashrc 隐藏文件,配置命令终端的
vi /home/CLC/.bashrc - 在文件最后一行加入:
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/CLC/lessonPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
或者
export PATH=$PATH:/home/nicek/githubProjects/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux--gnueabihf-raspbian-x64/bin
source /home/CLC/.bashrc
加载配置文件,马上生效配置。
三、树莓派Linux源码配置
1、为什么进行配置?
- 驱动代码的编写
- 驱动代码的编译需要一个提前编译好的内核编译内核,就必须配置
- 配置的最终目标会生成 .config文件,该文件指导Makefile去把有用东西组织成内核
2、厂家配linux内核源码
——————比如说买了树莓派,树莓派linux内核源码
- 第一种方式:
cp 厂家.config .config
找到:find -name *_defconfig
树莓派1, bcmrpi_defconfig
树莓派2,3是./arch/arm/configs/bcm2709_defconfig
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
此命令功能是获取bcm2709_defconfig的配置到 .config里
- 第二种方式:
make menuconfig 一项项配置,通常是基于厂家的config来配置 - 第三种方式:
完全自己来
驱动两种加载方式:
(ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
进入ncurses页面)
- *编译进内核 zImage包含了驱动
- M 模块方式生成驱动文件xxx.ko 系统启动后,通过命令inmosd xxx.ko 加载
内核配置:
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
指定ARM架构 指定编译器 树莓派 主要核心指令
四、树莓派Linux内核编译
4.1 编译:
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs
(需要很久30分钟左右) -j4 指定用多少电脑资源进行编译( 4线程 ) zImage生成内核镜像 modules要生成驱动模块 dtbs生成配置文件
4.2 编译成功后
- 可以看到源码树目录(/home/cslz/SYSTEM/linux-rpi-4.14.y)多了vmlinux,失败则无此文件
- 成功后,目标zImage镜像arch/arm/boot底下
4.3 打包zImage成树莓派可用的xxx.img
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
4.4 数据拷贝
-
mkdir data1 data2
-
挂载U盘(挂载分区)
- sudo mount /dev/sdb1 data1 一个fat分区,是boot相关的内容,kernel的img
- sudo mount /dev/sdb2 data2 一个是ext4分区,也就是系统的根目录分区。/dev/sdb2是我的用的根目录
-
安装modules,在源码树目录完成(/home/cslz/SYSTEM/linux-rpi-4.14.y) 没有这一步很多,设备驱动文件没法用: hdmi usb wifi io …
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=/home/cslz/data2 modules_install
- 安装更新 kernel.img 文件,注意镜像名字是kernel7.img
- 先备份
cd /home/cslz/data1
cp kernel7.img kernel7OLD.img - 再把编译新生成的拷贝到data1,起名kernel7.img
cp kernel_new.img /home/cslz/data1/kernel7.img
- 先备份
- 拷贝配置文件(一些驱动等)
cp arch/arm/boot/dts/.dtb /home/cslz/data1
cp arch/arm/boot/dts/overlays/.dtb /home/cslz/data1/overlays/ /* [fat]就是我的:/home/cslz/data1
cp arch/arm/boot/dts/overlays/README [fat]/overlays/ / cp arch/arm/boot/dts/overlays/README /home/cslz/data1/overlays/ *\
注:图片过程:图片记录
五、有关Linux内核开发的的常识(扯淡)
1.树莓派Linux源码目录树分析
-
大约1.3w个C文件 1100w行代码
-
Linux是开源,免费,LInux开源社区工作者共同维护,爱好
-
Linux是一个开源的,支持多架构多平台代码 =非常牛逼
-
可以执行非常高,但是Linux内核编译出来一般就几M. 4M
-
因为支持多平台,多架构,所以编译之前要配置,配置成适合的目标平台来用
-
ARM
海思 友善之臂 RK 树莓派 nanoPi -
X86
PowerPC
MIPS
2、树莓派等芯片带操作系统的启动过程
-
C51,STM32(裸机)》》》》》》C直接操控底层寄存器实现相关业务。 业务流程型的裸机代码
- 遥控灯: while(1)
- 垃圾桶:WemosD1 LOOP
- 恩智浦智能车: stm32
-
X86,Intel windows
启动过程: 电源 -》 BIOS -》windows内核-》C,D盘-》 程序启动(QQ) -
嵌入式产品: 树莓派,mini2440, mini6410,nanopi,海思,RK(瑞芯微)------人脸识别打卡器,智能家居主控。。。
启动过程: 电源-》BootLoader(引导操作系统启动)-》Linux内核-》文件系统(根据功能性来组织文件夹,带访问权限)-》KTV点歌机, -
安卓
启动过程: 电源-》 fastBoot/Bootloader/-》linux内核-》文件系统-》虚拟机-》HOME应用程序-》点某图标打开某APP -
BootLoader:
一阶段 让CPU 跟内存,FLASH, 串口,IIC,IIS, 数据段,打交道,驱动这些设备(汇编和C结合)
二阶段: 引导Linux内核启动 (纯C)