UBoot、BIOS、grub各自的功能、区别,UBoot详细过程

        由于从事的是嵌入式应用开发,有次和驱动的沟通过程中提到flash中存放的uboot,平时工作中也会提及升级uboot的事情,一直疑惑uboot到底做了哪些工作,以及平时听到的BIOS,grub,感觉它们几个的功能很类似,但是不清楚各自都属于什么平台,在什么场景下干活,干的活又有什么区别。此次抽时间分类总结了一下。

        先总结区别:UBoot 主要用于嵌入式系统、嵌入式设备;而BIOS、GRUB 主要用于传统的桌面计算机和服务器等通用计算机系统,通俗解释就是电脑主机。

然后这三个在各自的场景下又干了什么活呢,首先看一下每个功能的定义:

BIOS

        主要功能:针对计算机而非嵌入式装置的硬件初始化,硬件设备自检等。        

        详细解释:BIOS 是计算机启动时运行的第一个软件,它负责对计算机的基本硬件进行初始化。这包括检测和初始化 CPU、内存、硬盘、键盘、鼠标等硬件设备。例如,它会检查内存的容量和类型,对内存进行简单的测试以确保其正常工作;还会检测硬盘的存在,识别硬盘的型号和参数。

GRUB

        主要功能:多操作系统引导:

        详细解释:主要用于引导多种操作系统,在一个安装了多个操作系统(如同时安装了 Linux 和 Windows)的计算机上,GRUB 会提供一个启动菜单,让用户选择要启动的操作系统。它能够识别不同操作系统的内核位置和启动方式,从而实现多系统引导。

U-Boot

        因为本人从事的是嵌入式应用软件开发,而非修电脑和装系统的工作,所以UBoot是此次介绍的重点。简单了解看前面即可,深入了解看后面详细过程。

       横向对比:在嵌入式系统中发挥类似于 BIOS 在传统计算机中的硬件初始化作用,但更加侧重于嵌入式硬件。

        UBoot主要功能:系统上电或复位后,初始化硬件设备,加载并启动操作系统内核UBoot 的一个关键任务是将操作系统内核从存储设备(如 Flash、硬盘或网络)加载到内存中。例如,在开发一个基于 ARM 架构的嵌入式设备时,UBoot 可以帮助启动 Linux 内核,为设备的正常运行提供最初的引导。

        简要说明Uboot的三个工作:

        1、初始化相关硬件(存储、内存、网络接口),为加载内核做准备工作;

        2、加载内核;

        3、加载内核时给内核传参数(根文件系统信息、硬件的配置信息,如内存大小、CPU 频率等);

这三个工作总结成一个主旨,uboot的一切工作都是为了加载内核,前期准备、加载内核、给内核传参。

加载并启动内核的详细过程:

  • 硬件复位与预初始化

        当嵌入式装置上电或复位后,首先是硬件层面的复位操作。此时,处理器的内部寄存器被设置为默认值,芯片进入初始状态。例如,CPU 内部的程序计数器(PC)会被设置为特定的复位向量地址,这个地址指向芯片内部固化的启动代码(通常在芯片内部的 ROM 或 Flash 中),在嵌入式装置中,这个所谓的启动代码往往就是UBoot的一小部分。为什么只放一小部分呢?因为整个UBoot程序相较于CPU内部存储来说还是比较大的,仅仅CPU的片内存储是不够的。

  • 引导加载程序(如 UBoot)启动

        处理器从复位向量地址开始执行代码,首先运行的通常是一小段引导加载程序。在很多嵌入式系统中,会使用 UBoot 作为引导加载程序。与上文呼应。

        UBoot 启动后,它会进行一系列更为详细的硬件初始化。这包括初始化存储设备接口(如 NOR Flash、NAND Flash、SD 卡等)、内存控制器(设置内存的时序参数、映射内存地址空间等)、网络接口(如果设备支持网络启动)等。对于存储设备,UBoot 会识别其类型、容量和分区情况。(标红部分,初始化过程文末有详细介绍)

        UBoot 还会加载设备树(Device Tree)文件(如果系统采用设备树架构)。设备树是一种描述硬件设备的数据结构,它包含了设备的各种信息,如 CPU 型号、内存大小、外设连接情况等。UBoot 利用设备树来了解系统的硬件配置,以便更好地进行后续的加载和启动操作。

  • 加载操作系统内核

        在完成硬件初始化后,UBoot 会根据预先配置的参数,从存储设备中查找并加载操作系统内核。如果内核存储在 Flash 中,UBoot 会使用 Flash 驱动程序来读取内核二进制文件,并将其加载到内存中的指定位置。例如,对于 Linux 内核,可能会加载到内存的高端地址区域。注意:FLASH的驱动程序会集成为UBoot的一部分。

        同时,UBoot 会向内核传递启动参数。这些参数包括根文件系统的位置(如存储设备的分区号、文件系统类型等)、控制台设备的设置(如串口波特率、数据位、停止位等)、以及一些特定于硬件的配置信息(如内存大小、CPU 频率等)。这些参数对于内核正确启动和初始化非常关键。

  • 操作系统内核初始化

        一旦内核被加载到内存中,处理器就开始执行内核代码。内核首先会进行自身的初始化工作。这包括设置中断向量表、初始化内核数据结构(如进程控制块、内存管理数据结构等)、建立内存管理机制(如页表初始化)。

        接着,内核会根据 UBoot 传递的参数来挂载根文件系统。如果根文件系统是基于 ext4 等文件系统类型,内核会调用相应的文件系统驱动程序来解析文件系统结构,从而能够访问根文件系统中的文件和目录。

        内核还会初始化各种设备驱动程序。对于嵌入式系统中的常见设备,如串口、以太网接口、USB 接口等,内核会调用相应的驱动程序来完成设备的初始化和注册工作,使这些设备能够被系统识别和使用。

  • 启动用户空间进程和应用程序

        在完成内核初始化和设备驱动程序的加载后,内核会启动第一个用户空间进程(通常是 init 进程)。这个进程是用户空间的始祖进程,它会根据系统的初始化脚本(如 init.rc 等)来启动其他系统服务和应用程序。

        例如,在基于 Linux 的嵌入式系统中,init 进程可能会启动网络服务、文件系统守护进程(如 nfs - daemon 等)、用户界面程序(如果是有用户界面的嵌入式设备)等。这些应用程序和服务会根据系统的设计和用户的需求,提供各种功能,如网络通信、数据存储和用户交互等。

