嵌入式linux内核驱动学习2——linux启动流程
Linux系统启动过程涉及多个阶段,从硬件上电开始,程序首先在处理器内部的ROM中运行,根据拨码开关选择启动设备(如EMMC或SD卡),随后将Bootloader加载到内存中执行。Bootloader负责初始化内存等硬件,并将内核和DTB文件搬移到指定内存地址,最终启动内核并挂载根文件系统,完成操作系统启动。
一、启动设备与存储结构
存储设备类型
- 使用512MB内存和4GB EMMC作为主要存储设备。
- EMMC功能类似于SD卡,均可用于存储操作系统镜像。
启动设备选择机制
- 通过开发板上的拨码开关决定从EMMC还是SD卡启动。
- 不同存储介质的操作方法略有差异,但后续启动流程一致。
程序存储位置
- 操作系统相关程序(Uboot、Kernel、RootFS)需预先存储在EMMC或SD卡中。
- 上电后程序从存储设备加载至内存运行。
二、内存结构与访问机制
内存三大总线
- 地址总线:传输内存地址信息。
- 数据总线:传输实际数据,方向由读写信号控制。
- 控制总线:包含读写使能等控制信号。
内存组织结构
- 内存按bank、行、列三级结构组织,访问需分两次传输地址(bank+行,再列)。
- 芯片规格为256M×16位,总容量512MB。
- (245M16 256M16位 = 512MB 512M8位)是一个道理
内存初始化复杂性
- 内存初始化涉及大量时序参数配置,复杂度较高。
- 需正确设置各类时间参数以确保稳定访问。
三、非线性访问存储设备
EMMC/SD卡访问特点
- 属于非线性访问设备,无独立地址总线。
- 地址与数据通过同一组信号线分时传输。
访问效率问题
- 单次传输无法完成大地址传递,需多次传输。
- 连续读写多个字节以提高传输效率。
控制逻辑必要性
- 必须有专用控制逻辑才能访问此类设备。
- 处理器内部ROM程序包含对多种存储设备的支持代码。
四、系统启动流程
存储器 作用 类比 ROM 放启动代码/常量/固件,上电就能跑 仓库里的说明书 RAM 放正在运行的程序和数据,可快速改写 办公桌上的草稿纸
linxu启动流程:(系统上电开始)1. 先执行OCROM的启动程序(确定启动方式)2. 拷贝bootloader程序到内存2.1 OCROM的程序中先读取emmc中的 HEAD(IVT,DCD)等信息,根据该信息初始化好内存,拷贝uboot.bin到内存中,执行 uboot.bin。(uboot.bin首次被加载的内存的低地址处,自己搬移自己到高地址处运行)。2.2 拷贝uboot.bin的前半部分(最多128KB) 到OCRAM中,uboot.bin在前半部分将内存初始化好,拷贝自己的后半部分到内存中 ,执 行后半部分。3. uboot启动到最后阶段时搬移(如果emmc方 式:读取emmc中的kernel到内存中,如果tftp 方式:通过tftp下载kernel到内存中)kernel到内存的0x80800000地址处(搬移dtb文件到内存 的0x83000000地址处), 向kernel传参,启动内核4. 内核启动到最后阶段,根据bootloader传递的参数加载(挂载的形式:本地及nfs)根文件系统及设置终端(控制台)5. 根文件系统挂载完成后,内核中的init进程 退化为用户可见的init进程,init进程加载各种配置、启动各种脚本(程序)、启动shell至此操 作系统启动完成,用户可以在shell下运行程序
初始启动阶段
- 上电后执行处理器内部ROM中的引导程序。
- 根据拨码开关状态确定启动设备。
Bootloader加载方式
- 方式一:先加载前128KB到OC RAM,初始化内存后再将剩余部分搬移到DDR3。
- 方式二:直接利用内部程序初始化内存,一次性将完整Bootloader加载到内存。
内核启动过程
- 将zImage内核镜像搬移到内存0x80800000地址处。
- 将DTB设备树文件搬移到内存0x83123456地址处。
- 通过内存传递启动参数给内核。
根文件系统挂载
- 支持本地挂载(EMMC/SD卡)和网络挂载(NFS)两种方式。
- 挂载成功后切换到用户空间init进程。
(对比ubuntu和emmc两种内核启动方式)
五、系统移植与烧写
必需组件
- Uboot(通用引导加载程序)
- zImage(压缩内核镜像)
- RootFS(根文件系统)
特殊文件说明
- DTB文件(设备树)在Linux 3.5版本后引入,描述硬件配置。
- uboot.imx文件包含头部信息,支持直接加载到内存。
烧写方式
- 可向EMMC或SD卡烧写系统镜像。
- 支持Windows或Linux(Ubuntu)平台进行烧写操作。
- 开发过程中常用网络方式(TFTP/NFS)进行快速部署。
六、操作系统烧写
- 开发初期建议将系统烧写到SD卡,因为损坏后可重新烧写,而eMMC中的系统可能被其他应用依赖。
- 烧写过程需使用特定工具和脚本,通过USB OTG接口连接开发板与PC,在软件中选择对应SD卡或eMMC的启动模式进行烧写。
- 烧写完成后需断电并将拨码开关切换至SD卡启动模式,以验证操作系统是否成功启动。
七、虚拟机网络配置
- 配置虚拟机网络时应仅保留一个网络适配器并设置为桥接模式,修改网络配置文件设定静态IP地址。
- 关闭虚拟机后进入虚拟网络编辑器,还原默认配置并选择有线网卡进行桥接,确保主机与开发板间通信正常。
- 若使用USB转网口设备,应注意其名称识别并在Windows系统下正确查看网卡名用于桥接设置。
八、串口连接与终端操作
- 使用mini_com或Windows串口调试助手建立PC与开发板之间的串行通信,波特率设为115200,数据位8位,无校验,1位停止位。
- 通过串口可向开发板发送命令并接收执行结果,区分黑白界面为开发板终端,彩色界面为Ubuntu虚拟机终端。
- mini_com可通过保存默认配置简化后续操作,退出时使用Ctrl+A再Shift+X组合键。
九、文件共享与交叉开发
- 利用NFS实现PC与开发板间的文件共享,需确保双方网络连通,然后在开发板端挂载Ubuntu上的指定目录。
- 在Ubuntu上编写程序并通过arm-linux-gnueabihf-gcc编译器交叉编译成适用于ARM架构的可执行文件。
- 将编译后的程序放置于NFS共享目录下,在开发板端运行该程序完成测试,形成典型的交叉开发流程。
十、TFTP下载与Uboot操作
- 设置TFTP服务目录存放zImage和设备树文件,通过Uboot命令行从TFTP服务器下载内核镜像至内存指定地址。
- 在Uboot环境下需先配置开发板IP地址、子网掩码、网关及MAC地址,并设置TFTP服务器IP以便成功下载文件。
- 使用bootz命令加载已下载的内核镜像及其设备树,启动Linux内核;若根文件系统未准备好则会出现kernel panic错误