第二季-专题5-核心初始化
专题5-核心初始化
第1课-异常向量表
一.概念解析
- 异常定义
因为内部或者外部的一些事,导致处理器停下正在处理的工作,转而出处理这些发生的事件。
- 异常类型
Arm处理器有七种异常类型,依次是:重启键,用户自己的命令未识别,软中断,预取指令识别,取数据失败,中断,快速中断。
- 异常向量
当一种异常发生的时候,ARM处理器会跳转到对应异常的固定地址去执行异常处理程序,而这个固定的地址,就称为异常向量。
- 向量表
由七个异常向量以及其处理函数跳转关系组成的表就是异常向量表:
0x00000000: b reset
0x00000004: ldr pc, _undefined_instruction
0x00000008: ldr pc, -software_interrupt
0x0000000c: ldr pc, _prefetch_abort
0x00000010: ldr pc, _data_abort
0x00000014: ldr pc, _not_used
0x00000018: ldr pc, _irq
0x0000001c: ldr pc, _lrq
二.代码编写
start.s
gboot.lds
makefile
start.S
.text
.global _start
_start:
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction @使得伪指令变成了装载指令
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
undefined_instruction:
nop
software_interrupt:
nop
prefetch_abort:
nop
data_abort:
nop
not_used:
nop
irq:
nop
fiq:
nop
reset:
nop
gboot.lds
OUTPUT_ARCH(arm) //宏定义,输出格式是arm的
ENTRY(_start) //宏定义,输出程序的入口
SECTIONS {
. = 0x30008000; //起始地址
. = ALIGN(4); //四字节,对齐的处理
.text : //代码段
{
start.o (.text)
*(.text)
}
. = ALIGN(4);
.data : //数据段
{
*(.data)
}
. = ALIGN(4);
bss_start = .;
.bss : //bss段
{
*(.bss)
}
bss_end = .;
}
makefile
all: start.o
arm-linux-ld -Tgboot.lds -o gboot.elf $^
arm-linux-objcopy -O binary gboot.elf gboot.bin
%.o : %.S
arm-linux-gcc -g -c $^ //通用规则
%.o : %.c
arm-linux-gcc -g -c $^
.PHONY: clean
clean:
rm *.o *.elf *.bin
三. 210处理器BL1头信息添加
我们编写的gboot充当BL1的作用,在210的irom中自带BL0,上电后率先运行的就是BL0,在BL0运行之后会进行一个校验。BL1之前是有16个字节的头的,LB0将BL1拷贝到irom里面后,会通过对BL1的计算,得到校验码。将这个经验吗和在BL1的头中填入的校验码进行比对,若是比对结果一样,BL1可以运行;若是不一样就BL1就不能运行,若BL1之中没有头文件,肯定BL1就不会运行。头文件格式如下:
0x0写的是:BL1的大小;
0x4没有用到;
0x8写的是用户写入的校验码大小;
0xc没有用到。
第2课-设置svc模式
这一部分不需要做2440、6410和210的区分
这是linux系统的其中工作模式,对于bootloader它的工作模式是supervisor,一种比较高级的工作模式,本节课的重点就是将处理它设置在supervisor模式。具体依靠的是程序状态字寄存器:
0-4字段设置的是工作模式,,将这5个字设置为10011就可以。
步骤:
(1)将这五个字段全部置零:bic
(2)将其中的三个字段置1:orr
(3)为了访问CPSR或者SPSR,需要使用mrs和msr
对start.s进行改动,如下:
.text
.global _start
_start:
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
undefined_instruction:
nop
software_interrupt:
nop
prefetch_abort:
nop
data_abort:
nop
not_used:
nop
irq:
nop
fiq:
nop
reset:
bl set_svc
set_svc:
mrs r0, cpsr @从cpsr取值
bic r0, r0, #0x1f
orr r0, r0, #0xd3 @理论上是#0x13用来表示10011,这里用#0xd3来表示@11010011,设置I和F两位为1,屏蔽了中断与快速中断
msr cpsr, r0 @将值放在cpsr
mov pc, lr
第3课-关闭看门狗
- 作用
在嵌入式领域,有些系统需要长期运行在无人看守的环境。在运行的过程中,难免不出现系统死机的情况,这时候需要系统自带的一种自动重启的功能。Watchdaog一般是一个硬件模块,起作用就是在系统死机时,帮助系统实现自动重启。
- 工作方式
Watchdaog在在硬件上实现了计时功能,启动计时后,用户(软件)必须在计时结束前重新开始计时,俗称“喂狗”,如果到超时的时候还没有重新开始计时,那么它就认为系统是死机了,就自动重启系统。
- 原理图
时钟源经过WTCON[15:8]和WTCON[4:3]分频器的处理,得到我们需要的时钟信号,之后通过WTCNT进行计数,当它检测到0的时候,没有新的WTDAT信号来重置,下面通过WTCON[0]进行重启。
看门狗有这么好的作用,之所以要关闭看门狗,因为bootloader是一个简单的程序,一般是不需要使用的,使用它会增加“喂狗”的操作,增加系统而定负担。
我们通过寄存器来完成这个操作。
在2440中,寄存器名字为WTCON,如下:
在6410中,寄存器名字为WTCON,如下:
设置与2440一样。
在210中的WTCON的地址是0xE2700000,其他设置与2440一样。
- 代码实现
修改start.s的下半部分,如下:
reset:
bl set_svc
bl disable_watchdog
set_svc:
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
mov pc, lr
#define pWTCON 0x53000000
disable_watchdog:
ldr r0, =pWTCON @把地址装载到r0
mov r1, #0x0 @mov只能访问通用寄存器,都设置为0
str r1, [r0] @将0的值都放在r0中
mov pc, lr
第4课-关闭中断
步骤:
(1) 在CPSR中将I位(中断位)和F位(快速中断位)设置为1,将它们关闭,这在我们设置svc模式的时候已经设置了#0xd3
(2) 设置中断屏蔽寄存器,把中断屏蔽掉
2440:
在s3c2440的芯片手册中,找到下图:
当中断请求前来的时候,会将请求指令记录在SRCPND里面,中断的请求要送到处理器,还要送到MASK寄存器,若将MASK(屏蔽寄存器)屏蔽掉请求信号,就不会有中断操作。在芯片手册的233页找到如下的内容:
这是32位的寄存器,将其中某一位写做1,对应的中断就会被屏蔽,也就是,将所有的位都置1就好了。
代码:
2440,将start.s作如下修改:
reset:
bl set_svc
bl disable_watchdog
bl disable_interrupt
set_svc:
mrs r0, cpsr
bic r0, r0,#0x1f
orr r0, r0,#0xd3
msr cpsr, r0
mov pc, lr
#define pWTCON 0x53000000
disable_watchdog:
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
mov pc, lr
disable_interrupt:
mvn r1, #0x0 @取反后赋值
ldr r0, =0x4a000008 @将寄存器地址记录下
str r1, [r0] @将值幅值给地址
mov pc, lr @返回原位置
6410:
6410中有两个中断使能寄存器,如下:
6410中有两个中断关闭寄存器,如下:
代码如下:
reset:
bl set_svc
bl disable_watchdog
bl disable_interrupt
set_svc:
mrs r0, cpsr
bic r0, r0,#0x1f
orr r0, r0,#0xd3
msr cpsr, r0
mov pc, lr
#define pWTCON 0x7e004000
disable_watchdog:
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
mov pc, lr
disable_interrupt:
mvn r1,#0x0
ldr r0,=0x71200014
str r1,[r0]
ldr r0,=0x71300014
str r1,[r0]
mov pc, lr
210:
210与6410类似都是采用向量中断,也分为使能IntEnable寄存器和屏蔽IntEnable寄存器。由于210分为更多功能的中断,它的屏蔽寄存器有4个,保存的地址分别是:
在6410基础上改写的代码是:
disable_interrupt:
mvn r1,#0x0
ldr r0,=0xf2000014
str r1,[r0]
ldr r0,=0xf2100014
str r1,[r0]
ldr r0,=0xf2200014
str r1,[r0]
ldr r0,=0xf2300014
str r1,[r0]
mov pc, lr
第5课-关闭mmu与cache
- ARM存储体系
金字塔顶端是各种寄存器,访问速度快但是数量有限;第二层是TCM,包括内存与cache,数量较多,但速度相对来说慢一些;辅助存储器数量更多,但是访问速度更加缓慢。
- cache
cache的存储图如下:
对比有无cache的访问主内存的方式,有cache的系统对主内存的访问效率更高。
cache是一种容量小但存取速度非常快的存储器,它保存最近用到的存储器中数据的拷贝。对于程序员来说,cache是透明的。它自动决定保存哪些数据、覆盖哪些数据。按照功能划分:
I-Cache: 指令Cache,用于存放指令
D-Cache:数据Cache,用于存放数据
对于2440的存储结构如下:
其中既有Data Cache有Instruction Cache,它们的大小都是16Kb。210中的连个cache大小是32KB。
- 虚拟地址
虚拟地址:程序中使用的地址。
物理地址:物理存储单元实际的地址
使用虚拟地址
-可以让进程使用更大的空间
-可以解决冲突
- mmu作用
在Arm11之前,根据虚拟地址就可访问cache,但是在Arm11本身包括之后的操作,需要实际的物理地址才能访问cache
- 关闭cache和mmu
mmu与cache的使用是需要一系列的配置才能使用的,并不是不用。只是在初始化的时候,必须将它们关闭,控制它们的是协处理器CP15。
2440:
在920核心手册里面,可以看到CP15有一个control register寄存器,它也是32位的寄存器,12位作用是Icache enable,第2为控制Dcache enable,第0位控制MMU,如下:
我们还要设置CP15里面的第7个寄存器,使得原本的数据无效,指令是:
MCR p15, 0, Rd, c7, c7, 0
步骤:
(1) 使Icache和Dcache失效
(2) 关闭Icache、Dcache和关闭mmu
修改start.s代码为:
reset:
bl set_svc
bl disable_watchdog
bl disable_interrupt
bl disable_mmu
disable_mmu:
mcr p15,0,r0,c7,c7,0 @使Icache和Dcache失效
mrc p15,0,r0,c1,c0,0 @将寄存器读出来,固定的格式,与下面的配对
bic r0, r0, #0x00000007 @使得第0和2位置零,12位可以不去处理
mcr p15,0,r0,c1,c0,0 @将寄存器写进去,固定的格式,与上面的配对
mov pc, lr @返回主函数的位置,bl将返回地址存在lr寄存器,当程序@运行结束,将返回地址传给pc指针
在6410与210的芯片上,CP15的结构是一样的,不用修改。
转载于:https://www.cnblogs.com/free-1122/p/11452006.html
第二季-专题5-核心初始化相关推荐
- 第二季4:初始化MPP系统(step12)
以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除. 前言 本文将详细介绍博文第二季3:sample_venc.c的整体分析中提及的"初始化MPP系统". MPP系统的初 ...
- 跟着王进老师学开发C#篇第二季:面向对象-王进-专题视频课程
跟着王进老师学开发C#篇第二季:面向对象-9471人已学习 课程介绍 面向对象的思想在现在程序开发中非常重要,很多刚入门的程序员没有真正理解面向对象的思想而被挡在在软件开发的门外,本次 ...
- Android自动化测试第二季(提高篇)-金阳光-专题视频课程
Android自动化测试第二季(提高篇)-17804人已学习 课程介绍 [金阳光测试]是由金阳光等创办的国内个人免费培训测试.欢迎喜欢测试的朋友来观看学习,提意见. 课程收益 ...
- Python可以这样学(第二季:tkinter案例精选)-董付国-专题视频课程
Python可以这样学(第二季:tkinter案例精选)-3592人已学习 课程介绍 董付国老师系列教材<Python程序设计基础>(ISBN:9787302410584) ...
- 火星人敏捷开发1001问(第二季)-陈勇-专题视频课程
火星人敏捷开发1001问(第二季)-17497人已学习 课程介绍 此课程为敏捷开发的课程,聚焦于敏捷开发中似是而非的各种问题.每个问题都会有分析与解决的环节,从而令学员不但得到可行的答 ...
- 血腥大地-第二季(资源破解与管理)-张立铜-专题视频课程
血腥大地-第二季(资源破解与管理)-2426人已学习 课程介绍 课程继承<血腥大地>游戏内容 1.主要完成游戏资源的获取,从原血腥大地游戏中获取(不涉及任何商业利益,不能将 ...
- 哈工程计算机学院领导门志国,电气学院“钥匙工程”第二季:赵洪教授为2018级新生打开专业之门...
以引领电气新生代感受专业魅力.感悟专业精神.坚定专业信仰.铭记专业使命.立志忠于祖国.忠于人民.忠于专业为宗旨的"钥匙工程"第二季迎来了第三位主讲嘉宾.9月4日8:30,电气与电子 ...
- 优酷直播节目“冠军体育课”第二季收官 共吸引近百万用户观看互动
[TechWeb]3月5日消息,昨天,阿里体育联合优酷少儿推出的直播节目"冠军体育课"第二季收官,张丹.张虹.朱芳雨.王仕鹏等七位体育明星分别走进优酷体育直播间,分享他们疫情宅家期 ...
- 尚硅谷面试第二季(周阳主讲)
尚硅谷面试第二季 1.volatile关键字 volatile是什么 volatile的作用 1.保证可见性 2.不保证原子性 3.禁止指令重排 DCL(单例模式双重锁) JMM模型 JMM是什么 J ...
- 亚马逊云科技Build On2022技能提升计划第二季——揭秘出海爆款新物种背后的黑科技
Build On是什么? 亚马逊云科技开发者Build On是由亚马逊团队策划.开发者社区联合打造的动手实操系列活动.它是以现实技术应用和需求场景为核心,结合时下重点技术领域与亚马逊云科技的前沿技术方 ...
最新文章
- 自带数据线的迷你数显充电宝,旅途必备
- JAVA (集合和数据结构)
- window对象方法之setTimeout(),setInterval()
- 打印机打印网页不清晰_针式打印机不开机故障维修
- Java字符类isLowerCase()方法与示例
- 17 java 存在的问题(转)
- JSP基础--J2EE赢在起跑线
- 微信怎么at所有人_微信怎么艾特所有人 微信艾特所有人方法
- unity3d:路径点移动,使用dotween(模拟蝴蝶飞舞)
- java gbk编码_Java GBK 中文乱码问题分析
- 现有存储系统技术架构
- Quartus .sof转换成.jic
- 2019年南京大学计算机研究生复试分数线,2019南京大学研究生分数线汇总(含2016-2019历年复试)...
- layui使用formselect4完成的下拉框多选,拼音搜索
- 微信小程序新手留言板
- 无人洗车小程序源码开发
- Kafka3.0 提交offset方式
- 在马斯克收购推特之际,为什么去中心化社交网络代表着必然的历史趋势?
- ie浏览器报错:不支持此类_浏览器趋势(2013年3月):IE降至30%以下
- DPDK mbuf引用计数出错的分析
热门文章
- php数据库密码查询,php数据库查询及密码匹配的功能
- Myeclipse打包生成jar文件 A exception has Occured问题解决
- sql 查出表转换为html,如何执行表中的sql语句并将其转换为html
- 深入解析 Flink 的算子链机制
- 投票 | 全球首个 Apache 线上盛会,直播 talk 由你决定!
- 牛逼!支付宝 App架构
- linux caffe ssd 编译,Ubuntu 16.04 编译 Caffe SSD
- python pickle反序列化漏洞_渗透测试 - 黑客技术 | 【技术分享】记CTF比赛中发现的Python反序列化漏洞_吾爱漏洞...
- python中列表去重有哪几种方法_python列表里的字典元素去重
- fscapture下载收费吗?_听歌要收费,下载又要付费?国内的音乐app还想干什么?...