UBOOT初始化硬件设备时的部分具体细节

        关于网络启动:

        以前装置在进行网络启动时我一直有个疑问,协议栈是内核的一部分,进行网络加载时明明内核都没起来,压根 也没有网络协议栈,是怎么实现从网络加载程序的,今天看了Uboot终于理解了。

        嵌入式设备在启动时,首先运行的是 Bootloader,如 UBoot。UBoot本身就具备一定的网络功能支持。它们被设计用来初始化硬件设备,包括网络接口芯片。例如,UBoot 可以配置以太网控制器的寄存器,设置 MAC 地址、网络速度和双工模式等基本参数。

        Uboot对网络初始化的具体细节

        嵌入式设备的网络硬件通常有一些默认的配置或者可以通过硬件引脚等方式进行简单的初始设置。例如,一些以太网控制器芯片有默认的自协商模式,能够自动确定网络连接的速度和双工模式。在这种情况下,即使内核尚未启动,只要 Bootloader 能够正确识别和利用这些硬件特性,就可以建立基本的网络连接。

        UBoot在初始化网络硬件后,可以通过 TFTP(Trivial File Transfer Protocol)来实现从网络加载文件。TFTP 是一种简单的文件传输协议,它基于 UDP 协议,不需要复杂的操作系统级别的网络栈支持,主要用于在局域网内进行文件传输。

        TFTP 协议的操作相对直接,主要包括读取文件请求、数据传输和确认等基本步骤。嵌入式设备(通过 UBoot)可以作为 TFTP 客户端,这使得嵌入式设备在启动的早期阶段就能够有效地实现文件通过网络从TFTP服务器到设备的传输,从而在设备内核尚未启动时完成对内核等关键文件的网络加载。

        关于网络启动时网口有默认IP地址:

        在设备制造过程中,一些网络相关的参数(如 IP 地址、子网掩码等)可能已经被预先配置到设备的非易失性存储(如 EEPROM 或 Flash 的特定区域)中。Bootloader 在启动时可以读取这些参数,进一步帮助其建立网络连接并进行网络加载。
        

关于UBoot 初始化内存

  1. UBoot 自身可以使用内存
    • UBoot 在启动过程中就会对内存进行初始化,并且会使用内存来完成自身的运行。当系统加电后,UBoot 首先会被加载到内存中的特定位置(这个位置通常是由硬件的启动机制决定的,比如在某些 ARM 系统中,可能会被加载到片内 RAM 的起始地址)。
    • 在初始化阶段,UBoot 会设置内存控制器,定义内存的工作模式(例如内存的频率、位宽、时序、内存的地址映射参数),这个过程实际上就是在为使用内存做准备。例如,在设置内存的时序参数时,UBoot 会根据内存芯片的规格说明书来配置相关寄存器,以确保内存能够正常工作。
    • 一旦内存初始化完成,UBoot 就会使用内存来存储各种数据和代码。比如,它会将自身的一些全局变量、函数调用栈等存储在内存中。同时,在执行一些命令或者加载内核等操作时,也会使用内存作为数据的临时存储区域。例如,当通过网络加载内核镜像时,接收到的内核数据片段会先存储在内存中,等待全部接收完成后再进行后续处理。
  2. UBoot 对内存的初始化也是为后续操作系统内核识别和使用做准备
    • UBoot 对内存的初始化工作是非常关键的,因为它为操作系统内核的正确运行提供了基础。操作系统内核在启动时需要知道内存的布局、大小等信息,而 UBoot 已经在启动过程中完成了这些基本的设置。
    • UBoot 会将内存的相关信息以参数的形式传递给操作系统内核。例如,在引导 Linux 内核时,UBoot 会通过设置启动参数(如 “mem = xxx”,其中 “xxx” 表示内存的大小)来告诉 Linux 内核系统中可用内存的大小。这样,Linux 内核在启动后就可以根据这些信息来正确地管理和使用内存,包括分配内存给各种进程、加载内核模块等操作。所以,UBoot 不仅自己使用内存,还为操作系统内核能够正确识别和高效使用内存奠定了基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值