文档章节

[233]树莓派裸机代码bootloader学习总结

提莫队长
 提莫队长
发布于 2016/08/08 22:57
字数 1161
阅读 274
收藏 0

代码来源:https://github.com/dwelch67/raspberrypi/tree/master/bootloader05

前要:po学渣,想造车轮,于是开始了不归路。

树莓派启动流程(照搬github主原文):

  1. boots off of an on chip rom of some sort
  2. reads the sd card and looks for additional gpu specific boot filesbootcode.bin and start.elf in the root dir of the first partition(fat32 formatted, loader.bin no longer used/required)
  3. in the same dir it looks for config.txt which you can do things likechange the arm speed from the default 700MHz, change the address whereto load kernel.img, and many others
  4. it reads kernel.img the arm boot binary file and copies it to memory
  5. releases reset on the arm such that it runs from the address where the kernel.img data was written.

所以kernel.img会被gpu加载到0x8000的地方,我们要写的代码于是就从这里开始。

file:vectors.s

.globl _start
_start:
    b skip

.space 0x200000-0x8004,0  ;这里将0x8004到0x200000的数据统统填为0

skip:
    mov sp,#0x08000000
    bl notmain
....

为什么填0x8004,原因是0x8000地址开始是要写一个跳转指令,跳转到skip这边来。

所以,原理一下子就明晰了,写代码然后做成kernel.img给gpu加载到内存0x8000的地方并让cpu去执行。

剩下的就是如何组织代码结构的问题了。

github主的方法是,cpu加载他的代码,然后他的代码配置uart,并等待数据传输进来,然后从0x8000这里开始堆放代码数据,最后执行跳转到0x8000执行您传输的数据。

file:periph.c
.......
#define AUX_ENABLES     0x20215004
#define AUX_MU_IO_REG   0x20215040
#define AUX_MU_IER_REG  0x20215044
#define AUX_MU_IIR_REG  0x20215048
#define AUX_MU_LCR_REG  0x2021504C
#define AUX_MU_MCR_REG  0x20215050
#define AUX_MU_LSR_REG  0x20215054
#define AUX_MU_MSR_REG  0x20215058
#define AUX_MU_SCRATCH  0x2021505C
#define AUX_MU_CNTL_REG 0x20215060
#define AUX_MU_STAT_REG 0x20215064
#define AUX_MU_BAUD_REG 0x20215068
.......

github主说uart地址在0x20215000这里开始,树莓派的datasheet却写的是0x7E20 1000(arm pl011)和0x7E21 5000(mini uart)

当然,kernel.img我也没具体运行过,懒。既然mmu也没启用,肯定是github主写错了,要不就是我错了(已解决,看下面的更新)。

然后github主弄了个判断xmodem传输协议(看下面的更新解释)的代码来判断数据传输状态

file:bootloader05.c
//SOH 0x01
//ACK 0x06
//NAK 0x15
//EOT 0x04
.......
if(state==0)
        {
            if(xstring[state]==0x04)
            {
                uart_send(0x06);
                for(ra=0;ra<30;ra++) hexstring(ra);
                hexstring(0x11111111);
                hexstring(0x22222222);
                hexstring(0x33333333);
                uart_flush();
                BRANCHTO(ARMBASE);
                break;
            }
        }
........

当接受的数据块头标识着EOT(我猜全称是end of transmit)时,就完成数据写入,并反馈,然后跳转执行您发送的数据。

由于我要造轮子,所以研究到这还不够。于是打开了bootloader05.list,并打开kernel.img和vectors.o继续研究。

kernel.img与vectors.o前面一部份相同,原因是kernel.img是vectors.o与其他文件一同链接成的(elf文件格式)然后生成的纯代码块(elf应该是linux下一种软件执行标准)。

kernel.img开头就是FE DF 07 EA,这应该就跳转指令,由于大小端的原因(其实我并不知道具体意思...)实际加载到cpu是EA 07 DF FE,对比bootloader05.list即可分析出来。

然后查表,armv7架构arm指令里跳转指令是b,由于有几种处理器都是32位的,所以有个cond这个值用来判断处理器(这句话我瞎编的,我也不知道是干嘛的)。

但后边的1010确实是A,所以应该就是这个指令。07 DF FE 是imm24,是有符号的值,用来表示当前运行地址指针(不知道是什么指针,先不研究)要偏移的量。

参考过的文章:http://blog.csdn.net/logicworldzju/article/details/8923596

更新:

