S5PV210开发1.0.5----重定位relocate与SDRAM

2023-12-12 10:08

本文主要是介绍S5PV210开发1.0.5----重定位relocate与SDRAM,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.5.1.关看门狗
1.5.2.设置栈、调用C语言
1.5.3.开iCache
1.5.4.重定位及其代码实战
1.5.5 SDRAM介绍

1.用汇编关看门狗

1.1 什么是看门狗?
watch dog timer,定时器,Soc的内部外设,看门狗可相当于闹钟,系统在闹钟响铃前必须把闹钟时间往后调,否则会响铃(不希望响铃,响铃会复位),往后调就不会响铃,系统正常工作时,具备自动将时间往后调这种能力。系统非正常,不会调时间,则响铃,看门狗把系统自动复位。

1.2 物理特性、原理图、数据手册
1.Soc内部外设
2.无原理图,外部外设才有原理图,看门狗不予外设相连接

1.3 特殊功能寄存器
在这里插入图片描述
在这里插入图片描述
显然,WTCON地址为0xE270_0000,控制它的Watchdog timer(bit 5),0代表关,1代表开
1.4 代码

#define WTCON	0xE2700000ldr r0, =WTCONldr r1, =0x0str r1, [r0]

2.用汇编设置栈

2.1 C语言运行时需要
——2.1.1为什么要设置栈?
——C语言局部变量在栈存放
——2.1.2单片机、应用程序C程序为什么不需要设置?
——单片机C51有默认栈,C程序在链接时,编译器会自动设置栈

2.2 CPU模式和各种模式下的栈
复位后默认SVC模式,当前CPU刚复位(刚启动),外部的DRRAM尚未初始化,目前可用的内存只有内部的SRAM(因为它不需初始化即可使用)。因此我们只能在SRAM中找一段内存来作为SVC的栈。

2.3 查阅文档并设置栈指针至合法位置
在这里插入图片描述

设置栈(满减栈):
#define SVC_STACK	0xd0037d80
ldr sp, =SVC_STACK

2.4 栈的类型:
在这里插入图片描述

2.5 汇编调用C语言
2.5.1相关代码:

bl led.c //短跳转makefile:
led.bin: start.o led.o //添加led.o//C语言访问寄存器(内存地址)
unsigned int *p = (unsigned int *)0x0xE0200240;
*p = 0x11111111;
上面这两句其实可以简化为1句:*((unsigned int *)0x0xE0200240) = 0x11111111;

2.5.2 start.S

#define WTCON		0xE2700000
#define SVC_STACK	0xd0037d80.global _start					// 把_start链接属性改为外部,这样其他文件就可以看见_start了
_start:// 第1步:关看门狗(向WTCON的bit5写入0即可)ldr r0, =WTCONldr r1, =0x0str r1, [r0]// 第2步:设置SVC栈ldr sp, =SVC_STACK// 从这里之后就可以开始调用C程序了bl led_blink	// led_blink是C语言实现的一个函数// 汇编最后的这个死循环不能丢b .
#define GPJ0CON		0xE0200240
#define GPJ0DAT		0xE0200244
void delay(void);// 该函数要实现led闪烁效果
void led_blink(void)
{// led初始化,也就是把GPJ0CON中设置为输出模式unsigned int *p = (unsigned int *)GPJ0CON;unsigned int *p1 = (unsigned int *)GPJ0DAT;*p = 0x11111111;while (1){// led亮*p1 = ((0<<3) | (0<<4) | (0<<5));// 延时delay();// led灭*p1 = ((1<<3) | (1<<4) | (1<<5));// 延时delay();}
}void delay(void)
{volatile unsigned int i = 900000;		// volatile 让编译器不要优化,这样才能真正的减while (i--);							// 才能消耗时间,实现delay
}

3.开iCache

3.1 什么是cache
从容量来说:CPU < 寄存器 < cache < DDR
从速度来说:CPU > 寄存器 > cache > DDR

3.2 icache的作用
icache存放一些DDR的指令,cpu要执行时直接从icache里面取指令,不需要从DDR里面取,速度快

3.3 cache的操作
1.icache的一切动作都是自动的,不需人为干预。我们所需要做的就是打开/关闭icache。
2. 在210的iROM中BL0已经打开了icache。所以之前看到的现象都是icache打开时的现象。

3.4 用代码开关icache

mrc p15,0,r0,c1,c0,0;			// 读出cp15的c1到r0中
bic r0, r0, #(1<<12)			// bit12 置0  关icache
orr r0, r0, #(1<<12)			// bit12 置1  开icache
mcr p15,0,r0,c1,c0,0;

4.重定位及其代码实战

