您现在的位置是:首页 >技术杂谈 >6.嵌入式系统启动流程与PMIC供电的关系网站首页技术杂谈

6.嵌入式系统启动流程与PMIC供电的关系

心随雪冻 2026-03-16 12:01:04
简介6.嵌入式系统启动流程与PMIC供电的关系

一、前言

​ 在看PMIC的原理图和以及了解Regulator框架后,难免产生一个疑问,Regulator是用来供电的设备,甚至可以为CPU、DDR供电,但供电的大小又是由CPU通过i2c来控制,如果把Regulaitor输出的电压比作“蛋”,把CPU、DDR比作能下蛋的鸡,那么鸡还没下蛋时(CPU没控制PMIC时),蛋是哪里来的(控制CPU的电压是哪里来的)?

​ 抛开鸡和蛋的弯弯绕绕,其实不难猜出,CPU最初上电时肯定有一个勉强能工作的电压,这个电压的由来可能是PMIC的默认输出,也可能是其他硬件电路输出,然后等待SOC在uboot或内核运行PMIC的驱动后再进行调压供电给CPU。

二、SOC启动流程分析

参考传送门:

RK3399】RK3399启动引导流程分析
https://blog.csdn.net/dengjin20104042056/article/details/137828704

1 BootROM介绍

一般来说,SoC厂家都会做一个ROM在SoC的内部,这个ROM很小,里面固化了上电启动的代码(一经固化,永不能改,是芯片做的时候,做进去的);这部分代码呢,我们管它叫做BootROM,也叫作一级启动程序。

2 初始化硬件

芯片上电后先接管系统的是SoC厂家的BootROM,它主要初始化系统,CPU 的配置,关闭看门狗,初始化时钟,初始化一些外设(比如 USB Controller、MMC Controller,Nand Controller 等);

3 加载程序到SRAM(分不清ROM和SRAM的去学微机原理)

当我们拿到一款新的SoC时,都会进行电路原理图设计,我们一般会在芯片外挂一些存储设备(eMMC、Nand、Nor、SDCard等)和内存(SDRAM、DDR等)。

  • 可执行的程序(u-boot、Kernel)都放(烧写)到了外部存储器

  • BootROM的代码除了去初始化硬件环境以外,还需要去外部存储器上面,将接下来可执行的程序读到内存来执行。

  • SoC 厂家设计的DDR控制器呢,一般会支持很多种类型的DDR设备,并且会提供兼容性列表,即SoC厂家可能不知道用户PCB上到底用了哪种内存,不同的DDR的供电需求可能也是不一样的,即系统启动初期是不方便调用DDR的。

  • 一般来说呢,SoC都会做一个内部的小容量的SRAM ,BootROM将外部的可执行程序从外部存储器中读出来,放到SRAM去执行

  • 确定程序在什么内存运行的问题后,需要决定数据在哪里存储,亦即使用哪里存储的数据。SoC 厂家一般会支持多种启动方式,比如从eMMC 读取,从SDCard读取,从Nand Flash 读取等等。上电的时候,需要告诉BootROM需要从什么样的外设来读取后面的启动二进制文件;

    一般的设计思路是,做一组 Bootstrap Pin,上电的时候呢?BootROM去采集这几个IO的电平,来确认要从什么样的外部存储器来加载后续的可执行文件;比如呢,2 个 IO,2’b00 表示从Nand 启动,2’b01表示从eMMC 启动,2’b10 表示从SDCard 启动等等;

    当 BootROM读到这些值后,就会去初始化对应的外设,然后来读取后面要执行的代码;这些 IO一般来说,会做成板载的拨码开关,用于调整芯片的启动方式;

    以OK1046-C3为例

在这里插入图片描述

4.SPL的引入

芯片上电后BootROM会根据 Bootstrap Pin 去确定从某个存储器来读可执行的二进制文件到SRAM并执行;理论上来说,这个二进制文件就可以是我们的u-boot.bin文件了;也就是 BootROM 直接加载u-boot.bin;

理论上是这样的,但是这里有一个问题,就是SRAM很贵,一般来说,SoC的片上 SRAM 都不会太大,一般4KB、8KB、16KB…256KB不等;但是呢,u-boot 编译出来却很大,好几百KB,放不下

放不下怎么办?有两种办法:

  • 假设片内SRAM为4KB,uboot的前4KB程序实现uboot的重定位,即将uboot拷贝到SDRAM中运行;
  • 做一个小一点的boot程序,先让BootROM加载这个小的程序,后面再由这个小boot去加载uboot;这个小boot就叫做SPL(Secondary Program Loader),它很小很小(小于SRAM大小),它先被BootROM加载到SRAM运行,那么这个SPL要做什么事情呢?最主要的就是要初始化内存控制器,然后将真正的大u-boot从外部存储器读取到SDRAM中,然后跳转到大uboot。
5.rk3399的启动流程图

在这里插入图片描述

如上图所示:

(0)上电后,BootROM开始执行,初始化时钟,关闭看门狗,关 Cache,关中断等,根据 Bootstrap Pin 来确定启动设备,初始化外设;

(1) 使用外设驱动,从存储器读取SPL;

---------------- 以上部分是 SoC 厂家的事情,下面是用户要做的事情 ----------------

