0 说明

本文主要说明在裸机和linux启动中链接地址和运行地址的关系,但是这俩哥们的关系和位置无关码以及MMU有所牵扯,所以放到一起进行说明。

以下针对imx6ull处理器平台

1、imx6u的Memory Maps

首先确定一下物理内存的开始地址,不同处理器DDR或者RAM的基地值是不一样的。这个需要根据平台的参考手册查找,对于imx6ul,在数据手册Memory Maps一章,有如下图:

也就是说,CPU中的0x8000000地址对应物理内存的起始位置。而并不简单的是0地址对应物理内存的0地址。

因此我们写一个裸机程序的时候,指定运行地址的时候,一般是0x80008000(uboot),这里0x80008000指的是处理器中的地址,对应到DDR,也就是偏移为0x8000位置处。

2、链接地址

这个地址是在程序构建到链接阶段的时候确定下来的。

2.1 链接地址的两种设置方式

  • -Ttext 0x80002000
  • 链接脚本

2.2 链接后的影响

链接后,查看反汇编可以参考,代码段开始时候的地址正是指定的链接地址。

3、运行地址

运行地址是和pc指针(r15寄存器)有关的地址。

举例1:uboot加载裸机并跳转执行

uboot中通过tftp将程序加载到内存0x80002000处,然后通过go 0x80002000,开始执行。这个时候0x80002000就是运行地址。

=> tftp 0x80002000 boot.bin;go 0x80002000
TFTP from server 192.168.1.108; our IP address is 192.168.1.187
Filename 'boot.bin'.
Load address: 0x80002000
Loading: #######################################################################2 MiB/s
done
Bytes transferred = 1040520 (fe088 hex)
## Starting application at 0x80002000 ...
****************************************************
************* IMX6UL Bootloader RUN ****************
****************************************************1.Init io/clock/uart/usdhc/irq... success2.Start Copy kerner and dtb to ddr2.1 Mount fatfs [ SUCCESS ]2.3 Open zImage file [ SUCCESS ]2.4 Open dtb file [ SUCCESS ]2.5 Read kernel file to ENTRY ADDR:0x80800000[ SUCCESS ]2.6 Read dtb file to 0x83000000[ SUCCESS ]3.Starting kernel ...Booting Linux on physical CPU 0x0
Linux version 4.1.15-g696dd24-dirty (root@xxzh) (gcc version 6.2.1 20161016 (Linaro GCC 6.2-2016.11) ) #68 SMP PREEMPT Thu Aug 11 09:45:05 CST 2022
CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine model: Freescale i.MX6 ULL 14x14 EVK Board
Reserved memory: created CMA memory pool at 0x8c000000, size 320 MiB
Reserved memory: initialized node linux,cma, compatible id shared-dma-pool
Memory policy: Data cache writealloc
PERCPU: Embedded 12 pages/cpu @8bb33000 s16908 r8192 d24052 u49152
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 130048
Kernel command line: console=ttymxc3,115200 imx2-wdt.timeout=120 root=/dev/mmcblk1p2 rootwait rw
PID hash table entries: 2048 (order: 1, 8192 bytes)
Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
Memory: 180876K/524288K available (6847K kernel code, 377K rwdata, 2316K rodata, 400K init, 422K bss, 15732K reserved, 327680K cma-reserved, 0K highmem)
Virtual kernel memory layout:vector  : 0xffff0000 - 0xffff1000   (   4 kB)fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)vmalloc : 0xa0800000 - 0xff000000   (1512 MB)lowmem  : 0x80000000 - 0xa0000000   ( 512 MB)pkmap   : 0x7fe00000 - 0x80000000   (   2 MB)modules : 0x7f000000 - 0x7fe00000   (  14 MB).text : 0x80008000 - 0x808fb110   (9165 kB).init : 0x808fc000 - 0x80960000   ( 400 kB).data : 0x80960000 - 0x809be598   ( 378 kB).bss : 0x809c1000 - 0x80a2a948   ( 423 kB)

