目录
满栈,空栈,减栈,增栈
ARM中,要求使用满减栈
c语言中的局部变量是用栈来实现的,如果汇编没有设置栈地址,c代码定义的局部变量就会落空,导致整个程序崩了。
ARM有37个寄存器,7种模式,每种模式都有自己的SP(r13栈)寄存器
各种模式下用不同的栈,操作系统内核使用自己的栈,每个应用程序也使用自己独立的栈,这样各是各的,就不会说一个栈出错,整个系统崩。
cache是一种内存,叫高速缓存。
从容量来说:CPU < 寄存器 < cache < 内存DDR(RAM)
从速度来说:CPU > 寄存器 > cache > 内存DDR(RAM)
1.指令是放在flash/硬盘中的,运行时读取到DDR,再从DDR读到寄存器,再由寄存器送给cpu。
2.因为寄存器和DDR之间速度差异太大,DDR的速度远不能满足寄存器的需要(不能满足cpu的需
要,所以没有cache会拉低整个系统的整体速度)
3.cache工作时会把cpu正在运行指令的旁边几句指令事先读到cache。
4.读写cp15实现开关cache
位置有关编码:汇编源文件编码成二进制可执行时编码方式与位置(内存地址)无关
位置无关编码:汇编源文件编码成二进制可执行时编码方式与位置(内存地址)有关
对比:位置无关代码要好一些,适应性强,放在哪里都能正常运行;位置有关代码就必须运行在链接时指定的地址上,适应性差。位置无关码有一些限制,不能完成所有功能,有时候不得不使用位置有关代码。
链接地址:链接时指定的地址(指定方式为:Makefile中用-Ttext,或者链接脚本)
运行地址:程序实际运行时地址(指定方式:由实际运行时被加载到内存的哪个位置说了算)
uboot启动过程:上电后BL0运行,BL0会加载外部启动设备中的uboot的前16KB(BL1)到SRAM中去运行,BL1运行时会初始化DDR,然后将整个uboot搬运到DDR中,然后用一句长跳转(从SRAM跳转到DDR)指令从SRAM中直接跳转到DDR中继续执行uboot直到uboot完全启动。uboot启动后在uboot命令行中去启动OS。
分散加载:把uboot分成2部分(BL1和整个uboot),两部分分别指定不同的链接地址。启动时将两部分加载到不同的地址(BL1加载到SRAM,整个uboot加载到DDR),这时候不用重定位也能启动。
分散加载其实相当于手工重定位。重定位是用代码来进行重定位,分散加载是手工操作重定位的。
1.代码段,数据段,bss段(ZI段),自定义段
2.整个程序的所有东西分成了一个一个的段,给每个段起个名字,然后在链接时就可以用这个名字来指示这些段。也就是说给段命名就是为了在链接脚本中用段名来让段站在核实的位置。
3.段名分为2种:
先天性段名:编译器内部定的,代码段(.text),数据段(.data)非零初始化全局变量,bss段(.bss)零初始化全局变量
后天性段名:自己定义的
从源码到可执行程序的步骤:预编译、编译、链接、strip(把可执行程序中的符号信息给拿掉)
用来指挥连接器工作的,处理.o文件中的程序段,将其链接成一个可执行程序
链接脚本的关键内容有2部分:段名 + 地址(作为链接地址的内存地址)
SECTIONS {} 这个是整个链接脚本
. 点号在链接脚本中代表当前位置。
= 等号代表赋值
1.ldr和adr都是伪指令,区别是ldr是长加载、adr是短加载。
adr指令加载符号地址,加载的是运行时地址;ldr指令在加载符号地址时,加载的是链接地址。
2.用处:uboot分2次运行,BL1加载到SRAM,整个uboot加载到DDR。执行DDR时候需要重定位到指定地址
3.步骤:拷贝代码和数据段,清bss段,长跳转
1.扇区,软盘硬盘一般都是以扇区为单位,读写最小单位为扇区
2.一个扇区可以看成一个块(block)
3.常见块设备有:磁存储设备硬盘,软盘,flash等
1.Nand的结构可以看成是一个矩阵式存储器,其中被分成一个一个的小块,每一小块可以存储一个bit位,然后彼此以一定单位组合成整个Nand
2.Nand单次访问的最小单位叫Page(页),就是扇区
3.一个block(块)等于若干Page(页)
4.Nand中:Page是读写Nand的最小单位;Block是擦除Nand的最小单位
5.Nand的每个页由2部分组成,譬如K9F2G08中为2K+64字节,64k用来存储ECC数据(错误校验码)、坏块标志等