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

2023-11-03

目录

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	0xE2700000
	ldr r0, =WTCON
	ldr r1, =0x0
	str 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, =WTCON
	ldr r1, =0x0
	str 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, =WTCON
	ldr r1, =0x0
	str r1, [r0]
	
	// 第2步:设置SVC栈
	ldr sp, =SVC_STACK
	
	// 第3步:开/关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步:重定位
	// adr指令用于加载_start当前运行地址
	adr r0, _start  		// adr加载时就叫短加载		
	// ldr指令用于加载_start的链接地址:0xd0024000
	ldr 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总能等于r2
	bne copy_loop

	// 清bss段,其实就是在链接地址处把bss段全部清零
clean_bss:
	ldr r0, =bss_start					
	ldr r1, =bss_end
	cmp 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 + 4
	bne clear_loop

run_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步:初始化ddr
	bl sdram_asm_init //sdram_init.S
	
 //sdram_init.S
 27步初始化SDRAM
 .
 .
DMC0_MEMCONTROL
	burst length=41chip,···对应值是0x00202400
DMC0_MEMCONFIG_0
	DRAM0通道中memory chip0的参数设置寄存器
DMC0_MEMCONFIG_1
	DRAM0通道中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无用,所以我直接给他了默认值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

S5PV210开发1.0.5----重定位relocate与SDRAM 的相关文章

  • 如何在R语言中找到统计值最小所在的分组

    如何在R语言中找到统计值最小所在的分组 介绍 在数据分析和统计中 我们经常需要找到某个统计值在不同分组中的最小值所在的组别 在R语言中 我们可以使用一些函数和技巧来实现这个目标 本文将介绍如何使用R语言找到统计值最小所在的分组 并提供相应的
  • 算法讲解:二分图匹配【图论】

    二分图匹配 自然要先从定义入手 那么二分图是什么呢 二分图 二分图又称作二部图 是图论中的一种特殊模型 设G V E 是一个无向图 如果顶点V可分割为两个互不相交的子集 A B 并且图中的每条边 i j 所关联的两个顶点i和j分别属于这两个
  • 前端工程师必须收藏的 JavaScript 资源大全

    我想很多程序员应该记得 GitHub 上有一个 Awesome XXX 系列的资源整理 awesome javascript 是 sorrycc 发起维护的 JS 资源列表 内容包括 包管理器 加载器 测试框架 运行器 QA MVC框架和库
  • Go语言的JSON 库

    1 Go语言的JSON 库 Go语言自带的JSON转换库为 encoding json 1 1 其中把对象转换为JSON的方法 函数 为 json Marshal 其函数原型如下 func Marshal v interface byte
  • innodb的锁

    一致性锁定读和一致性非锁定读 Read Committed和Repetable Read级别下采用MVCC 实现非锁定读 但在一些情况下 要使用加锁来保障数据的逻辑一致性 自增列 锁的算法 唯一值 MySQL 中关于gap lock nex
  • qt delegate 委托 多级联动 小结

    最近使用qt写程序用到了treewidget和tablewidget 涉及到编辑默认情况下可以设置treewidget和tablewidget的item可编辑属性来进行编辑 默认情况只是简单的文本输入格式 在qt的demo中看到了spin
  • ES6详解(持续更)

    前言 之前对ES6也有过学习使用 但是都没有深入系统去看看文档书籍 这里开始对一些ES6语法进行整理总结 本文基于阮一峰ES6入门 线上地址 阮一峰ES6入门 let和const命令 1 let命令 如果使用let 声明的变量仅在块级作用域
  • android之adb connect手机设备

    adb手机连接是Android开发过程中常用的 也可以通过无线wifi来连接手机 但是百度搜索了一大堆资料都不全面 而且认知还不全面 导致浪费生命 有时候浪费个人的时间反而更加惹人恶心 window10电脑adb环境搭建 错误提示 adb
  • 人工智能入门学习笔记(一)

    家人们 好久不见哈 最近在尝试着学习人工智能的相关知识和具体技能呀 说实话 当像我这样的 小白初探人工智能体系时 总是被很多未知的名词以及茫茫内容所淹没 便去想通过网络学习帮助自己建立正确的人工智能基本概念认知 在此 我便进一步对人工智能体
  • Token的验证流程以及用法

    一 身份验证流程 1 用户向服务器发送用户名和密码 2 服务端收到请求 去验证用户名与密码 3 验证成功后 服务端会签发一个 Token 将这个 Token 发送给客户端 4 客户端收到 Token 以后可以把它存储起来 放在 Cookie
  • java多线程-Thead线程学习记录笔记

    介绍的内容 主要介绍多线程的基本概念到后面的基本使用 以及一些稍微的原理猜测 个人笔记 不喜勿喷 目录 目录 一 线程使用 1 1 概念 1 2 线程生命周期 1 3 java中实现的方式 1 3 1 继承线程 Thread 1 3 2 实
  • 干货|采用Istio实现灰度发布(金丝雀发布)

    点击上方 中兴开发者社区 关注我们 每天读一篇一线开发者原创好文 灰度发布 又名金丝雀发布 介绍 当应用上线以后 运维面临的一大挑战是如何能够在不影响已上线业务的情况下进行升级 做过产品的同学都清楚 不管在发布前做过多么完备的自动化和人工测
  • unity之shader学习笔记(四)--高光反射

    但是我们会发现物体的背光面是个全黑的颜色 现实生活中物体的背光面并不是全黑的 而是可以看到物体的大概形状 并不是全黑的 之前使用的计算方式是兰伯特光照模型 要实现此种现象 那么就需要使用半兰伯特光照模型来实现 半兰伯特光照模型 Diffus
  • unity鼠标键盘交互

    鼠标交互之鼠标拖动物体 将代码放置在被拖动的物体上 public Camera mainCamera 相机悬挂 private void OnMouseDrag 拖动物体的碰撞体 Ray r mainCamera ScreenPointTo

