嵌入式linux开发 (二十二) 内存管理(4) I.MX6ULL内存管理
正点原子ARMLinux开发板I.MX6ULLcortex-A7ARMv7-内置sram:128KBsrom:96KB,用户不可编程-外扩NT5CC256M16EP-EK:512MB,DDR3LKLM8G1GET:8GB,EMMC硬件对内存的管理总述系统架构1 sram2 DDR3L软件对内存的管理...
·
- 正点原子ARMLinux开发板 I.MX6ULL cortex-A7 ARMv7
-内置
sram:128KB
// 名字为OCRAM
// 0090_0000 0091_FFFF 128 KB OCRAM 128 KB
srom:96KB,用户不可编程
//0001_7000 0001_7FFF 4 KB Boot ROM—Protected 4 KB area
//0000_0000 0001_6FFF 92 KB Boot ROM (ROMCP)
-外扩
NT5CC256M16EP-EK:512MB,DDR3L
//8000_0000 FFFF_FFFF 2048 MB MMDC—x16 DDR Controller
KLM8G1GET:8GB,EMMC
// 通过sdio接口访问,没有编址.
硬件对内存的管理
- 总述系统架构
The memory system consists of these components:
• Level 1 cache—32 KB instruction, 32 KB data cache
• Level 2 cache—unified instruction and data (128 KB)
• On-Chip Memory:
• Boot ROM, including High-Assurance Boot (HAB, 96 KB)
• Internal fast access RAM (OCRAM, 128 KB)
• External memory interfaces:
• 16-bit LP-DDR2, 16-bit DDR3-400, and LV-DDR3-400 //8000_0000 FFFF_FFFF 2048 MB MMDC—x16 DDR Controller.
• 8-bit NAND-flash, including support for Raw MLC/TLC, 2 KB ,4 KB, and 8 KB
page size, BA-NAND, PBA-NAND, LBA-NAND, OneNAND™, and others
• BCH ECC up to 40 bits
• 16-bit NOR flash
• 16-bit PSRAM, Cellular RAM
• Dual-channel/single-channel QuadSPI flash
- 1 sram
// 0090_0000 0091_FFFF 128 KB OCRAM 128 KB
- 2 DDR3L
8000_0000 FFFF_FFFF 2048 MB
- 3 BOOT配置
1. 上电
2. 根据 BOOT_MODE[1:0]的设置来选择 BOOT 方式 // 可以通过两种方式改变.一种是改写 eFUSE(熔丝),一种是修改相应的 GPIO 高低电平
2.1 [00]从 FUSE 启动
2.1 [01]串行下载
2.1.1 简介:
通过 USB 或者UART 将代码下载到板子上的外置存储设备中
2.1.2 过程
读取usb数据,下载到sram.
从sram启动
2.1.3 应用举例:
DDR3 测试工具读取init scripts,会将测试使用的固件下载到 i.MX6X的内部 RAM 中,用于测试外部的 DDR3
2.2 [11]保留
2.3 [10]内部boot模式,从bootrom启动
2.3.1 简介
从bootrom启动,然后做相关初始化之后,探测BOOT_CFG1 BOOT_CFG2 BOOT_CFG4,得到需要加载的设备(QSPI WEIM Serial-ROM SD eMMC NAND 中的一种),然后从加载该设备(二级启动设备)的内容,并进行下一步动作
2.3.2内部bootrom运行(figure8-3有bootrom的存储分布图)
初始化时钟
使能MMU和cache
从指定的加载设备读取bin文件的头到sram.
根据头初始化ddr
然后根据头(bin文件位置a,大小b) 拷贝b大小字节(bin文件的大小)到a地址(在sdram或ocram中),开始运行bin中的代码(用户代码)
2.3.3bin文件有什么内容
1.image vector table(8个)
2.boot数据
3.device configure data
4.用户数据和代码
软件对内存的管理
- 硬件(包括bootrom)已经做了什么
// 我们分析的是2.3 [10]内部boot模式,从bootrom启动的过程
1. 初始化时钟 使能MMU和cache // I.MX6ULL 不需要关看门狗
2. 初始化ddr
// 虽然是读取的二级启动设备中的数据,并根据该数据 初始化了ddr, 我们也应该将其看为硬件做的部分
// 注意: bootrom中读取的数据需要我们关心,因为初始化不同的ddr用到的数据不同
3. 将用户代码搬移到ram,并执行.
- 软件(用户代码)还需要做什么(对比stm32)
1. stm32
内存映射启动
stm32 代码 重定位(.data .bss .code .ro-data)
初始化 .stack .heap
初始化c库
调用用户main函数
2. imx6ull // 参考 汇编代码demo
从 bootrom启动
从SD卡外置存储中读取ddr信息,然后初始化ddr
读取bin头部,并将bin文件拷贝到0X87800000(重定位.code) // 地址0X87800000 可以自定义
然后pc=0X87800000.
执行用户函数
stm32 官方的代码 和 imx6ull 硬件(固化代码bootrom)做的 我们都可以看做是 官方已经做好的.那么对比得到
不同点
1.stm32 多做了初始化 .data .bss .ro-data .stack .heap 及 C库 .
2.imx6ull 多做了 初始化ddr
相同点
都初始化了.data段
imx6ull 用户代码还需要做的部分
初始化 .bss .stack .heap 及 C库 .
- 软件(用户代码)主要怎么做
初始化 .bss .stack .heap 及 C库
链接知识
-Ttext 0X87800000 是将 .bin文件中中的.text段 .ro-data .data 放在了 0X87800000.
// 虽然示例给的 .s 文件 只有 .text段, 没有其他段. 但其实还可以扩充 .ro-data .data
// 注意不可以扩充 .bss .stack .heap
// 编译一个文件的时候会生成一个.o文件,.o文件包括很多段,其中就有 .text .ro-data .data ,但不会有.bss .stack .heap
虽然 .o 会 有很多段,但是没有链接方法将各种段布局到最终的elf文件中去
然后可以通过链接文件解决这个问题.
那么需要做:
创建链接文件(将.s中的各种段布局到elf文件中)
需要补充的内容:
gcc 会将 一个源文件编译成 .o
链接文件怎么写
汇编代码demo
1、使能所有时钟
2、设置 GPIO1_IO03 复用为 GPIO1_IO03
3、配置 GPIO1_IO03 的 IO 属性
4、设置 GPIO1_IO03 为输出
5、设置 GPIO1_IO03 输出低电平
6、循环
// 代码中用到了一些指令,该指令为 位置相关代码
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf // elf 文件中会有 0X87800000
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin // 因为 代码中有位置相关代码,所以bin文件中有 0X87800000
//烧写 到sd卡
./imxdownload led.bin /dev/sdd
// 过程中生成一些初始化ddr的数据结构(用于bootrom读取并初始化ddr)及一个bin头部(有bin文件大小及位置信息0X87800000 ,用于指示bootrom将bin文件加载到0X87800000)(0X87800000这个信息是写到了 imxdownload软件中,具体在头文件)
// 然后和bin 重新组成一个bin文件,为load.imx(bin文件格式),然后用dd命令将bin文件直接写入sd卡
// 启动
bootrom启动
从SD卡外置存储中读取ddr信息,然后初始化ddr
读取bin头部,并将bin文件拷贝到0X87800000
然后pc=0X87800000.
其他问题
问题:
imx6ullreset 时CPSR状态
0x600000d3 0110 0000 0000 0000 0000 0000 1101 0011 // 禁止IRQ 禁止FIQ ARM 状态 SVC(管理)模式
bootrom有没有改 CPSR ???
bootrom 执行用户代码时 CPSR 为多少???
CPSR 的值对应不同的模式,而不同模式的SP寄存器是不一样的,所以设置SP的时候需要注意该SP是什么模式下的.
更多推荐
所有评论(0)