首页 > 其他分享 >嵌入式系统 第六讲 Boot Loader技术

嵌入式系统 第六讲 Boot Loader技术

时间:2024-12-27 20:30:49浏览次数:7  
标签:vivi RAM Boot 嵌入式 内核 串口 Loader

• 6.1 Boot Loader基本概念

• Boot Loader(引导程序)是在操作系统内核运行之前运行 的一段小程序,Boot Loader初始化硬件设备和建立内存空 间的映射图,从而将系统的软硬件环境带到一个合适的状 态,以便为最终调用操作系统内核准备好正确的环境。

• 嵌入式Linux系统启动后,先执行Boot Loader ,进行硬件 和内存的初始化工作,然后加载Linux内核和根文件系统, 完成Linux系统的启动。

• 6.1.1 Boot Loader所支持的硬件环境

– Boot Loader依赖于:

嵌入式CPU(实验箱MPU的RK3399处理器)

② 嵌入式板级设备的配置(实验箱上的各种硬件)。

• 6.1.2 Boot Loader的安装地址

– Boot Loader的安装地址(即ARM处理器的复位启 动地址):0x00000000

固态存储器(Flash存储器)的典型空间分配结构:

        ① Boot Loader

        ② 内核的启动参数(Boot parameters)

        ③ 内核映像

        ④ 根文件系统映像

• 6.1.3 Boot Loader相关的设备和基址

– 主机(宿主机,Ubuntu)和目标机(目标板,实验箱)之间一般通过串 口Xshell串口超级终端)建立连接,Boot Loader软件在执行时通常会通 过串口来进行输入、输出,比如:输出打印信息到串口,从串口读取用 户控制字符等。

– Boot Loader的基址:0x00000000

• 6.1.4 Boot Loader的启动过程

– 启动过程包括两个阶段:

• 阶段1 • 阶段2

– 阶段1完成初始化硬件,为阶段2准备内存空间,并将 阶段2复制到内存中,设置堆栈,然后跳转到阶段2。

• 6.1.5 Boot Loader的操作模式

– Boot Loader的两种模式:

• 启动加载模式:也称为自主模式,也即Boot Loader从目标机 (实验箱)上的某个固态存储设备(通常为Flash存储器)上 将操作系统加载到RAM(通常为SDRAM)中运行,整个过程 并没有用户的介入。这种模式是Boot Loader的正常工作模式

下载模式:在这种模式下目标机(实验箱)上的Boot Loader 将通过串口连接网络连接等通信手段从主机(宿主机, Ubuntu)下载文件(内核映像、根文件系统映像),从主机 下载的文件通常首先被Boot Loader保存到目标机的RAM (SDRAM)中,然后再被Boot Loader写(烧写)到目标机上 的固态存储设备(Flash存储器)中。

– 实验箱的两种模式的切换:在打开实验箱电源(或者按下 实验箱的Reset按钮)后,出现倒计时后,按Ctrl+C,则会 进入下载模式(“=>”状态);否则进入启动加载模式; 在下载模式下(“=>”状态),执行“reset”命令,也会 进入启动加载模式。

– 常用的Boot Loader:

① U-Boot:全称 Universal Boot Loader,是由开源项目 PPCBoot发展起来的,ARMboot并入了PPCBoot,和其 他一些arch的Loader合称U-Boot。

② vivi:是韩国mizi公司开发的Boot Loader,适用于 ARM9处理器。vivi有两种工作模式:启动加载模式和 下载模式。启动加载模式可以在一段时间后(这个时 间可更改)自行启动Linux内核,这是vivi的默认模式。 在下载模式下,vivi为用户提供一个命令行接口,通过 接口可以使用vivi提供的一些命令。

③ Blob:全称Boot Loader Object,是由Jan-Derk Bakker和 Erik Mouw发布的,是专门为StrongARM构架下的LART 设计的Boot Loader。

• 6.1.6 Boot Loader与主机之间的通信设备及 协议

– 串口:目标机使用串口与主机相连,这时的传输协议通常是 xmodem/ymodem/zmodem中的一种。

– 网口:目标机使用网口与主机相连,用网络连接的方式传输文件, 这时使用的协议多为TFTP简单文件传输协议)。

• 6.2 Boot Loader典型结构

• Boot Loader的阶段1:

