1. Bootloader

1.1 Bootloader基本概念

  • 系统启动时激活
  • 在操作系统内核运行之前的一段程序
  • 任务
    • 初始化硬件设备和建立内存空间的映射图
    • 引导操作系统:将系统软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好环境

  • PC机的引导加载程序
    • BIOS:硬件检测和资源分配,将硬盘MBR中的BootLoader读到系统RAM中,控制权交由Bootloader
    • Bootloader:将硬盘中的操作系统内核从硬盘上读取到RAM中,然后跳转到内核入口点,交由操作系统
  • 嵌入式系统的Bootloader
    • 严重依赖于硬件环境,每一个特定的系统的Bootloader均会有所不同

1.1.1 Bootloader功能分类

  • 简单Bootloader
    • 只具备系统引导功能
  • 具有监控功能(Monitor)的Bootloader

    • 调试支持
    • 内存读写
    • Flash烧写
    • 网络下载
    • 环境变量配置

      1.1.2 Bootloader启动操作系统方式

  • 系统上电从0x0000地址启动

  • Bootloader程序的入口就放置在这里
  • 如果采用Nor Flash
    • 直接在0地址运行
  • 如果采用Nand Flash

    • 需要从0地址将程序读取到片内RAM后运行
    • 映射到了0地址上

      1.1.3 Bootloader的操作模式

  • 启动加载模式

    • Bootloader从目标机的某个固态存储设备上将操作系统加载到RAM中运行
  • 下载模式

    • 目标机上的Bootloader通过串口或网络连接等通信手段从宿主机上下载文件

      1.2 Bootloader典型框架

  • Bootloader分为两个阶段

    • 阶段1:实现依赖于CPU体系结构的代码
    • 阶段2:实现一些复杂的功能

      1.2.1 Stage1

  • 基本的硬件设备初始化

    • 屏蔽所有中断/设置CPU的速度和时钟频率/RAM初始化/初始化LED/关闭cache
  • 为Stage2准备RAM空间
    • 安排Stage2的C语言执行代码的地址范围/对该地址范围测试(测试每页前两个字的读写)
  • 拷贝Bootloader的Stage2到RAM
    • 需要确定Stage2的可执行映象在固态存储设备(flash)的存放地址和终止地址/确定RAM空间的起始地址
  • 设置好堆栈
    • 为执行C语言做好准备/以及CPU的模式切换也需要堆栈
  • 跳转到Stage2的C入口点

    • 可以修改PC寄存器实现

      1.2.2 Stage2

  • 初始化本阶段要使用的硬件设备

    • 初始化串口实现I/O输出信息/初始化计时器/LED使能显示状态/初始化完成后打印信息
  • 检测系统内存映射
    • 明确整个物理地址空间中哪些范围被分配用来作为寻址系统的RAM单元(哪些是未使用的
  • 将kernel和根文件系统映像从flash上读到RAM空间中(加载内核映像和根文件系统映像blob)
    • 规划内存布局(内核映像和根文件系统的占用范围)/从Flash上拷贝
  • 为内核设置启动参数
    • 标记列表形式传递参数
  • 调用内核

    • 跳转到内核第一条指令处/CPU模式禁止中断/MMU必须关闭

      1.3 Bootloader生命周期

  • Stage1:初始化硬件设备和建立内存空间的映射

  • Stage2:引导操作系统
  • 消亡

    1.4 Bootloader控制设备与通信协议

  • 主机和目标机通过串口建立连接

  • 输出打印信息到串口,从串口读取用户控制字
  • 串口终端出现问题—显示乱码,没有显示
    • bootloader对串口的初始化设置不正确
    • 主机端仿真程序对串口的设置不正确:波特率/奇偶校验/数据位/停止位
  • 传输协议:xmodem/ymodem/zmodem中的一种

  • 可通过以太网连接

  • 传输协议:借助TFTP协议下载文件

    1.5 Bootloader编译与烧写

    1.5.1 编译

    make menuconfig
    设置组态

    1.5.2 烧写

  • 裸板,需要通过JTAG口把Bootloader烧写到板子上

  • bootloader,已有bootloader时,可以通过串口(网口)烧写更新升级

    1.6 常用Bootloader

  • vivi

  • U-boot
  • Redboot

    2. Linux内核移植

    2.1 移植分类

  • 板级移植

    • Linux发行版本已经支持CPU,只需要对板级移植硬件修改
  • 片级移植
    • Linux发行版本没有支持的CPU,需要CPU的内核移植
  • 片级移植更复杂

2.2 移植步骤

  • 准备工作,阅读硬件文档,下载Linux内核源码和编译器源码
  • 建立交叉编译环境
  • 制作Bootloader
  • 配置和编译内核
  • 编写相应的设备驱动

3. Linux设备驱动

3.1 设备驱动程序概述

3.1.1 Linux设备驱动程序的作用

  1. 设备驱动程序屏蔽具体硬件设备的细节
    1. 操作系统-机器硬件之间的接口
  2. 驱动是展现硬件所具有的功能,是一个中间环节
    1. 由应用程序操作硬件
  3. 并发问题
    1. 驱动程序有时会被多个进程同时使用,需要调用一些内核的函数使用互斥量和锁的机制

3.1.2 设备驱动原理

  • 所有操作系统下设备驱动程序的共同目标是屏蔽具体物理设备的操作细节
  • 实现设备无关性
  • 嵌入式操作系统中,设备驱动程序是内核的重要组成部分
  • 设备驱动程序为内核提供了一个I/O接口

3.1.3 模块化编程

  • 代码特征:模块是完成一项独立功能的函数集合
  • 使用特征:可以随时被安装,不需要时又可以随时被卸载

典型的Linux 设备驱动程序必要的组成部分:

  • 驱动程序模块的注册与注销函数
  • 设备的打开、关闭、读、写及需要的其它操作函数;
  • 设备的中断服务程序

3.1.4 设备类型

  • 字符设备
    • 处理字节为单位的顺序进行的设备
    • 没有缓存区,不支持随机读写
    • 串口/触摸屏/并口/AD
  • 块设备
    • 处理以块为单位的设备
    • 缓存技术,支持数据的随机读写
    • 磁盘/内存/flash
  • 网络设备
    • 通过BCD套接口访问的设备
    • 对数据包大小无限制
    • 网卡

3.1.5 设备抽象

  • Linux所有的硬件设备被抽象为文件
  • 可以使用与操作文件相同的调用接口完成打开/关闭/读写/I/O控制等

3.1.6 设备标识

  • 主设备号:设备种类,该设备所使用的驱动程序
  • 次设备号:标识使用同一设备驱动程序的不同硬件设备

3.1.7 设备驱动的特点

  • 内核代码:如果驱动程序出错,可能导致系统崩溃
  • 内核接口:设备驱动程序必须是内核或子系统提供的一个标准接口
  • 内核机制和服务:设备驱动程序使用一些标准的内核服务,内存分配、锁等
  • 可装载:需要时装载,不用时卸载
  • 可设置:设备驱动程序可以集成为内核的一部分
  • 动态性:驱动程序维护其控制的设备,如果设备不存在也不影响系统的运行

    3.2 设备驱动程序的使用方法

    3.2.1 机制与策略

  • 机制

    • 设备驱动程序所具备的能力
  • 策略
    • 这些能力如何被使用
  • 设备驱动程序应该是策略无关的

    3.2.2 使用

  1. 驱动程序模块的动态链接和静态链接
  2. 创建设备文件
  3. 使用设备

应用程序➡系统调用➡设备驱动程序➡设备(寄存器)