(2) SPL被读到SRAM 执行,此刻,控制权以及移交到我们的SPL 了;

(3) SPL初始化外部SDRAM;

(4) SPL使用驱动从外部存储器读取uboot并放到SDRAM;

(5) 跳转到SDRAM中的uboot执行;

(6) 加载内核;

6.rk3399 SOC地址与空间

进行重映射前:

  • 0x0000 0000 ~ 0xF800 0000:为DDR内存空间;
  • 0xFF8C 0000 ~ 0xFF98 0000:片内SRAM内存空间,一共192KB;
  • 0xFFFF 0000~ 0xFFFF 8000:为BootROM内存空间,一共32KB;
7.rk3399烧录的本质

RK3399提供从片外设备启动系统,如serial nand or nor flash、eMMC、SD/MMC卡。当这些设备中的启动代码没有准备好时,可以通过 USB OTG 接口将系统代码下载到各个外设存储中,这便是烧录的本质

烧录引导过程,是SOC厂商写好引导代码,存储在内部 BootROM中的。

PS:系统的启动就记到这了,再讲就不礼貌了,讲启动流程,是为了分析各个PMIC芯片的工作原理与使用方法。

三、结合系统启动流程分析的Firefly-RK3399主板供电状况

参考传送门:

exynos 4412 电源管理芯片PMIC 的配置及使用方法
https://news.eeworld.com.cn/mcu/ic557192.html

1.BootROM的执行,离不开CPU的供电

Firefly-RK3399 CPU的供电有两部分

  • VDD_CPU_L由PMIC RK808的Buck2提供,默认输出1v

在这里插入图片描述

在这里插入图片描述

  • VDD_CPU_B由PMIC SYR837提供,默认输出1v

在这里插入图片描述

在这里插入图片描述

2.初始化外设存储器,EMMC需要被供电,由DC-DC电路转换而来

在这里插入图片描述

3.SPL初始化外部SDRAM,DDR需要被供电

Firefly-RK3399 DDR的供电由由PMIC RK808的Buck3提供,通过上上上面的表可以看出,Buck3 这路电源比较特殊,不能通过寄存器修改电压,只能通过外部电路的分压电阻进行调节,所以如果需要修改电压需要修改外围硬件,在 Rockchip 的方案上一般作为 VCC_DDR 使用。

在这里插入图片描述

PS:firefly的主板原理图是这样画的,图中的表格估计是从原厂粘的,从开发板的规格书中看出肯定是DDR3,我没在RK808数据手册里看到过外围电阻应该怎么配比,也没看懂上面的电阻配比是不是DDR3,嗯,大家都寥寥草草的懂DDR是怎么被供电的就好

4.加载内核后,syr837驱动设定调压范围,cpu作为消费者根据频率调压

大概会有人有疑问,既然SOC能正常启动,还加PMIC驱动调节cpu的电压,岂不是多次一举?

我没查过具体的数据,大致原理为,默认的电压无法维持cpu在更高的频率工作。

我是遇到过类似的问题,某项目照搬的原厂的原理图,又没有修改配置设备树cpu的供电节点,导致测试过程中常常死机,降低cpu的频率也仅仅只是降低死机的频率。

&cpu_b0 {
	cpu-supply = <&vdd_cpu_b>;
};

vdd_cpu_b: syr827@40 {
		compatible = "silergy,syr827";
		reg = <0x40>;
		vin-supply = <&vcc5v0_sys>;
		regulator-compatible = "fan53555-reg";
		regulator-name = "vdd_cpu_b";
		pinctrl-0 = <&vsel1_gpio>;
		vsel-gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
		regulator-min-microvolt = <712500>;
		regulator-max-microvolt = <1500000>;
		regulator-ramp-delay = <1000>;
		fcs,suspend-voltage-selector = <1>;
		regulator-always-on;
		regulator-boot-on;
		regulator-initial-state = <3>;
			regulator-state-mem {
			regulator-off-in-suspend;
		};
	};

四、PMIC厂家的行为大赏

​ 在调nxp的主板过程中看到有用到PMIC芯片MC33PF8100,后面简称PF8100,对比官方的其他也使用的该PMIC的主板,他们给各自器件的输出电压差异很大,像是给DDR的供电的BUCK也没有对应的外围电阻可配置。在dmesg里也没有相关的regulator日志,内核源码里也找不到相关的源文件。

​ PMIC的输出的配置简直是凭空产生的,总不能机器的供电是靠人意识控制的吧?通过google得知,该PMIC需要特定的烧写板烧写固件。都难以想象,普通开发者在批量生产前的调试过程得多么麻烦。

参考传送门:

​ i.MX8QXP_PMIC_PF8100 OTP 配置操作方法
​ https://www.wpgdadatong.com/blog/detail/75069

五、后记

​ 关于PMIC的使用我前后用了三篇,PMIC往往有原厂配套设计,不难看出原厂对普通开发者在调试PMIC芯片上是抱有敷衍态度和恶意的。但能否正常供电是软件工作的前提,有的硬件设计者又只会粗暴抄袭,故软件调试的人加深对PMIC的了解十分必要。希望自己的蹚水行为能为后人铺路。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。