主要包含依赖于CPU的体系结构硬件初始化的代 码,通常都用汇编语言来实现。这个阶段的任务有(5个任务):

        ① 基本的硬件设备初始化屏蔽所有的中断关闭处理器内部指令/数据Cache等)

        ② 为加载Boot Loader的阶段2准备RAM空间

        复制Boot Loader的阶段2代码到RAM

        ④ 设置堆栈

        跳转到阶段2的C程序入口点

• Boot Loader的阶段2:

通常用C语言完成,以便实现更复杂的功能,也 使程序有更好的可读性可移植性。这个阶段的任务有(5个任务):

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

        ② 检测系统内存映射

        ③ 将内核映像根文件系统映像从Flash读到RAM

        ④ 为内核设置启动参数

        ⑤ 调用内核

• 6.2.1 Boot Loader阶段1介绍(5个任务)

– 任务1:基本的硬件设备初始化

屏蔽所有的中断(通过写CPU的中断屏幕寄存器状态寄存器(如CPSR)来完成)

• 设置CPU的速度和时钟频率

• RAM初始化

• 初始化LED(通过LED显示系统的状态是OK还是Error)

– 任务2:为加载阶段2准备RAM(SDARM)空间

• 阶段2加载到RAM中,通常准备1MB的RAM空间,放在整个RAM的最顶端,并且要 对这个1MB的空间进行测试

– 任务3:复制阶段2的代码到RAM(SDRAM)

• 阶段2的映像Flash中的起始地址终止地址

RAM空间的起始地址

– 任务4:设置堆栈指针SP = stage2_end – 4

– 任务5:跳转到阶段2的C程序入口点

• 通过修改PC的值来实现

• 6.2.2 Boot Loader阶段2介绍(5个任务)

– 利用trampoline(弹簧床)的概念,即用汇编语言写一段 trampoline小程序,并将这段trampoline小程序来作为阶段2可执 行映象的执行入口点;然后我们可以在trampoline汇编小程序中用 CPU 跳转指令跳入 main() 函数中去执行,而当 main() 函数返回时, CPU 执行路径显然再次回到我们的 trampoline 程序。

– trampoline小程序:

.text        @代码段

.globl _trampoline        @声明全局

_trampoline:        

        bl main        @跳转到main

        b _trampoline         @跳转到_trampoline

– 任务1:初始化本阶段要使用到的硬件设备

• 初始化至少一个串口,以便和终端用户进行 I/O 输出信息

• 初始化计时器

– 任务2:检测系统内存映射

• 所谓内存映射就是指在整个 4GB 物理地址空间中有哪些地址范围 被分配用来寻址系统的 RAM 单元

• 虽然 CPU 通常预留出一大段足够的地址空间给系统 RAM,但是在 搭建具体的嵌入式系统时却不一定会实现 CPU 预留的全部 RAM 地址空间,嵌入式系统往往只把 CPU 预留的全部 RAM 地址空间 中的一部分映射到 RAM 单元上,而让剩下的那部分预留 RAM 地 址空间处于未使用状态

• 内存映射的描述

typedefstruct memory_area_struct {
 u32 start;
 u32 size;
 int used;
 } memory_area_t;

 – 这段 RAM 地址空间中的连续地址范围可以处于两种状态之一:

» (1)used=1,则说明这段连续的地址范围已被实现,也即真正地被映射到 RAM 单元上。

» (2)used=0,则说明这段连续的地址范围并未被系统所实现,而是处于未使用 状态。

– 基于上述 memory_area_t数据结构,整个 CPU 预留的 RAM 地址空间可以用一个 memory_area_t类型的数组来表示,如下所示:

memory_area_tmemory_map[NUM_MEM_AREAS] = {
 [0 ... (NUM_MEM_AREAS - 1)] = {
 .start = 0,
 .size = 0,
 .used = 0
 },
};

 – 任务3:将内核映像和根文件系统映像从Flash读到RAM (SDRAM)

• 规划内存占用的布局

        – 这里包括两个方面:

                » 内核映像所占用的内存范围:MEM_START+0x8000开始、大约 1MB大小的内存范围内(嵌入式 Linux 的内核一般都不操过 1MB)

                » 根文件系统所占用的内存范围:MEM_START+0x0010,0000开始、 大约1MB大小的内存范围内(如果用 Ramdisk作为根文件系统 映像,则其解压后的大小一般是1MB)

• 从 Flash 上拷贝

        – 由于像 ARM 这样的嵌入式 CPU 通常都是在统一的内存地址空间中寻 址 Flash 等固态存储设备的,因此从 Flash 上读取数据从 RAM 单元 中读取数据并没有什么不同。用一个简单的循环就可以完成从 Flash 设备上拷贝映像的工作:

