Nand Flash
Nand Flash
nand_page_read(unsignedint *buf, unsigned int page)
利用读页实现将Linux内核文件(Image)到读到内存0x20008000中,并运行Linux内核
1.将ftp://arm/day06/Image拷贝到共享目录
2.将cp /mnt/hgfs/1405/Image /tftpboot
3.启动开发板,烧写Image内核文件到Nand Flash中
(1) tarena# tftp 20008000 Image
(2) tarena# nand erase 0x600000 0xC00000
(3) tarena# nand write 0x20008000 0x6000000xC00000
tarena#tftp 23000000 shell.bin
tarean#go 23000000
shell#bootlinux
…………………………………………………………
………………………………………………………….
pleasepress the enter to activate this consle.
#/ls
坏块处理
原则:
Nand flash8192块
64页
main区
spare区 坏块的标志
0块
0
1
2
3
4
……
63
读第0页,第2048个字节(spare区第一个字节),如果不是0xFF,坏块,如果是0xFF
读第1页,第2048个字节(spare区第一个字节),如果是0xFF,若不是0xFF,坏块
好块
第0页,2048 0xFF
第1页,2048 0xFF
坏块
第0页,2048 不是0xFF
1块
0页2048
1页2048
0块
0
1
1块
64
65
2块
128
129
Shell#nbad
16进制 十进制
Bad Block:0x000000EA 234 0x1d40000
Bad Block:0x000000EC 236 0x1d80000
Bad Block:0x000000F4 244 0x1e80000
Bad Block:0x000000F6 246
Bad Block:0x000010A8 4264
Bad Block:0x00001938 6456
Bad Block:0x0000193A 6458
tarena#tftp 20008000 Image
tarena#nand erase 0x1200000 0xC00000
tarena#nand write 0x20008000 0x1200000 0xC00000
tarena #nand erase 0x1200000 0xC00000
NAND erase:device 0 offset 0x1200000, size 0xc00000
Skippingbad block at 0x01d40000
Skippingbad block at 0x01d80000
Erasing at0x1de0000 -- 100% complete.
OK
tarena #nand write 0x20008000 0x1200000 0xC00000
NAND write:device 0 offset 0x1200000, size 0xc00000
Main arearead (96 blocks):
Main areawrite (96 blocks):
Bad blocks234 at 0x1d40000 is skipped
Bad blocks236 at 0x1d80000 is skipped
12582912 bytes written: OK
tarena #
一:ARM体系架构
精简指令集(RISC)
复杂指令集(CISC)
ARM编程模型:
1.工作模式:
管理模式SVC:复位后,执行SWI指令后进入该模式
快速中断FIQ:发生高优先级的中断
中断IRQ:发生低优先级的中断
中止:用于处理非正常访问存储器
未定义:用于处理未定义的指令,执行的指令,不能识别
系统:与用户模式共用同一组寄存器的特权模式
用户:多数应用程序以及系统任务运行在该模式下
2.工作模式的分类:
异常/非异常:
异常:管理模式,快速中断,中断,中止,未定义
非异常:系统,用户
权限/非特权:
特权模式:其余6中都是特权模式
非特权模式:用户模式
3.工作模式之间是否可以切换,如何切换?
工作模式之间可以切换
切换的方式有两种:
1.处理器自动切换:发生异常,处理器自动进入对应的异常模式
2.指令切换
工作模式之间的切换需要遵循的规则:
1.特权模式之间可以随意切换
2.可以从特权模式进入用户模式,不能从用户模式切换特权模式
3.如果用户模式要进入特权模式,可以通过调用SWI指令来完成。
4.ARM的运行状态:
1.ARM状态
执行ARM指令,32bit
PC的值字(4个字节)对齐,PC的值最后两个bit 为0
指令地址 PC值后四位
20008000 0 0000
20008004 4 0100
20008008 8 1000
2000800C C 1100
20008010
2.Thumb状态
执行Thumb指令,16bit
PC的值半字(2个字节)对齐,PC的值最后1bit为0
指令地址 PC值后四位
20008000 0000
20008002 0010
20008004 0100
20008006 0110
20008008
2000800A
2000800C
2000800E
5.运行状态的切换
1.处理器自动切换
处理器进行异常处理,若在Thumb状态下,则进入ARM状态,异常处理完返回Thumb状态
2.用指令切换:BX(带状态切换的跳转指令)
6.寄存器
在Cortex-A8核心里
所有的寄存器都是没有地址,如要使用,直接使用r0 ,r1
寄存器是32bit
R0-R12:通用寄存器
R13(SP):栈顶指针,栈顶的地址,栈是内存的一个区域
异常模式下,都有自己的栈,
在发生异常时,CPU会自动切换异常模式,先保护现场,将上一模式的寄存器进行入栈,等到异常处理完毕,返回上一模式时,再将栈中保存的值依次出栈到对应寄存器
R14(LR):存放返回地址(存储普通的函数调用返回地址以及以及异常返回地址)
R15(PC):存放的取指的指令的地址(三级流水线的第一级取值阶段的指令地址)
CPSR:当前程序状态寄存器
SPSR:备份程序状态寄存器,当异常发生时,CPU会将CPSR的值保存到对应的异常工作模式下专有SPSR,当异常处理完毕后,再将SPSR的值恢复到CPSR中。
三级流水线
执行(宏观)一条指令,分三个阶段:
取指(Fetch)
解码(Decode)
执行(微观)(Execute)
这三个阶段,分了三个不同硬件来完成
取指 解码 执行
push
add push
ldr add push
正在执行指令的地址:20008000
正在取指指令的地址:20008008
PC=20008008
正在执行(微观)的指令的地址=PC-8(因为PC值是字对齐(ARM状态下))
CPSR/SPSR
mode[4:0]:模式位
T[5]:状态位
0:ARM状态
1:Thumb状态
F[6]:FIQ禁止位
0:开FIQ
1:禁止FIQ
I[7]:IRQ禁止位
0:开IRQ
1:禁止IRQ
[27:8] 保留位
N [31] 负数
Z [30] 0
C [29] 进位或者借位
V [28] 溢出标志位
NZCV 受指令执行完目标寄存器的值的影响
ARM支持的数据类型有字节、半字、字、双字
(内存中)数据的对齐方式有(在加载、存储指令中会用到):
字节对齐(字节访问内存)
半字对齐(半字访问内存)
字对齐(字访问内存)
注意要与PC值的字对齐和半字对齐分清!
PC值字对齐:ARM状态下,指令4字节
PC值半字对齐:Thumb状态下,指令2字节
一个是指令的对齐方式,一个是数据的对齐方式
数据的存储格式
对于多字节的数据类型的数据
大端:低位高地址,高位低地址
小端:低位低地址,高位高地址
大端和小端格式
0x12345678(4个字节)
(高地址) 小端 大端
0x20008003 12 78
0x20008002 34 56
0x20008001 56 34
0x20008000 78 12
(低地址)
二:ARM指令
少用跳转指令,尽量给指令加条件
CMP r3, #0 CMP r3,#0
BEQ skip ADDNEr0,r1,r2
ADD r0,r1,r2 skip:
skip:
1.跳转指令 B
(1)B{cond} <target_label>
start:
cmp r0, r1 //r0-r1
beq not_copy //在r0与r1相等的情况下,跳转到not_copy执行
mov r0, r1 //r0=r1
not_copy:
b . //无条件执行,原地跳转
跳转范围 PC=PC±32MB
指令机器码:bit[31:28]为条件码,bit[27:24]为操作码
剩下的低24位bit[23:0]用来存储偏移量,但是又因为ARM状态下指令地址(PC值)是按字对齐的,PC值低2位为0,所以实际计算偏移量的时候会自动加上低两位00,构成26为的偏移量!+/-32MB
eb00000a
1110 1011
101000
0x28
EQ:0000
B:101
24bit用来表示偏移量
1bit符号位
23bit偏移量 8M 23X220=223
25bit偏移量 32M 25X220=225
ARM指令,32bit,最后2bit为0
2.BL指令带链接的跳转指令
指令地址 机器码 指令
2000804c: eb00000a bl 2000807c <delay>
...
2000807c<delay>:
2000807c:e52db004 push {fp};
执行bl,PC=2000804c + 8 = 20008054
通过分析bl指令的机器码,得到偏移量为0x28
PC(new)=PC(当前)+偏移量
=0x20008054 + 0x28
=0x2000807C
2.带链接的跳转指令
指令格式: 跳转范围 PC=PC±32MB
BL{cond} <target_address>
CPU会将BL指令的下一条指令的地址保存在LR(R14),跳转到要执行的代码去执行,当执行完毕,返回时,将LR的值赋值给PC,即回到BL指令的下一条指令继续执行。
START:
MOV R0,#1 //R0=1
MOV R1,#2 //R1=2
BL DoAdd //执行该指令前,CPU将下一条指令(B .)
的地址保存在LR中,然后跳转到DoAdd
标号继续执行
B .
…
DoAdd:
ADD R0, R0, R1 //R0=R0+R1
MOV PC, LR //PC=LR,接下取指B. 指令,解码,
执行B .
B:无返回
BL:带返回,通常子函数的调用
3.带状态切换的分支指令:BX
指令格式
BX{cond} <Rm> 32bit
跳转范围限制
绝对地址、4G范围
指令功能伪代码:
如果指令指定的条件成立则
CPSR的T Flag=Rm[0]
PC =Rm AND 0xfffffffe
.CODE 32
ARM_code: (CPU处于ARM状态)
ADR R0, THUMB_code + 1 //R0=Thumb_code + 1
BX R0 //R0[0]给CPSR的T位
…… //PC=R0&0xfffffffe
1110
.CODE 16
THUMB_code:(CPU处于thumb状态)
ADR R0, ARM_code //R0=(ARM_code)addr
BX R0 //R0[0]给CPSR的T位
…… //PC=R0&0xfffffffe
1110
由于ARM指令,32bit,字对齐,地址的最后两bit位,将最后1bit的0给到CPSR的T 位,将当前的Thumb状态改回到ARM状态,并且跳转到ARM_code下继续执行代码。
跳转指令:
B :跳转范围PC(new)=PC(当前)+/- 偏移量(32M)
相对跳转
无返回的跳转
BL:跳转范围PC(new)=PC(当前)+/- 偏移量(32M)
相对跳转
带返回的跳转
在执行该指令时,CPU会将BL指令的下一条指令的地址保存到LR(R14)寄存器中,当跳转到的代码执行完毕之后,通过指令MOV PC ,LR将返回地址赋值给PC,之后,取指,解码,执行。通常用于函数的调用。
BX:跳转范围4G,绝对跳转
在执行该指令时,CPU会将Rm的bit[0]修改CPSR的T位,PC=Rm&0xFFFFFFFE,这样既实现了CPU状态的切换,又实现了程序的跳转。
ARM工作模式(7种)
ARM运行状态(ARM Thumb)
ARM寄存器
ARM支持的数据类型(字节,半字,字,双字)
ARM存储格式(大端,小端)
ARM指令集
跳转指令
数据处理指令