举例2:mkimage指定可执行程序开始运行的地址

imx6ul在裸机编译产生bin文件后,可以通过如下命令产生imx文件,增加一个头部,bootrom会根据头部中的信息,把可执行程序放到0x80002000,在这个地址开始运行,这个地址就是运行地址。

./tools/mkimage -n ./tools/imximage.cfg.cfgtmp -T imximage -e 0x80002000 -d $(TARGET).bin $(TARGET).imx

链接地址和运行地址的区别

链接地址=运行地址

程序中有函数调用,有全局变量,指定链接地址后,每一个数据都被安排好地址了。程序运行的时候, 可以找到对应的资源,上面的例子中,程序的链接地址和运行地址一样,所以运行不会有问题。

链接地址≠运行地址

链接指定了0x80002000地址,但是uboot中不是go 0x80002000,那么可以运行吗,也许可以,需要看程序是不是位置无关码,如果是那么就可以正常运行,因为位置无关码下,链接地址将不会有影响。

但是一个程序完全实现位置无关太难了,但是这俩地址又无法做到相同,那怎么办呢,那就是重定位,程序开始的时候运行位置无关码,通过前期位置无关码,把程序拷贝到链接地址处开始运行。

位置无关码

这里不做太多说明,代码执行的时候使用相对地址调转,所以链接地址不会影响。

重定位

链接地址≠运行地址的时候,可以通过重定位,在代码开始使用位置无关码将程序拷贝到正确的链接地址去,所以重定位用在链接地址≠运行地址的场景下。

MMU对链接、运行地址的影响

这里主要是在linux引导时候会产生的情况。对于arm32平台,用户空间一般是3G/1G内核空间。因此内核的链接地址一般是0xc0008000。也就大于了0xc0000000。

但是程序加载ddr的时候并不一定会被加载到0xc0008000,正如开始的时候说的imx6ul是从0x80000000开始,如果ddr只有512M,那么不可能把内核直接放到0xc0008000处。

不过,对于imx6ul的内核空间一般是2G,也就可以以0x80008000作为链接地址,可以使得运行地址和链接地址一致。

对于别的平台,可以在开启MMU之前,临时页表创建的时候,将内核链接地址和实际的物理地址映射起来。

开启MMU前,位置无关码,链接地址≠运行地址,开启后链接地址=运行地址。

