CPU上电后加载程序的流程 | 基于RK3399

芯片上电解复位之后执行的第一段程序,在芯片中称之为Bootrom loader。这部分程序在芯片制造过程中固化到其内部的ROM空间,具备只读属性,在实际使用过程中无法修改这部分内容,这部分程序的知识产权也仅归属于芯片公司所有。其实,你也可以将Bootrom loader称之为固件。

75e700bf7d9e549f00f2c4e9b806179d.png

对于ARM架构的处理器而言,芯片上电解复位后的PC通常是指向0x000000000xffff0000地址,也就是说,它会去该地址处取第一条指令、译码、执行。CPU能支持的启动模式通过硬件拨码的方式告知CPU,CPU上电解复位后内部逻辑会识别bootmode。依据识别出的bootmode决定去何处取第一条指令。假设解析bootmode后发现并不是从bootrom启动,而是从其他存储外设启动,例如norflashnandflashqspiflash等,这些外设就会变为CPU的一级启动设备,而CPU内部逻辑也会将这些启动外设的地址空间进行remap处理。

RK3399内部包含4个ARM cortex-A53以及2个cortex-A72,典型的cluster结构,cortex-A53作为小核而cortex-A72作为大核。当系统上电解复位之后,cortex-A53的core0作为第一个启动的核心,执行0xffff0000处的Bootrom loader程序。

其完整的启动流程如下图所示:

+--------+----------------+----------+-------------+---------+
| Boot   | Terminology #1 | Actual   | Rockchip    | Image   |
| stage  |                | program  |  Image      | Location|
| number |                | name     |   Name      | (sector)|
+--------+----------------+----------+-------------+---------+
| 1      |  Primary       | ROM code | BootRom     |         |
|        |  Program       |          |             |         |
|        |  Loader        |          |             |         |
|        |                |          |             |         |
| 2      |  Secondary     | U-Boot   |idbloader.img| 0x40    | pre-loader
|        |  Program       | TPL/SPL  |             |         |
|        |  Loader (SPL)  |          |             |         |
|        |                |          |             |         |
| 3      |  -             | U-Boot   | u-boot.itb  | 0x4000  | including u-boot and atf
|        |                |          | uboot.img   |         | only used with miniloader
|        |                |          |             |         |
|        |                | ATF/TEE  | trust.img   | 0x6000  | only used with miniloader
|        |                |          |             |         |
| 4      |  -             | kernel   | boot.img    | 0x8000  |
|        |                |          |             |         |
| 5      |  -             | rootfs   | rootfs.img  | 0x40000 |
+--------+----------------+----------+-------------+---------+

RK3399的二级启动设备支持SPI NOR FLASHSPI NAND FLASHeMMCSD以及USB load,可以将二级启动程序放置于上述静态存储设备中,RK3399通过读取ID BLOCK信息决定当前启动程序是否有效。

6aeeae19db981cea33db5a9f83624560.png

RK3399提供了镜像文件更新的软件工具AndroidTool.exe,该工具可以更新二级启动程序及之后的所有镜像。

32591d1cebead936002847bd61d8365e.png

对于如何进入到固件更新模式,这取决于板卡的设计方式,例如我们手中的这块板子,它进入固件更新方式如下:

使用 Type-C 线连接开发板和主机,按住 recover 键然不要松开然后按 reset 键系统复位,大约两秒后,松开 recover 键。系统将提示发现 loader 设备。


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

2c12252c163e6e4308c5514190b0f62a.png

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/464775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IPv6与IPv4的区别

Technorati 标签: Hank--network porter■第一个就不说哈,32bit直接升级到128bit了。 从2的32次方升级到2的128次方了,地球上的每一粒沙子都可以分到一个IP地址。这个是IPv6最拉风的地方. ■在IPv6中,路由器不能用自动配置机制来配置接口&…

前端安全系列(一):如何防止XSS攻击?

前端安全 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题的高危据点。在移动互联网时代,前端人员除了传统的 XSS、CSRF 等安全问题之外,又时常遭遇网络劫持、非法调用 Hybrid API …

判断一个链表是否为循环单链表

判断一个链表是否为循环单链表: #设置两个指针(fast, slow),slow步长为1,fast步长为2, 大概的思路如下: 如果链表为循环单链表,则fast与slow必定相遇。 如果链表不为循环单链表,则fast必定先指…

在腾讯的这半年

晚上和同事聚餐后,我和李总坐车回公司,李总在电话里面和大家开会,然后说着各种让大家帮忙的话,我看着窗外密密麻麻的车辆——想着,这一年又要过去了。我是有总结的习惯的,不管是做事情还是生活,…

mysql数据删除后无法恢复数据恢复_Mysql数据库delete删除后数据恢复报告

