前期工作
-
配置好交叉编译工具链 交叉编译工具链详细教程 -
树莓派Linux内核源码下载 查看树莓派操作版本命令:uname -r 源码下载
一、嵌入式裸机和带操作系统启动过程了解
-
C51,stm32启动过程: c直接操控底层寄存器实现相关业务,业务流程型的裸机代码 -
x86,Intel----windows 启动过程: 电源–>BIOS–>windows内核–>C,D盘–>启动程序 -
嵌入式产品 树莓派,mini2440,mini6410,nanopi,海思,RK(瑞芯微)启动过程: 电源–>Bootloader(引导操作系统启动)–>Linux内核–>文件系统–>应用程序 -
安卓启动过程: 电源–>fastBoot/Bootloader(引导操作系统启动)–>Linux内核–>文件系统—>虚拟机–>home程序->APP Bootloader: 一阶段:让CPU跟内存,FLASH,串口,IIC,IIS,数据段打交道—驱动这些设备(汇编和C ) 二阶段:引导Linux内核启动(纯C)
二、树莓派Linux源码目录树分析
arch :包含和硬件体系结构相关的代码,每种平台占一个相应的目录。和32位PC相关的代码存放在i386目录下,其中比较重要的包括kernel(内核核心部分)、mm(内存管理)、math-emu(浮点单元仿真)、lib(硬件相关工具函数)、boot(引导程序)、pci(PCI总线)和power(CPU相关状态)。block :部分块设备驱动程序。crypto :常用加密和散列算法(如AES、SHA等),还有一些压缩和CRC校验算法。Documentation :关于内核各部分的通用解释和注释。drivers :设备驱动程序,每个不同的驱动占用一个子目录。fs :各种支持的文件系统,如ext、fat、ntfs等。include :头文件。其中,和系统相关的头文件被放置在linux子目录下。init :内核初始化代码(注意不是系统引导代码)。ipc :进程间通信的代码。kernel :内核的最核心部分,包括进程调度、定时器等,和平台相关的一部分代码放在arch/*/kernel目录下。lib :库文件代码。mm :内存管理代码,和平台相关的一部分代码放在arch/*/mm目录下。net :网络相关代码,实现了各种常见的网络协议。scripts :用于配置内核文件的脚本文件。security :主要是一个SELinux的模块。sound :常用音频设备的驱动程序等。usr :实现了一个cpio。
- Linux是开源的,支持多架构多平台代码
- 因为支持多架构,架构又会有很多子架构,比如ARM架构里又有海西、树莓派等。所以驱动代码通过gcc编译出来的可执行文件会很大,几M
- 驱动代码的编译需要在提前编译好的内核上进行,所以我们通过配置出合适的内核使编译出的可执行文件不会很大,适用于目标平台的架构即可
- 因此我们需要做内核配置,内核编译。来得到合适的内核
三、开始准备树莓派Linux内核
1 树莓派Linux内核配置
我们是配置生成xxx.config文件,是该文件指导Makefile去把有用的东西组织成内核
厂家提供好Linux内核源码。比如买了树莓派,厂家会提供树莓派内核源码,里面就有 xxx厂家树莓派.config
配置树莓派的Linux内核有三种方式
第一种:使用厂家自带config,cp 厂家.config .config。 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig 指定arm架构——————指定编译器——-————-—树莓派————树莓派核心指令
第二种:通过make menuconfig 一项项的配置,通常是基于厂家的config来配置,优点可以自己加入一些想要的驱动。 1.安装ncurses库: 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 2.执行menuconfig进入device drivers->Input device support 按空格键选择需要的驱动,*代表系统一开始就已经加载进了内核 在zImage里面包含了驱动,M代表系统启动后 可以通过指令insmod xxx.ko临时加载驱动,空格代表这个驱动不加载进内核 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
第三种:略
2 树莓派内核编译
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs
-j4 指定用4核编译 zImage 生成内核镜像 modules 生成驱动模块 dtbs 生成配置文件
- 编译成功会在源码树目录生成vmlinux :是没有压缩的树莓派Linux内核文件,真正的内核是zImage文件。
在arch/arm/boot下,生成zImage :是内核镜像,实际作用就是对内核进行解码
3 把编译好的zImage文件进行打包
目的:使打包后的zImage文件变成树莓派可用的xxx.img文件 回到源码根目录输入指令:./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
4 把树莓派SD卡2个分区挂载到Linux
按照文章写着做,千万别乱操作乱删除,否则可能会把sd卡所有内容删除掉
- 把树莓派sd卡插入Linux系统电脑,树莓派有2个分区sdb1(fat子目录分区,是boot相关的内容,kernel的img文件就放在这个分区里)和sdb2(ext4系统根分区)
- 创建2个文件夹用于挂载这2个分区
mkdir data1 data2 输入指令进行挂载 在data1、2目录的上一级执行 sudo mount /dev/sdb1 data1 sudo mount /dev/sdb2 data2 - 安装modules
为了得到设备驱动文件,如:hdmi usb wifi io … 在inux-rpi-4.14.y目录下执行命令 sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=data2路径 modules_install 操作ext4分区,需要root权限。若不执行这条指令 则内核能跑起来 但很多驱动都不能用 - 先进入data1,备份一份kernel7.img,以防刷机失败 树莓派无法启动,执行命令备份:
cp kernel7.img kernel7OLD.img 进入inux-rpi-4.14.y目录执行命令继续拷贝cp kernel_new.img/home/pi/lessonPI/data1/kernel7.img - 复制相关文件
进入inux-rpi-4.14.y目录执行命令: cp arch/arm/boot/dts/.*dtb* data1路径 cp arch/arm/boot/dts/overlays/.*dtb* data1路径/overlays/ cp arch/arm/boot/dts/overlays/README data1路径/overlays/ - 完美的完成,接下来来验证是否配置树莓派内核成功
把sd卡插进树莓派,通过串口登陆树莓派,ifconfig查看ip地址是否有,uname -r查看当前树莓派版本是否为前期工作下载的那个树莓派版本 我的是4.14.114-v7
**回顾:**第二大点第3小点,驱动代码的编译需要在提前编译好的内核上进行,所以我们以上操作已经是做好了一个编译好的内核(树莓派内核)
转发请表明出处 作者:星辰~念
|