imx6ul链接地址、运行地址、加载地址、位置无关、mmu的关系相关推荐

  1. 链接脚本使用AT加载地址的总结

    (一)如果不使用AT这个选项,比如下边这个连接脚本 此时在bin文件里的位置就是烧写到某个地址(比如0地址),然后顺着往下排,具体在文件哪个地址不确定.但在ELF文件里,它的地址信息是从0x30000 ...

  2. linux 内核入口地址,linux内核的加载地址和入口地址

    编译完内核之后,会产生zImage,而把它直接导入0x30008000,会出现Bad Magic Number. 查明是需要将内核加一个0x40大小的头,由mkimage工具来添加.mkimage在编 ...

  3. 运行地址与加载地址估计大部分人没弄明白~

    本文为[单片机步入嵌入式Linux]系列文章的第二篇,主要是跟大家讲解一下链接过程中几个地址的区分与理解~ 1 单片机存储分配 在玩单片机(以stm32为例)的时候会有RAM空间和ROM空间,RAM空 ...

  4. 从单片机步入Linux之运行地址与加载地址

    大家好,我是情报小哥! 本文为[单片机步入嵌入式Linux]系列文章的第二篇,主要是跟大家讲解一下链接过程中几个地址的区分与理解~ 01 单片机存储分配 查看全文 http://www.taodudu ...

  5. mPaas之如何查找离线包的在线加载地址

    NAMApp *app = [NAMServiceGet() findApp:@"20200100"version:nil]; 返回数据中 _fallback_host 拼上 _m ...

  6. Kernel32加载地址查找的基本方法

    搜索内存中的API有许多方法,主要的是要找到KERNEL32.DLL的加载地址,常用的基本方法也就几种. 1.暴力搜索KERNEL32.DLL,同时需要处理内存访问异常 2.通过线程初始化时压入堆栈的 ...

  7. java 浏览器访问图片不显示_[Java教程]重新上传图片后 地址不变 浏览器加载不到的问题...

    [Java教程]重新上传图片后 地址不变 浏览器加载不到的问题 0 2016-05-27 07:00:50 做项目的时候遇到一个问题: 上传文件以后,相同的地址,第一次加载没有问题,当你操作次数过快, ...

  8. 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集...

    其调用的方法是从sqlite数据库中获取原来已经使用过的数据库连接,当时也没注意,就是准备设断点然后单步调试,结果竟然是断点无法进入方法体内,后来仔细看了一下方法体的时候发现了一个问题,就是现有的Sy ...

  9. 混合模式程序集是针对“v1.1.4322”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。

    看到一个kinect大牛编写的一个水果忍者的体感游戏版本,让我为自己一直以来只用现有的网页游戏来模拟kinect体感游戏控制感到惭愧,没办法,我还是菜鸟.学习一段后自己模仿星际大战这个游戏,自己写了一 ...

  10. Linux系统程序运行时加载动态库路径顺序

    程序运行时加载动态库路径顺序(Linux) 在linux系统中,如果程序需要加载动态库,它会按照一定的顺序(优先级)去查找: 链接时路径(Link-time path)和运行时路径(Run-time ...

最新文章

  1. 【旧文章搬运】Win7可变对象头结构之InfoMask解析
  2. micropython文件上传软件_ESP32玩转MicroPython(二) 连接WIFI网络 webperl文件传输
  3. 696. Count Binary Substrings 计数二进制子串
  4. (0.2)HarmonyOS鸿蒙开发工具DevEco Studio工程文件目录结构
  5. 完全相同的4个小矩形如图所示放置_吸睛!矩形在PPT中的创意表现
  6. TreeView递归系统目录
  7. 一步步实现SDDC-vSphere Auto Deploy的妙用
  8. idea module取得是parent的文件路径_React(或使用TS)中样式混乱解决方案 *.module.less...
  9. 【有内鬼,终止交易】风靡朋友圈的壁纸,实现代码竟如此简单 | 原力计划
  10. 今天,Google 在中国终于光明正大地搞 AI 了!
  11. Android进程框架:线程通信的桥梁Handler
  12. Union和Union All ,
  13. matlab求多元极大似然估计,matlab求极大似然估计
  14. linux宝塔面板是什么,宝塔面板是什么
  15. [6.15] 心态 信念
  16. vue alert内含有html,vue一步步实现alert功能
  17. Restful API 生成复杂Json数据结构及使用客户端解析该数据结构(三)
  18. 统计输入数据的个数、求和、平均值、方差、中位数
  19. python数据库管理实例_Python之路【第八篇】:堡垒机实例以及数据库操作
  20. 12枚硬币中取1枚假币的问题

热门文章

  1. 玩转 ArrayFire:07 数组和矩阵操作
  2. INA219与INA216测试总结
  3. java连接as400数据库,连接到AS400 DB2服务器JDBC时出错
  4. 【去广告版】P2P终结者4.2最高权限
  5. Tecplot单位转换(开尔文K转摄氏度℃)
  6. 学Python该看什么书?12本精华好书推荐!
  7. android九宫格点击打开功能,Android Studio 实现九宫格功能
  8. LeakCanary 原理分析
  9. IAR9.2及以上版本编辑器主题设置配色方案
  10. cad字体安装_免费的CAD字体去哪找?下载之后如何安装?1分钟教你搞定