文档章节

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

提莫队长
 提莫队长
发布于 2016/08/08 22:57
字数 1161
阅读 95
收藏 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字节的数据块。

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

© 著作权归作者所有

共有 人打赏支持
提莫队长
粉丝 1
博文 7
码字总数 3196
作品 0
咸宁
程序员
预告:基于树莓派如何开发机器人 | 硬创公开课

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

金红
2017/02/16
0
0
用树莓派通过Java实现远程控制电灯

用树莓派通过Java实现远程控制电灯 本文章由 亓根火柴 原创,转载请注明出处:http://blog.csdn.net/qigenhuochai/article/details/17661845 传说,女娲娘娘炼就七根火柴,来帮助人类度过第一个...

亓根火柴
2014/01/02
0
0
Windows系统监听键盘通过UDP协议控制树莓派小车

  树莓派小车硬件从淘宝买到手后已经鼓捣很长时间了,其中最喜欢的应用是控制小车运动了。我的小车控制系统在开发的过程中遇到了很多小问题,都被我一一修正了,将开发经验与大家分享,希望...

FreeBuf
07/30
0
0
Banana Pi VS Raspberrry Pi,是敌是友?

现在开源硬件,已经成为了一种潮流,很多开源硬件项目不断推出各自的开源硬件产品. 市场上主流的有: raspberrry Pi, arDuino,Pcduino, CubieBoard, 在各自的发展过程中,大家都在维护各自的社区...

sinovoip
2014/07/31
0
0
树莓派+一根网线直连笔记本电脑

用网线直连电脑,不经过路由器。这个方法最大的特点用最少的工具玩树莓派。 一、材料:树莓派一部、网线一根,笔记本电脑一台。 1、树莓派:带供电系统和烧好Raspbian系统的SD卡; 2、网线:...

maweitao
2014/07/31
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

函数调用约定 (cdecl stdcall)

函数调用约定 (cdecl stdcall) 在 C 语言里,我们通过阅读函数声明,就知道怎么携带参数去调用函数,也能在函数体定义内使用这些参数。但是 CPU 并不直接完成函数调用的传参操作,这需要人为...

傅易
3分钟前
0
0
Python 核心编程 (全)

浅拷贝和深拷贝 1.浅拷贝:是对于一个对象的顶层拷贝,通俗的理解是:拷贝了引用,并没有拷贝内容。相当于把变量里面指向的一个地址给了另一个变量就是浅拷贝,而没有创建一个新的对象,如a=b...

代码打碟手
6分钟前
0
0
mysql5.7 修改datadir

mysql 的默认存储路径为 /var/lib/mysql ,修改后为 /data/mysql 关闭服务 service mysql stop 复制mysql 数据文件到新的目录 cp -rp /var/lib/mysql /data 查看原目录的权限,如果新目...

hotsmile
22分钟前
0
0
证书安装指引之Tomcat 证书部署

Tomcat 证书部署 0 申请证书 1 获取证书 如果申请证书时有填写私钥密码,下载可获得Tomcat文件夹,其中有密钥库 www.domain.com.jks; 如果没有填写私钥密码,证书下载包的Tomcat文件夹中包括...

吴伟祥
27分钟前
0
0
ConcurrentHashMap1.7和1.8的底层不同实现

1.Hashmap和HashTable在线程安全方面的优劣? Hashmap多线程会导致HashMap的Entry链表形成环形数据结构,一旦形成环形数据结构,Entry的next节点永远不为空,就会产生死循环获取Entry。 Hash...

刘祖鹏
42分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部