4.1 位置有关码与位置无关码
.S转变成的.elf,与位置(内存地址)有/无关

4.2 链接地址和运行地址
链接地址:希望程序执行的地址(指定方式为:Makefile中用-Ttext,或者链接脚本)
运行地址:程序执行时的地址(dnw中就是下载地址)

4.3 S5PV210的启动过程
三星推荐:(假设bootloader为80KB)
1.上电
2.BL0初始化
3.BL0程序执行控制BL1(16KB)加载到SRAM中
4.BL1程序执行控制BL2(80KB-16KB),加载到SRAM中
5.BL2程序执行,1.初始化DDR 2.OS加载到DDR

uboot:

1.上电
2.BL0初始化
3.BL0程序执行控制BL1(16KB)加载到SRAM中
4.BL1运行时会初始化DDR,然后将整个uboot搬运到DDR中
5.长跳转(从SRAM跳转到DDR),执行完剩下的uboot,完成启动

4.4 链接地址和运行地址的决定因素
运行地址:编译链接时是无法绝对确定运行时地址的
链接地址:1.Makefile中-Ttext xxx 2.链接脚本

4.5 程序段
先天性段名:
代码段:(.text),又叫文本段,代码段其实就是函数编译后生成的东西
数据段:(.data),数据段就是C语言中有显式初始化为非0的全局变量
bss段:(.bss),又叫ZI(zero initial)段,就是零初始化段,对应C语言中初始化为0的全局变量。
后天性段名:
段名由程序员自己定义,段的属性和特征也由程序员自己定义。

4.6 链接脚本
链接:把编译后的.o文件按照一定规则处理,生成一个.elf

SECTIONS
{. = 0xd0024000;.text : {start.o* (.text)}.data : {* (.data)}bss_start = .; .bss : {* (.bss)}bss_end  = .;	
}

4.7 代码重定位思路

  1. 用链接脚本来确定链接地址(运行位置有关码)
  2. 确定运行地址(执行位置无关码、拷贝、长跳转)

4.8 代码重定位实战

/** 文件名:	led.s	* 作者:	朱老师* 描述:	演示重定位(在SRAM内部重定位)*/#define WTCON		0xE2700000
#define SVC_STACK	0xd0037d80.global _start	// 把_start链接属性改为外部,这样其他文件就可以看见_start了
_start:// 第1步:关看门狗(向WTCON的bit5写入0即可)ldr r0, =WTCONldr r1, =0x0str r1, [r0]// 第2步:设置SVC栈ldr sp, =SVC_STACK// 第3步:开/关icachemrc p15,0,r0,c1,c0,0;			// 读出cp15的c1到r0中//bic r0, r0, #(1<<12)			// bit12 置0  关icacheorr r0, r0, #(1<<12)			// bit12 置1  开icachemcr p15,0,r0,c1,c0,0;// 第4步:重定位// adr指令用于加载_start当前运行地址adr r0, _start  		// adr加载时就叫短加载		// ldr指令用于加载_start的链接地址:0xd0024000ldr r1, =_start // ldr加载时如果目标寄存器是pc就叫长跳转,如果目标寄存器是r1等就叫长加载	// bss段的起始地址ldr r2, =bss_start	// 就是我们重定位代码的结束地址,重定位只需重定位代码段和数据段即可cmp r0, r1			// 比较_start的运行时地址和链接地址是否相等beq clean_bss		// 如果相等说明不需要重定位,所以跳过copy_loop,直接到clean_bss// 如果不相等说明需要重定位,那么直接执行下面的copy_loop进行重定位// 重定位完成后继续执行clean_bss。// 用汇编来实现的一个while循环
copy_loop:ldr r3, [r0], #4    // 源str r3, [r1], #4	// 目的   这两句代码就完成了4个字节内容的拷贝cmp r1, r2			// r1和r2都是用ldr加载的,都是链接地址,所以r1不断+4总能等于r2bne copy_loop// 清bss段,其实就是在链接地址处把bss段全部清零
clean_bss:ldr r0, =bss_start					ldr r1, =bss_endcmp r0, r1				// 如果r0等于r1,说明bss段为空,直接下去beq run_on_dram			// 清除bss完之后的地址mov r2, #0
clear_loop:str r2, [r0], #4		// 先将r2中的值放入r0所指向的内存地址(r0中的值作为内存地址),cmp r0, r1				// 然后r0 = r0 + 4bne clear_looprun_on_dram:	// 长跳转到led_blink开始第二阶段ldr pc, =led_blink				// ldr指令实现长跳转// 从这里之后就可以开始调用C程序了//bl led_blink					// bl指令实现短跳转// 汇编最后的这个死循环不能丢b .

