本文仅探讨s3c6410从nand flash启动u-boot时的代码重定位过程 参考: 1)<USER'S MANUAL-S3C6410X>第二章 MEMORY MAP 第八章 NAND FLASH CONTROLLER 2)u-boot源码: u-boot-x.x.x/board/samsumg/smdk6410/lowlevel_init.S u-boot-x.x.x/cpu/s3c64xx/start.S u-boot-x.x.x/cpu/s3c64xx/nand_cp.c 代码重定位…
文章目录 一.启动方式 1.1 NAND FLASH 启动 1.2 NOR FLASH 启动 二. 段的概念 2.1 重定位数据段 2.2 加载地址的引出 三.链接脚本 3.1 链接脚本的引入 3.2 链接脚本的正确打开方法 3.3 链接脚本测试 3.4 elf文件 3.5 bin文件 四.重定位 4.1 start.S 重定位数据段 4.2 start.S 清零.bss段 4.3 链接脚本改进 4.4 C语言实现重定位 4.5 C语言实现清零.bss段 4.6 符号表 五.位置无关码(相对跳转…
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). 目录 示例代码 sub.o 文件内容分析 段信息 符号表信息 main.o 文件分析 段信息 符号表信息 绝对寻址 相对寻址 重定位表信息 可执行程序 main 段信息 符号表信息 绝对地址重定位 相对地址重定位 总结 别人的经验,我们的阶梯! 最近因为项目上的需要,利用动态链接库来实现一个插件系…
通过前面的学习,我们知道,把可执行程序从一个位置复制到另一个位置的过程叫做重定位. 现在有两种方式,第一种是只重定位data段到内存(sdram),为什么需要重定位?因为有些flash的写操作,不是简单地内存访问,通常我们使用sdram这个介质作为程序运行的载体.但是只重定位data段这种方式存在弊端.第一,我们的调试工具通常不支持这种分体形式(比如我们的之前的代码在0地址开始存放text和rodata段,而在间隔很远处sdram 0x30000000存放data段,这就是分体的形式)的代码:第…
1.重定位的引入(为什么要代码重定位) 我们知道s3c2440的cpu从0地址开始取指令执行,当从nor启动时,0地址对应nor,nor可以像内存一样读,但不能像内存一样写.我们能够从nor上取指令执行. 例子1:当nand启动的时候,我们nand中的前4K指令会变自动加载到sram中去,这时的0地址对应sram. 那么我们的程序如果大于4K,要从nand启动,sram只拷贝了nand中的前4K代码,那么如何解决这个问题呢? 那么就需要重定位代码到sdram中去,sdram的容量较大,又可以直接…
1.代码重定位的改进 用ldr.str代替ldrb, strb加快代码重定位的速度. 前面重定位时,我们使用的是ldrb命令从的Nor Flash读取1字节数据,再用strb命令将1字节数据写到SDRAM里面. 我们2440开发板的Nor Flash是16位,SDRAM是32位. 假设现在需要复制16byte数据. 不同的读写指令 cpu读取nor的次数 cpu写入sdram的次数 ldrb.strb 16 16 ldr.str 8 4 可以看出我们更换读写指令后读写次数变少了,提升了cpu的访…
代码重定位(2.编程实现代码重定位) 1.引入链接脚本 我们上一节讲述了为什么要重定位代码,那么怎么去重定位代码呢? 上一节我们发现"arm-linux-ld -Ttext 0 -Tdata 0x30000000"这种方式编译出来的bin文件有800多M,这肯定是不行的,那么需要怎么把.data段重定位到sdram呢? 可以通过AT参数指定.data段在编译时的存放位置,我们发现这样指定太不方便了,而且不好确定要放在bin文件的哪个位置.这里就要引入链接脚本,它可以帮我们解决这个不必要…
作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux.嵌入式领域经典书籍. 转 载:欢迎转载文章,转载需注明出处. 目录 程序的结构 1. 程序头(Header)的描述信息 2. 关于汇编地址 bootloader 把程序从硬盘读取到内存 1. 读取到内存中的什么位置? 2. bootloader 设置数据段基地址 3. bootloader 读取所有…
都知道U-BOOT分为两个阶段,第一阶段是(~/cpu/arm920t/start.S中)在FLASH上运行(一般情况 下),完成对硬件的初始化,包括看门狗,中断缓存等,并且负责把代码搬移到SDRAM中(在搬移的时候检查自身代码是否在SDRAM中),然后完成C程序 运行所需要环境的建立,包括堆栈的初始化等,最后执行一句跳转指令: ldr pc, _start_armboot _start_armboot: .word start_armboot, 进入到/lib_arm/board.c中的函数v…
ref: https://blog.csdn.net/dhauwd/article/details/78566668 https://blog.csdn.net/yueqian_scut/article/details/39004727 https://blog.csdn.net/Egean/article/details/84889565 https://www.cnblogs.com/zafu/p/7399859.html 涉及领域:     裸机程序,uboot,Linux kernel…
对于2440而言,nand启动,nand的前4k内容由硬件复制到sram. nor flash,可以像内存一样读,但是不能像内存一样写,执行写操作需要特殊的操作. 程序中包含有需要写的全局或者静态变量,它们在bin文件中,写在nor flash上,直接修改这样的变量是无效的. 到底什么意思呢?还是看例子比较有说服力. 在学习C语言的过程中,我们或多或少知道一些东西,c/c++可执行文件需要预处理,编译,汇编,连接. 程序有text段,data段,bss段,rodata段等等,今天,就和它们来个亲…
在上一章中,将代码重定位到了SRAM中,但是这样的做法作用不大.正确的做法的是将代码重定位到更大的主存中,即DRAM.Tiny6410的DRAM控制寄存器最多只能支持两个同一类型的芯片.每个芯片最多可分配256MB的地址空间,所有的芯片在相同的端口共享所有的引脚,除了时钟启动信号和片选信号. 通过原理图 DRAM的地址为0x50000000 通过原理图可知SDRAM的使用的是K4X1G163PE-L(F)E/GC6.通过查看该芯片的数据手册可知道,如何启动SDRAM控制寄存器. SDRAM  初…
一.重定位 1.以前版本的重定位 2.新版本 我们的程序不只涉及一个变量和函数,我们若想访问程序里面的地址,则必须使用SDRAM处的新地址,即我们的程序里面的变量和函数必须修改地址.我们要修改地址,则必须知道程序的地址,就需要在链接的时候加上PIE选项: 加上PIE选项后,链接时候的地址就会生成,然后存储在段里面,如下段(u-boot.lds): 然后我们根据这些地址的信息来修改代码,程序就可以复制到SDRAM的任何地方去. 二.代码流程 start.S中执行到了 bl _main,跳转到_ma…
本文转载自:http://blog.csdn.net/eshing/article/details/37116637 一.关于DRAM 上一章我们讲解了如何对代码进行重定位,但是将代码重定位到只有256K IRAM中作用不大. 正确的做法是将代码重定位到容量更大的主存中,即DRAM.Exynos4412中有两个独立的DRAM控制器,分别叫DMC0和DMC1.DMC0和DMC1分别支持最大1.5G的DRAM,它们都支持DDR2/DDR3和LPDDR2等,512 Mb, 1 Gb, 2 Gb, 4…
本文转载自:http://blog.csdn.net/eshing/article/details/37115697 一.重定向 对于程序而言,我们需要理解两个概念,一是程序当前所处的地址,即程序在运行时,所处的当前地址:二是程序的链接地址,即程序运行时应该位于的运行地址.编译程序时,可以指定程序的链接地址.对于Tiny4412而言,启动时只会从MMC/sd等启动设备中拷贝前16K的代码到IRAM中,那么当我们的程序超过16K怎么办?那就需要我们在前16K的代码中将整个程序完完整整地拷贝到DRA…
目录 引入 环境配置 编译体验 入口查找 代码分析 board_init_f pie 内存分布分析 SP设置 board_init_f 重定位 代码段重定位实现 变量地址修改 参考 title: uboot2012(一)分析重定位 date: 2019/02/23 21:53:21 toc: true --- 引入 关于移植,搜索关键英文词语portting 移植简单的介绍在readme中,手册是它的使用帮助 代码仓库地址 02-uboot重定位加入自己的代码 环境配置 这里使用编译工具arm-…
第16-17章 - 基址重定位表&.reloc节区 @date: 2016/11/31 @author: dlive 0x00 前言 这几天忙着挖邮箱漏洞,吃火锅,马上要被关禁闭,看书进度比较慢... 0x01 PE重定位 若加载的是DLL.SYS文件,且在ImageBase位置处已经加载了其他DLL/SYS文件,那么PE装载器就会将其加载到其他未被占用的空间.这就涉及了PE文件重定位问题,PE重定位是指PE文件无法加载到ImageBase位置,而被加载到其他地址时发生的一系列处理行为. 开发工…
今天有一个朋友发短消息问我说“老师,为什么PE的格式要讲的这么这么细,这可不是一般的系哦”.其实之所以将PE结构放在解密系列继基础篇之后讲并且尽可能细致的讲,不是因为小甲鱼没事找事做,主要原因是因为PE结构非常重要,再说做这个课件的确是很费神的事哈.在这里再次强调一下,只要是windows操作程序,其就要遵循PE格式,再说人家看雪的网址就是www.pediy.com. 简单的讲是可以,但是怕就怕有些朋友知识点遗漏了或者错误理解意思.不能深刻体会等,这样的效果是不好的~所以,小甲鱼尽管这系列视频可…
1 平台 转http://blog.csdn.net/misskissc/article/details/43063419 1.1 硬件 Table 1. 硬件(lscpu) Architecture: i686(Intel 80386) Byte Order: Little Endian 1.2 操作系统 Table 2. 操作系统类型 操作系统(cat /proc/version) 位数(uname -a) Linux version 3.2.0-4-686-pae i686(32bit)…
什么是重定位: 重定位就是你本来这个程序理论上要占据这个地址,但是由于某种原因,这个地址现在不能让你占用,你必须转移到别的地址,这就需要基址重定位.你可能会问,不是说过每个进程都有自己独立的虚拟地址空间吗?既然都是自己的,怎么会被占据呢?对于EXE应用程序来说,是这样的.但是动态链接库就不一样了,我们说过动态链接库都是寄居在别的应用程序的空间的,所以出现要载入的基地址被应用程序占据了或者被其它的DLL占据了,也是很正常的,这时它就不得不进行重定位了. 哪些数据需要重定位: :00401000 5…
作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解答,望见谅如有关于该系列教程的疑问建议联系论坛的原作者ID:Tangerine 0x00 got表.plt表与延迟绑定 在之前的章节中,我们无数次提到过got表和plt表这两个结构.这两个表有什么不同?为什么调用函数要经过这两个表?ret2dl-resolve与这些内容又有什么关系呢?本节我们将通过…
0x01  重定位表结构   重定位表是由数据目录表中的第六个成员指出的: typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;  程序编译时每个模块有一个优先加载地址ImageBase,这个值是链接器给出的,因此链接器生成的指令中的地址是在假设模块被加载到ImageBase前提之下生成的,那么一旦程序没有将模…
ARM ELF的函数重定位与x86是一致的,但由于汇编指令不同,再鼓捣一遍. 示例代码: #include <stdio.h> #include <stdlib.h> int main () { puts ("Hello world"); sleep (1); FILE *fp = fopen ("1.c", "r"); fclose (fp); exit (0); } 通过 readelf -r 可以查看ELF中所有需要…
第16-17章 - 基址重定位表&.reloc节区 @date: 2016/11/31 @author: dlive 0x01 PE重定位 若加载的是DLL.SYS文件,且在ImageBase位置处已经加载了其他DLL/SYS文件,那么PE装载器就会将其加载到其他未被占用的空间.这就涉及了PE文件重定位问题,PE重定位是指PE文件无法加载到ImageBase位置,而被加载到其他地址时发生的一系列处理行为. 开发工具 PE 地址 SDK/Visual C++ EXE 00400000 SDK/Vi…
第六章 栈与重定位表 本章主要介绍栈和代码重定位.站和重定位表两者并没有必然的联系,但都和代码有关.栈描述的是代码运行过程中,操作系统为调度程序之间相互调用关系,或临时存放操作数而设置的一种数据结构.重定位表则是在一个PE中的代码被加载到任意一个内存地址时,用来描述相关操作数地址变化规律的数据结构.通过重定位技术,代码运行在内存中的任意位置时,可以避免因操作数的定位错误而导致失败. 6.1栈 前面基本概念直接过... 程序在运行的时候会为系统分配一块内存区域作为栈,由栈选择子SS和栈定指针(es…
百篇博客系列篇.本篇为: v55.xx 鸿蒙内核源码分析(重定位篇) | 与国际接轨的对外部发言人 | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应用程序入口并不是main | 51.c.h.o v53.xx 鸿蒙内核源码分析(ELF解析篇) | 你要忘了她姐俩你就不是银 | 51.c.h.o v54.xx 鸿蒙内核源码分析(静态链接篇) | 完整小项目看透静态链接过程 | 51.c.h.o v55.xx 鸿蒙内核源码分析(重定位篇) | 与国际接…
重定位代码 两个不同的地址概念: 对于程序而言,需要理解两个地址,一个是程序当前所处的地址,即程序运行时所处的当前地址.二是程序应该位于的运行地址,即编译程序时所指定的程序的链接地址.在Tiny6410中板子上电启动时只会从NAND Flash/MMC等启动设备中拷贝前8K的代码到SRAM中,然后跳转到SRAM中运行代码.那么问题就来了,如果我们的程序超过8K会出现什么问题呢?程序拷贝不完整运行当然出错.所以就需要我们在前8K的代码中实现将整个程序完整的拷贝到DRAM等其他更大的存储空间,然后在…
概述 重定位(relocate)代码将BootLoader自身由Flash复制到SDRAM,以便跳转到SDRAM执行.之所以需要进行重定位是因为在Flash中执行速度比较慢,而系统复位后总是从0x00000000地址取指. 重定位代码,位于/U-Boot/cpu/s3c44b0/start.S : relocate: adr r0, _start ldr r1, _TEXT_BASE cmp     r0, r1 beq     stack_setup ldr r2, _armboot_star…
PE加载的过程 任何一个EXE程序会被分配4GB的内存空间,用户层处理低2G的内存,驱动处理高2G的内存. 1.双击EXE程序,操作系统开辟一个4GB的空间. 2.从ImageBase决定了加载后的基址,ImageSize决定了程序有多大. 3.然后加载DLL 大体流程: 1.PE被执行时,装载器为进程分配虚拟地址空间,在此情况下,并不是把完整的PE文件载入到磁盘中,而是做一个简单的内存映射. 2.PE装载器在内核中创建进程对象和主进程对象以及其他的内容. 3.PE装载器搜索输入表,装载应用程序…
来看一下搬移部分和重定位部分的代码: relocate: /* 把U-BOOT重新定位到RAM*/          //r0=0; adr r0, _start /* r0是代码的当前位置*/ ldr r1, _TEXT_BASE /*测试判断是从FLASH启动,还是RAM  *///r1=TEXT_BASE = 0x33F80000 cmp     r0, r1     /*比较R0.R1,调试的时候不需要重定位. */ //如果当前的位置就是0x33F80000,既然uboot能够正常执行…