原标题:Mysql数据库delete删除后数据恢复报告数据库环境部署与故障原因:本次恢复的数据库安装在客户本地服务器上,服务器操作系统为windows2008 r2 。在当前环境内安装有mysql5.6单实例,引擎类型为innodb,表内数据存储…

HDU 下沙的沙子有几粒

题目网址: http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid2&sectionid3&problemid9 分析,这题其实是H和D的组合排列问题,只不过要考虑期间累计的H和D的数量关系。 用DP来做,可以推导出: dp…

一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针

输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针 typedef struct _node_t {struct _node_t *next;int data; }Node;Node *list_k_node(Node * head, int k) {Node *phead, *pkhead;if (NULL head || (0 > k)){return NULL;}fo…

Linux之yum安装lamp环境

参照链接: http://www.jb51.net/os/RedHat/9939.html http://pjhfjy.blog.163.com/blog/static/47876996200963025757122/ http://oldleader.blog.163.com/blog/static/170861343201102085947386/ http://arqiang86.blog.163.com/blog/static/1092594200871211548121/

倒计时跳转页面

<h3>目标&#xff1a;百度<span idt></span></h3> <script>var i5;var tdocument.getElementById(t);t.innerHTML i秒后跳转;setInterval(function () {t.innerHTML--i秒后跳转;if(i0){location.hrefbaidu.com}},1000) </script> 转载于:h…

Linux启动流程 | kernel执行第一个init应用程序的实现原理

1. 概述Linux系统启动过程中通过init_task创建0号idle进程。然后通过kernel_thread创建1号init进程。创建该进程时通过系统调用&#xff0c;在内核空间执行用户空间的/sbin/init程序&#xff0c;通过该程序产生出shell&#xff0c;并依赖init衍生出其他进程。通过top命令查看当…

m进制转换为n进制

m进制转换为n进制 void m2n(unsigned char *dest, unsigned int n, unsigned char *src, unsigned int m) {unsigned char ch, *p dest - 1;unsigned int i 0;if ((NULL dest) || (NULL src)){return ;}if ((m < 2 || m > 36) || (n < 2 || n > 36)){return ;}…

初始化linux-nginx的安装和使用

初始化linux-nginx的安装参考&#xff1a;https://blog.csdn.net/damys/article/details/68944070http://www.runoob.com/linux/nginx-install-setup.htmlhttps://www.cnblogs.com/crazylqy/p/6891929.html PS&#xff1a;为什么叫初始化linux&#xff0c;因为我用的是标准版的…

poj1484

简单题 View Code #include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define maxn 25int n, m, blow, power[maxn];bool on[maxn];void out(int a){int b m - a - 1;int x;for (int i 0; i < b; i…

memcpy()

memcpy()&#xff1a;把一块内存src的前count个字符复制到目的内存dest中 memcpy()用于对一块连续内存的拷贝&#xff0c;可用于对任何类型的数据拷贝&#xff0c;在拷贝时&#xff0c;需要指出要拷贝数据的大小 void *memcpy(void *dest, const void *src, unsigned int cou…

西安下雪了,做了一个室内温度计

摘要&#xff1a;最近各地都在下雪&#xff0c;湖南湖北西安都下雪了。养热带花草和宠物的同学们需要多留意室内温度。下面教一个实用性强、制作简单的温度计。使用DS18B20温度传感器和OLED模块构建&#xff0c;这里使用的开发板是Arduino。本项目的源码和3D文件在后台回复&…

oci mysql_Oracle常用的OCI函数

欢迎进入Oracle社区论坛&#xff0c;与200万技术人员互动交流 >>进入 sword OCIEnvInit ( OCIEnv **envhpp, ub4 mode, size_t xtramemsz, dvoid **usrmempp ); 注&#xff1a; 在8i以后&#xff0c;可用OCIEnvCreate一个函数就可以初始化环境了&#xff0c;相当于OCIIni…

sort注意事项

虽然是小事但是还是得注意一下&#xff1a;sort 区间左开右闭 从0开始 e.g: 10 9 8 7 6 5 4 3 2 1 sort(a6,a11) 区间 6 - 10 sort(a6,a10) 区间 6 - 9转载于:https://www.cnblogs.com/asdic/p/9758532.html

C语言预处理功能——关于字符串化和符号粘贴

在C语言开发中&#xff0c;宏定义是一个非常有用的工具&#xff0c;它可以使我们的代码更容易理解&#xff0c;更容易维护。如查一个常量在多处被使用&#xff0c;且今后可能会根据不同需要而修改的话&#xff0c;将其define一下那是再好不过了。除此之外&#xff0c;宏定义还有…

memmove()

memcpy()只是memmove()的一个子集 memcpy()在执行内存重叠的情况下时&#xff0c;就会发生错误&#xff0c;而memmove()不会 void *memmove(void *dest, const void *src, size_t count) {assert((dest!0)&&(src!0));unsigned char *pdest (char * )dest;unsigned char…