4.8 重定位总结

  1. 大多数代码是位置有关码
  2. 210的BL1执行时固定从0xD002_0010默认开始,假设某些位置有关码需要在0xd0024000运行,所以就需要用一段位置无关码来实现重定位
  3. 设置完重定位之后,PC指针还是在0xD002_0010地址,需要用长跳转指令来让PC在0xd002_4000的链接地址的某位置执行指令。
  4. 重定位思路:1.判断是否需要重定位,2.拷贝 3.判断是否需要清bss段 4.长跳转

1.5.5 SDRAM

1 什么是SDRAM

  1. SDRAM和DDR差不多
  2. SDRAM不等于SRAM,前者需要初始化,后者直接上电运行

在这里插入图片描述
2.SDRAM原理图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:

  1. DRAM0:内存地址范围:0x20000000~0x3FFFFFFF(512MB),对应引脚是Xm1xxxx
    DRAM1: 内存地址范围:0x40000000~0x7FFFFFFF(1024MB),对应引脚是Xm2xxxx
  2. 1.5GB,实际上210只占用了521MB(DRAM0 = DRAM1 = 256MB)
  3. 所以合理地址为:
    DRAM0:内存地址范围:0x20000000~0x2FFFFFFF(256MB)
    DRAM1: 内存地址范围:0x40000000~0x4FFFFFFF(256MB)
    在这里插入图片描述
  4. 每个DDR连接着
    1.地址总线14根
    2.数据总线16根(两片拼接就是32位)
    3 控制线

5.一片DDR有128MB

1片内存8bank
1bank里面有row address(14位) + column address(10位)
1bank = 2^14*2^10 = 2 ^24 = 16MB= 128Mb
8bank(128Mbit * 8)合在一起就是1片内存(128MB)

6.汇编初始化SDRAM

	// 第4步:初始化ddrbl sdram_asm_init //sdram_init.S//sdram_init.S27步初始化SDRAM..
DMC0_MEMCONTROLburst length=41chip,···对应值是0x00202400
DMC0_MEMCONFIG_0DRAM0通道中memory chip0的参数设置寄存器
DMC0_MEMCONFIG_1DRAM0通道中memory chip1的参数设置寄存器
DMC_DIRECTCMD
这个寄存器是个命令寄存器,我们210通过向这个寄存器写值来向DDR芯片发送命令(通过命令总线),这些命令应该都是用来配置DDR芯片工作参数。

总结:

总结:

  1. 三星设定:
    DRAM0 = 256MB+256MB = memory chip0 + memory chip1
    memory chip0:0x20000000到0x2FFFFFFF = 256MB
    memory chip1:0x30000000~0x3FFFFFFF = 256MB

  2. 210只用了chip0,chip0里面由两片128MB内存并联,只算一片

  3. DMC0_MEMCONFIG_0有用,而DMC0_MEMCONFIG_1无用,所以我直接给他了默认值。

这篇关于S5PV210开发1.0.5----重定位relocate与SDRAM的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/484220

相关文章

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1

如何基于Python开发一个微信自动化工具

《如何基于Python开发一个微信自动化工具》在当今数字化办公场景中,自动化工具已成为提升工作效率的利器,本文将深入剖析一个基于Python的微信自动化工具开发全过程,有需要的小伙伴可以了解下... 目录概述功能全景1. 核心功能模块2. 特色功能效果展示1. 主界面概览2. 定时任务配置3. 操作日志演示

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录

一文教你如何解决Python开发总是import出错的问题

《一文教你如何解决Python开发总是import出错的问题》经常朋友碰到Python开发的过程中import包报错的问题,所以本文将和大家介绍一下可编辑安装(EditableInstall)模式,可... 目录摘要1. 可编辑安装(Editable Install)模式到底在解决什么问题?2. 原理3.

Python+PyQt5开发一个Windows电脑启动项管理神器

《Python+PyQt5开发一个Windows电脑启动项管理神器》:本文主要介绍如何使用PyQt5开发一款颜值与功能并存的Windows启动项管理工具,不仅能查看/删除现有启动项,还能智能添加新... 目录开篇:为什么我们需要启动项管理工具功能全景图核心技术解析1. Windows注册表操作2. 启动文件

使用Python开发Markdown兼容公式格式转换工具

《使用Python开发Markdown兼容公式格式转换工具》在技术写作中我们经常遇到公式格式问题,例如MathML无法显示,LaTeX格式错乱等,所以本文我们将使用Python开发Markdown兼容... 目录一、工具背景二、环境配置(Windows 10/11)1. 创建conda环境2. 获取XSLT