while(count) {
 *dest++ = *src++;
 count -= 4;
 };
 

 – 任务4:为内核设置启动参数(Boot parameters)

• Linux 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数,启动参数标记列表以标记 ATAG_CORE 开始, 以标记 ATAG_NONE 结束

• 在嵌入式 Linux 系统中,通常需要由 Boot Loader 设置的常见 启动参数有:ATAG_COREATAG_MEM、ATAG_CMDLINE、 ATAG_RAMDISK、ATAG_INITRD、ATAG_NONE

– 任务5:调用内核

• Boot Loader 调用 Linux 内核的方法是直接跳转到内核的第一条 指令处,也即直接跳转到 MEM_START+0x8000 地址处

• 如果用 C 语言,可以像下列示例代码这样来调用内核:
 

void (*theKernel)(int zero, int arch, u32 params_addr) = (void (*)(int, int,u32))KERNEL_RAM_BASE; ……

theKernel(0, ARCH_NUMBER, (u32) kernel_params_start);

• 注意,theKernel()函数调用应该永远不返回的,如果这个调用 返回,则说明出错

• 6.2.3 关于串口终端

– 经常会碰到串口终端显示乱码或根本没有显示的问题,造成这个 问题主要有两种原因

① Boot Loader 对串口的初始化设置不正确