前面的地址问题,我弄明白了。一共有三种地址

  1. ARM virtual addresses (standard Linux kernel only)(这个地址是开启了mmu后的地址)
  2. ARM physical addresses(cpu访问的地址,实际访问时的地址)
  3. Bus addresses(总线地址,arm总线amba连接外围设备,然后芯片厂商将总线上的设备地址转换给cpu能用的地址去访问)

所以,由于没有开启mmu,实际的设备地址在cpu看来应该是从0x7E00 0000偏移到了0x2000 000。

偏移量为0x5E00 0000,所以mini uart的地址是0x7E21 5000 - 0x5E00 0000 = 0x2021 5000。

关于XModem协议

XModem协议介绍:
XModem是一种在串口通信中广泛使用的异步文件传输协议,分为XModem和1k-XModem协议两种,前者使用128字节的数据块,后者使用1024字节即1k字节的数据块。

这里说的异步文件传输,不知道这个异步到底是个什么异步。看了下这个文章,估计是指每块数据块之间不严格限定时间间隔。

© 著作权归作者所有

共有 人打赏支持
上一篇: [233]暂无标题
下一篇: gdi截屏代码
提莫队长
粉丝 1
博文 7
码字总数 3196
作品 0
咸宁
程序员
私信 提问
预告:基于树莓派如何开发机器人 | 硬创公开课

此前我们收到读者反馈,想听一节关于如何用树莓派开发机器人。树莓派为学习计算机编程教育设计的一种微型电脑,其系统基于Linux, 只有信用卡大小但视频、音频等功能通通皆有,可谓是“麻雀虽...

金红
2017/02/16
0
0
10 个最值得关注的树莓派博客

如果你正在计划你的下一个树莓派项目,那么这些博客或许有帮助。 网上有很多很棒的树莓派爱好者网站、教程、代码仓库、YouTube 频道和其他资源。以下是我最喜欢的十大树莓派博客,排名不分先...

作者: Ben Nuttall
2018/11/02
0
0
基于树莓派如何开发机器人(附PPT+视频) | 硬创公开课

导语:树莓派是为学习计算机编程教育而设计的一种微型电脑,其系统是基于Linux的, 虽然只有信用卡大小,但视频、音频等功能通通皆有,可谓是“麻雀虽小,五脏俱全”。因此自问世以来,受到了...

金红
2017/03/09
0
0
树莓派基金会创始人Eben Upton 2014年中国行

8月中旬,树莓派基金会创始人Eben Upton来到中国,在亚太授权代理商RS Components欧时电子的陪同下,在上海、深圳和台北三个城市,与树莓派迷们面对面的深入交流,进行了一次颇具影响的“树莓...

RS_Components
2014/09/16
264
0
树莓派笔记02—树莓派硬件环境准备

在开始玩转树莓派之前,我们需要了解下树莓派的硬件配置以及所需要的配件。跟电脑PC机类似,树莓派也需要必要的输入输出设备才能工作。 1. 树莓派3B+ 2018年3月14日,树莓派基金会正式发布新...

TonyCode
2018/08/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

SpringCloud 与 SpringBoot 的版本兼容

Spring Cloud Finchley 构建并使用 Spring Boot 2.0.x,预计不会与Spring Boot 1.5.x一起使用Spring Cloud Edgware Spring Boot 1.5.xDalston 和 Edgware 发布版基于Spring Boot 1......

晨猫
10分钟前
1
0
microtime 记录的时间点,以毫秒来显示,并显示每一阶段占用百分比。统计代码执行时间。

function mini_bench_to($arg_t, $arg_ra=false){ $tttime=round((end($arg_t)-$arg_t['start'])*1000,4); if ($arg_ra) $ar_aff['total_time']=$tttime; else $aff="total......

lwkai
12分钟前
2
0
Docker 解决容器时间与主机时间不一致的问题三种解决方案

这篇文章主要介绍了Docker 解决容器时间与主机时间不一致的问题的相关资料,这里提供了三种方法,供大家参考,需要的朋友可以参考下 Docker容器时间与主机时间不一致 通过date命令查看时间 查...

Jack088
14分钟前
2
0
neo4j 开启远程web访问7474端口 以 用浏览器打开远程neo4j的web控制台界面

一、对于3.0以前的版本 在安装目录的 $NEO4J_HOME/conf/neo4j.conf 文件内,找到下面一行,将注释#号去掉就可以了 #dbms.connector.https.address=localhost:7474 改为 dbms.connector.https...

Airship
14分钟前
2
0
集合排序

根据指定规则,对集合元素进行自定义排序 List<Map<String, Object>> list= data.stream().sorted(new Comparator<Map>() { @Override public int compare(Map o1, Map o2) { Comparator c =......

zhaochaochao
15分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部