随机推荐

  • 我在唯品会工作了四年_苦等两年,唯品会消金牌照终于批了,金融业务却“掉队”了...

    图片来源 视觉中国 记者 邹璐徽 界面新闻发现 唯品金融APP即将停用 早前的 唯品宝 唯多利 等金融理财产品也已消失 9月30日 银保监官网发布关于筹建四川省唯品富邦消费金融有限公司的批复 同意在四川省成都市筹建四川省唯品富邦消费金融有限
  • 同时修改多条数据

    想必大家对于可以同时编辑多条数据的事件并不陌生吧 下面我来给大家分享一下可以同时修改多条数据的方法 首先我们看一下我们要处理的是 一个菜品的厨打方案 我们的目的是将批处理方案 也就是同时修改多条数据 也就是把图片中的厨打厨打到区域厨打方案都
  • Hive 核心原理(hive-3.1.2)(转载)

    一 Hive 概述 1 1 Hive 是什么 由Facebook开源用于解决海量结构化日志的数据统计 基于Hadoop的一个数据仓库工具 可以将结构化的数据文件映射成一张表 并且提供类SQL的查询功能 Hive仅仅是一个工具 本身不存储数据
  • Linux系统重新生成boot,在fedora 28中重新生成/boot/grub2/grub.cfg,解决grub问题

    在电脑里安装了windows 7和fedora 28做双系统 现在需要删除掉其中的windows 7系统 在格式化硬盘后 还需要更新grub2的启动选项 删除grub启动界面原来的windows 7选项 以下为方法 grub硬盘启动选项是由
  • Modbus TCP读取寄存器数据

    modbus4j读取寄存器数据 ModbusReadUtil读取工具类 package cn sync modbus import org apache log4j Logger import com serotonin modbus4j
  • OS 关于信号量处理中的忙等待问题

    直接看图 下面这张图堪称神奇 问题描述 gt 套娃行为 信号量为了时临界区问题不发生忙等待 使用临界区mutex进行处理 临界区mutux的value需要被P1和P2的wait 指令进行操作 然而能否保证对mutex value进行互斥的操
  • python语法--面向对象基础(19)

    1 初识面向对象 1 1 面向过程 面向过程 根据业务逻辑从上到下写代码 开发过程的思路是将数据与函数按照执行的逻辑顺序组织在一起 数据与函数分开考虑 面向过程基本是由函数组成的 特点 注重步骤与过程 不注重职责分工 如果需求复杂 代码会变
  • Linux系统信息与系统资源

    目录 系统信息 系统标识uname sysinfo 函数 gethostname 函数 sysconf 函数 时间 日期 GMT 时间 UTC 时间 UTC 时间格式 时区 实时时钟RTC 获取时间time gettimeofday 时间转
  • 使用若以系统vue3兼容ie

    兼容IE 太坑了 下载插件 npm install save babel polyfill或者npm i babel polyfill npm i es6 promise或者 npm install es6 promise save dev
  • VRRP简介与配置

    一 VRRP介绍 1 VRRP作用 VRRP协议中文名称虚拟路由冗余协议 应用在路由器上 其作用是某一路由器损坏或链路出现问题立刻切换到另一个路由器上不影响整个网络的运行 更好的保障网络通信 2 VRRP实现原理 VRRP的原理 就是将多个
  • Go语言面试题--进阶提升(1)

    文章目录 1 下面的代码输出什么 2 下面哪一行代码会 panic 请说明原因 3 下面哪一行代码会 panic 请说明原因 4 下面的代码有什么问题 1 下面的代码输出什么 type N int func n N test fmt Pri
  • 奥的斯电梯服务器不显示菜单,奥的斯电梯调试服务器按键介绍.doc

    奥的斯电梯调试服务器按键介绍 doc 由会员分享 可在线阅读 更多相关 奥的斯电梯调试服务器按键介绍 doc 2页珍藏版 请在文库网上搜索 1 奥的斯电梯调试服务器 俗称ST 按键介绍 奥的斯电梯调试服务器 俗称ST 按键介绍 ST的前面板
  • 高阶函数 /内联函数/高阶函数中使用内联函数/闭包函数/内置高阶函数( let、also、with、run、apply )

    一 高阶函数 高阶函数的定义 高阶函数是指将一个函数作为另一个函数的参数或者将一个函数作为另一个函数的返回值 与java不同的是 在Kotlin中增加了一个函数类型的概念 如果我们将这种函数添加到另一个函数的参数声明或返回值声明当中 那么这
  • Mac及Xcode使用相关问题记录

    1 连接samba服务器 方法 finder gt 前往 gt 连接服务器 输入服务器地址smb 169 254 43 44 连接即可 2 xcode设置快捷键 xcode gt Prefrences gt Key Bindings 修改如
  • 程序中有游离的‘\240’ ‘\302’问题的解决方法

    错误 程序中有游离的 240 302 sed i s o240 o302 g test c
  • oracle问题排查

    目录 问题1 ORA 01017 invalid username password logon denied 问题2 链接普通用户报错ORA 01034 ORACLE not available 问题1 ORA 01017 invalid
  • 独自封装windows 10系统详细教程(一)

    目录 作者语录 一 封装前准备工具 二 安装Windows系统 1 创建虚拟机环境 2 更改BIOS启动顺序 3 安装windows系统 作者语录 这篇文章从无到有 从小白到会轻轻松松的事 超级详细的过程 方面你们操作实践 对你们有用的给我
  • 【C/C++】输出格式%d、%6d、%06d、%-6d、%.6f的区分

    C C 输出格式 d 6d 06d 6d 6f的区分 文章目录 C C 输出格式 d 6d 06d 6d 6f的区分 1 d 普通的整数输出 2 6d 整数输出 宽度是6位 不足左边补空格 3 06d 整数输出 宽度是6位 不足左边补数字0
  • Linux的命令——“cd”(内附Linux命令格式,相对路径和绝对路径)

    内容预知 目录 1 Linux的 命令格式书写 1 2 选项的用法 1 3 参数 2 绝对路径与相对路径 3 对终端中默认 root localhost 的认识 4 七种文件类型 5 命令cd 总结 1 Linux的 命令格式书写 1 1
  • 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的内