② 运行在 host 端(主机端,PC机)终端仿真程序(Xshell程序对串 口的设置不正确,这包括:波特率奇偶校验、数据位和停止位等方 面的设置。

– 此外,有时也会碰到这样的问题,那就是:在 Boot Loader 的运 行过程中我们可以正确地向串口终端输出信息,但当 Boot Loader 启动内核后无法看到内核的启动输出信息。对这一问题的原因 可以从以下几个方面来考虑:

        ① 首先请确认你的内核在编译时配置了对串口终端的支持,并配置了正 确的串口驱动程序。

        ② 你的 Boot Loader 对串口的初始化设置可能会和内核对串口的初始化设 置不一致。此外,对于诸如 s3c44b0x 这样的 CPU,CPU 时钟频率的设 置也会影响串口,因此如果Boot Loader 和内核对其 CPU 时钟频率的设 置不一致,也会使串口终端无法正确显示信息。

        ③ 最后,还要确认 Boot Loader 所用的内核基地址必须和内核映像在编译 时所用的运行基地址一致,尤其是对于 uClinux而言。假设你的内核映 像在编译时用的基地址是 0xc0008000,但你的Boot Loader 却将它加载 到 0xc0010000 处去执行,那么内核映像当然不能正确地执行了。

• 6.3 U-Boot简介

• 6.3.1 认识U-Boot

U-Boot,全称 Universal Boot Loader(通用的引导程序),是遵循 GPL条款开放源码项目。U-Boot的作用是系统引导。U-Boot从 FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、 编译形式与Linux内核很相似,事实上,不少U-Boot源码就是根据 相应的Linux内核源程序进行简化而形成的,尤其是一些设备的驱 动程序,这从U-Boot源码的注释中能体现这一点。

http:// http://ftp.denx.de/pub/u-boot/

• 6.3.2 U-Boot特点

① 开放源码

② 支持多种嵌入式操作系统内核,如Linux、NetBSD、VxWorks、QNX、 RTEMS、ARTOS、LynxOS、Android

③ 支持多个处理器系列,如PowerPC、ARM、x86、MIPS

④ 较高的可靠性和稳定性

⑤ 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产 品发布等

⑥ 丰富的设备驱动源码,如串口以太网SDRAMFLASH、LCD、 NVRAM、EEPROM、RTC、键盘等

⑦ 较为丰富的开发调试文档与强大的网络技术支持

• 6.3.3 U-Boot代码结构分析

– U-Boot 2017.09的目标结构:

① api:存放u-boot提供的接口函数

② arch:与体系结构相关的代码

③ board:根据不同开发板所定制的代码

④ cmd:命令

⑤ common:通用的代码,涵盖各个方面,已对命令行的处理为主

⑥ configs:配置文件

⑦ disk:磁盘分区相关代码

⑧ doc:文档,readme

⑨ drivers:驱动相关代码,每种类型的设备驱动占用一个子目录

⑩ dts:设备树文件

⑪ examples:示例程序

⑫ fs:文件系统,支持嵌入式开发板常见的文件系统

⑬ include:头文件,以通用的头文件为主

⑭ lib:通用库文件(14个)

⑮ Licenses:许可证

⑯ net:网络相关的代码,小型的协议栈

⑰ post:上电自检程序

⑱ scripts:脚本文件

⑲ test:测试文件

⑳ tools:辅助功能程序,用于制作u-boot镜像等

 – ARM926 EJ-S系列处理器(ARM 9系列)的U-boot两阶 段代码:

        • 第一阶段(用汇编语言编写):start.S

                – 位于/u-boot/arch/arm/cpu/arm926ejs/start.S

        • 第二阶段(用C语言编写):board.c

                – 位于/u-boot/arch/arm/mach-rockchip/board.c

• 6.4 vivi简介

• 6.4.1 认识vivi

– vivi是韩国mizi公司设计的一款主要针S3C2410平台的Boot Loader, 其特点是体积小功能强大运行效率高使用方便。vivi代码虽 然比较小巧,但麻雀虽小,五脏俱全,用来学习bootloader还是 不错的。

• 6.4.2 vivi代码导读

– vivi的代码目录包括:

        ① arch 存放一些平台相关的代码文件

        ② CVS 存放CVS工具相关的文件(CVS:Concurrent Version System, 版本管理工具)

        ③ Documentation 存放一些使用vivi的帮助文档

        ④ drivers 存放vivi相关的驱动代码

        ⑤ include 存放所有vivi源码的头文件

        ⑥ init 存放vivi初始化代码

        ⑦ lib 存放vivi实现的库函数文件

        ⑧ scripts 存放vivi脚本配置文件

        ⑨ test 存放一些测试代码文件

        ⑩ util 存放一些NAND Flash烧写image相关的工具实现代码

• Makefile 用来告诉make怎样编译和连接成一个程序

标签:vivi,RAM,Boot,嵌入式,内核,串口,Loader
From: https://blog.csdn.net/m0_74313796/article/details/144771678

相关文章

  • 基于Java+Springboot+MySQL新闻资讯网站系统设计与实现
     博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩,提供核心代码讲解,答辩指导。项目配有对应开发......
  • springboot毕设 在线学习系统 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和普及,教育领域正经历着前所未有的变革。在线学习作为一种新兴的教育模式,以其便捷性、灵活性和资源丰富性,逐渐成为广大学习......
  • springboot毕设 在线手机销售平台 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,电子商务已成为现代商业活动的重要组成部分。在线购物平台凭借其便捷性、高效性和广泛的选择范围,逐渐改变了消费者的购物习......
  • 痞子衡嵌入式:MCUXpresso for VS Code开发环境搭建及SDK工程导入
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是MCUXpressoforVSCode开发环境搭建及SDK工程导入。MCUXpressoIDE(包括其前身LPCXpressoIDE、KinetisDesignStudio)是恩智浦软件团队持续开发了十多年的免费集成开发环境,现在功能已经相当完善,IDE里面......
  • 370_基于springboot的研究生知识管理系统
    目录系统展示开发背景代码实现项目案例 获取源码博主介绍:CodeMentor毕业设计领航者、全网关注者30W+群落,InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者,博客领航之星、开发者头条/腾讯云/AWS/Wired等平台优选内容创作者、深耕Web......
  • 基于SpringBoot+Vue的乐器推荐系统的设计与实现
    开发环境开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9浏览器:谷歌浏览器后台路径地址:localhost:8080/项目名称/admin/dist/index.html前台路径地址:lo......
  • springboot毕设 在线考试系统 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和普及,教育领域正经历着深刻的变革。传统的考试模式,受制于时间、地点和资源的限制,已难以满足现代教育的多元化需求。特别是......
  • springboot毕设 作业检查平台 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在教育信息化快速发展的今天,作业作为教学过程中的重要环节,其质量直接关系到学生的学习效果和教师的教学成效。然而,传统作业检查方式存在诸多弊端,如教......
  • 使用UnstructuredRSTLoader加载RST文件的实战指南
    在大数据时代,爬取和收集网络数据是AI应用中的重要一环。而今天要跟大家分享的是一个非常强大的工具——Spider,它以其快速和高性价比著称,非常适合用于获取适合大型语言模型(LLM)的数据。技术背景介绍Spider是一款专门为AI代理和大型语言模型设计的网络爬虫工具。它最大的特......
  • 详解 Spring Boot 2.7.18 与 MyBatis PageHelper 的整合步骤
    一、添加依赖在pom.xml文件中添加必要的依赖:<dependencies><!--SpringBootStarterWeb--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>&l......