正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-8.2-链接脚本

 前言:

本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。

引用:

正点原子IMX6U仓库 (GuangzhouXingyi) - Gitee.com

《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.5.2.pdf》第 8.1 章

《正点原子资料_A盘/02开发板原理图/IMX6ULL_MINI_V2.2(Mini底板原理图).pdf》

正点原子资料下载中心 — 正点原子资料下载中心 1.0.0 文档

 资料盘 开发板资料链接: https://pan.baidu.com/s/1j5Jzbdx9i-g0cWIi3wf2XA 提取码:ag1u

正文:

本文是 “正点原子[第二期]Linux之ARM(MX6U)裸机篇--第8.2讲” 的读书笔记。第8.2 介绍了编译器连接脚本 .lds 文件的语法。并给出了一个例子,如何使用链接脚本来实现我们上一节C语言 LED 驱动程序实验里指定 start.o main.o 的文件链接顺序。

0. 链接脚本简介

在上一节C语言LED灯驱动实验的 Makefile 里,我们链接代码时使用了如下语句

arm-linux-gnueabihf-ld -Ttext 0x87800000 -o led.elf $^

上面语句是通过 "-Ttext" 来指定连接地址是 0x87800000 的,这样的话所有文件都会链接到以0x87800000  为起始地址的区域。但是有时候我们很多文件需要连接到指定的区域,或者叫做段里面,比如在 Linux 里面初始化函数都会放到 .init 段里面。因此我们需要能够自定义一些段,这些段的起始地址我们可以自由指定,同样的我们也可以指定一个文件或者函数应该放在哪个段里面去。要完成这个功能我们就需要使用到链接脚本,看名字就知道链接脚本主要用于链接的,用于描述文件应该如何被链接在一起形成最终可执行文件。其主要目的是描述输入文件中的段如何被映射到输出文件中,并且控制输出文件中的内存排布。比如,我们编译生成的文件一般都包含 .txt 段,.data 段等等。

1. 链接脚本的语法

链接脚本的语法很简单,就是编写一系列的命令,这行命令组成了链接脚本,每个命令是一个带有参数的关键字或者一个对符号的赋值,可以使用分号分隔命令。像文件名之类的字符串可以直接键入,也可以使用通配符“*”。最简单的链接脚本可以值包含一个命令 "SECTIONS",我们可以在这一个 "SECTIONS" 里面描述输出文件的内存布局。我们一般编译出来的代码都包含 .text, .data, .bss, .rodata 这四个段,假设现在代码要被链接到 0x10000000 这个地址,数据要被链接到 0x30000000 这个地方,下面就是完成此功能的最简单的链接脚本:

SECTIONS {. = 0x10000000;.text : { *(.text) }. = 0x30000000;.data ALIGN(4) : { *(.data) }.bss ALIGN(4) : { *(.bss) }
}

第一行写了一个关键字 "SECTIONS" ,后面跟了一个大括号,这个大括号和第七行的大括号是一对,这是必须得。看起来就跟C语言里面的函数一样。

第二行对一个特殊的符号 “.” 进行赋值,“.” 在链接脚本里叫做定位计数器,默认的定位计数器为0。我们要求代码链接到 0x10000000 位起始位置的地方,因此这一行给 “.” 赋值 0x10000000 ,表示以 0x10000000 开始,后面的文件或者段都会以 0x10000000 为起始地址开始链接。

第3行的 ".text" 是段名,后面的冒号是语法要求,冒号后面的大括号里面可以填上要链接到 ".text" 这个段里的所有文件,“*(.text)” 中的 "*" 是通配符,表示所有输入文件的 .text 段都放到 ".text" 中。

第四行,我们的要求是将数据放到 0x30000000 开始的地方,所以我们需要重新设置定位计数器,将其改为 0x30000000。如果不重新设置的话会怎样?假设“.text”段的大小为 0x10000,那么接下来的 .data 段的起始几十就是 0x10000000 + 0x10000 = 0x10010000,者明显不符合我们的要求。所以我们必须调整定位计数器为 0x30000000。

第五行跟第三行一行,定义了一个名字位 ".data" 的段,然后所有文件的 ".data" 段都放到这里面。但是这一行多了一个 "ALIGN(4)" ,这是什么意思呢?这是用来对 .data 这个段的起始地址做字节对齐的,ALGN(4) 表示4字节对齐。也就是说段 ".data" 的起始地址要能被 4 整除,一般常见的都是 ALIGN(4) 或者 ALIGN(8),也就是4字节对齐或者8字节对齐。

第6行定义了一个 “.bss” 段,所有文件中的 ".bss" 数据都会北方这个里面,".ss" 数据就是哪些定义了但是没有被初始化的变量。

上面就是链接脚本最基本的语法格式,我们接下来就按照这个基本的语法格式来编写我们本次 “C语言LED灯驱动程序”实验的链接脚本,我们本次实验的链接脚本要求如下:

  1. 链接起始地址为 0x87800000。
  2. start.o 要被链接到最开始的地方,因为 start.o 里面包含了第一个要执行的命令。

根据要求,在Makefle 同目录下创建一个 "im6ul.lds"的文件,然后在文件里输入如下代码:

SECTIONS {. = 0x87800000;.text : {start.omain.o*(.text)}.rodata ALIGN(4) : { *(.rodata*) }.data   ALIGN(4) : { *(.data) }__bss_start = .;.bss    ALIGN(4) : { *(.bss) *(COMMON) }__bss_end = .;
}

上面的链接脚本,其第2行设置定位计数器为 0x87800000 ,因为我们的链接地址就是 0x87800000。第5行设置链接到开始为止的文件为 start.o ,因为 start.o 里面包含着第一个要执行的指令,所以一定要链接到最开始的地方。第6行时 main.o 这个文件,起始这里可以不用写出来,因为 main.o 的位置就无所谓了,可以有由编译器自行决定链接位置。第11,13 行有 "__bss_start" 和 "__bss_end" 这两个东西?这个是什么呢? "__bss_start" 和 "__bss_end" 是符号,第11, 13 这两行起始就是对这两个符号赋值,其值为定位符号 "." ,这两个符号用来保存 .bss 段的起始地址和结束地址。前面说了 .bss 段是定义了但没有被初始化的变量,我们需要手动对 .bss 段的变量清零的,因此我们需要知道 .bss 段的起始地址和结束地址,这样我们直接对这段内存赋 0 即可完成清零。通过第11,13 行代码,.bss 段的起始地址和结束地址就保存在了 "__bss_start" 和 "__bss_end" 中,我们就可以直接在汇编或者C文件里面使用这两个符号了。

3. 修改Makefile使用 "imx6u.lds" 链接脚本

在上一节我们已经编写好了链接脚本 imx6u.lds ,我们可定是要使用这个链接脚本文件的,将Makifile中的如下一行代码:

arm-linux-gnueabihf-ld -Ttext 0x87800000 $^ -o ledc.elf

修改为:

arm-linux-gnueabihf-ld -Timx6ul.lds -o led.elf $^

其实就是将 “-T” 后面的 0x87800000 修改为 imx6ul.lds,表示使用 imx6ul.lds 这个链接脚本文件。修改完成以后使用新的 Makefile 和 链接脚本文件重新编译功能,编译成功之后就可以烧写到 SD 卡验证了。

链接脚本实验中,容易遇到的 .lds 文件的语法错误(我自己实验遇到的):

  • 在赋值语句的后面,缺失了分号 “;”
  • 在 ".bss" 段名语句中间,缺失了冒号 ":"

在编译的时候,编译器发现 .lds 链接脚本的语法错误就会输出错误提示信息,如下图,需要根据编译器提示的错误信息,修正 .lds 链接脚本文件里的语法错误。

(上面这张图就是我自己在第三行 '. = 0x87800000' 这一行尾缺失了分号";",编译其检查到 链接脚本语法错误,输出的错误提示信息。我们根据错误提示信息的行数修正第三行,加上分号。)

4. 下载验证

使用修改后的 Makefile,通过链接脚本控制文件的链接起始为止为 0x87800000,并且通过链接脚本指定文件的链接顺序,把 start.o 文件链接到最终文件的起始位置 0x87800000 处。

imxdownload ledc.bin /dev/sdb

烧录SD卡后,把SD卡查到正点原子 I.MX6ULL APHA/Mini 开发板上,开发板上电验证LED灯是否闪烁。

我验证的结果是使用链接脚本控制 led.elf 的链接位置和文件链接顺序后,使用正点原子提供的 imxdownlaod 烧写到SD卡中后,开发板LED灯正产闪烁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/319213.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3.9设计模式——Strategy 策略模式(行为型)

意图 定义一系列的算法,把它们一个个封装起来,并且使他们可以相互替换此模式使得算法可以独立于使用它们的客户而变化 结构 Strategy(策略)定义所有支持的算法的公共入口。Context使用这个接口来调用某ConcreteStrategy定义的方…

实验14 MVC

二、实验项目内容&#xff08;实验题目&#xff09; 编写代码&#xff0c;掌握MVC的用法。【参考课本 例1 】 三、源代码以及执行结果截图&#xff1a; example7_1.jsp&#xff1a; <% page contentType"text/html" %> <% page pageEncoding "ut…

【信息收集-基于字典爆破敏感目录--御剑/dirsearch

两个工具都是内置字典来对于目录进行爆破的&#xff0c;这是信息收集的一部分&#xff0c;若能在列举出的目录中找到有价值的信息能为后续渗透做准备。 御剑比较简便 dirsearch需要集成python3.x环境&#xff0c;但是可选的命令更多。两者爆破的结果不一定相同&#xff0c;可以…

怎样建设网站

建设一个网站需要经过一系列的步骤和技术&#xff0c;以下是一个简单的指导&#xff1a; 1. 确定网站目的&#xff1a;首先要确定网站的目的和目标。是为了促销产品&#xff1f;提供信息&#xff1f;还是为了社交交流&#xff1f;确定网站目的可以帮助你更好地规划网站的结构和…

【深度学习】位置编码

一、引言 Self-Attention并行的计算方式未考虑输入特征间的位置关系&#xff0c;这对NLP来说是不可接受的&#xff0c;毕竟一个句子中每个单词都有着明显的顺序关系。Transformer没有RNN、LSTM那样的顺序结构&#xff0c;所以Transformer在提出Self-Attention的同时提出了Posi…

RKNN Toolkit2 工具的使用

RKNN Toolkit2 是由瑞芯微电子 (Rockchip) 开发的一套用于深度学习模型优化和推理的工具。它主要面向在瑞芯微SoC上进行AI应用开发&#xff0c;但也可以用于PC平台进行模型的转换、量化、推理等操作。它支持将多种深度学习框架的模型&#xff08;如Caffe, TensorFlow, PyTorch等…

Linux下软硬链接和动静态库制作详解

目录 前言 软硬链接 概念 软链接的创建 硬链接的创建 软硬链接的本质区别 理解软链接 理解硬链接 小结 动静态库 概念 动静态库的制作 静态库的制作 动态库的制作 前言 本文涉及到inode和地址空间等相关概念&#xff0c;不知道的小伙伴可以先阅读以下两篇文章…

网络安全是智能汽车下一个要卷的方向?

2024年一季度&#xff0c;中国汽车市场延续了2023年的风格&#xff0c;核心就是「卷」。 2023年&#xff0c;我国汽车市场爆发「最强价格战」&#xff0c;燃油车的市场空间不断被挤压&#xff0c;如今只剩下最后一口气。近日乘联会发布4月1-14日最新数据&#xff0c;新能源&am…

【前端】VUE项目创建

在所需文件夹中打开cmd命令行窗口&#xff0c;输入vue ui 进入web可视化界面选择创建新项目 根据需求依次完成下列选择&#xff0c;下列是参考配置&#xff0c;完成后点击创建项目即可 最终显示完成

CUDA和显卡驱动

1.安装显卡驱动 https://www.nvidia.com/download/index.aspx?langen-us 由于我的显卡是RTX4060&#xff0c;因此先选择RTX40系列&#xff0c;然后选择RTX4060&#xff0c;进行安装 2.查看显卡对应的CUDA CUDA安装地址&#xff1a;https://developer.nvidia.com/cuda-toolk…

应用分层和企业规范

目录 一、应用分层 1、介绍 &#xff08;1&#xff09;为什么需要应用分层&#xff1f; &#xff08;2&#xff09;如何分层&#xff1f;&#xff08;三层架构&#xff09; MVC 和 三层架构的区别和联系 高内聚&#xff1a; 低耦合&#xff1a; 2、代码重构 controlle…

【 书生·浦语大模型实战营】学习笔记(六):Lagent AgentLego 智能体应用搭建

&#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料&#xff0c;配有全面而有深度的专栏内容&#xff0c;包括不限于 前沿论文解读、…

相机知识的补充

一&#xff1a;镜头 1.1MP的概念 相机中MP的意思是指百万像素。MP是mega pixel的缩写。mega意为一百万&#xff0c;mega pixel 指意为100万像素。“像素”是相机感光器件上的感光最小单位。就像是光学相机的感光胶片的银粒一样&#xff0c;记忆在数码相机的“胶片”&#xff…

spring boot运行过程中动态加载Controller

1.被加载的jar代码 package com.dl;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class App {public static void main(String[] args) {SpringApplication.run(A…

C++函数模板

简介&#xff1a;C函数模板的作用就是按照程序员的要求生成想要的函数对象。本质上是一种函数声明&#xff0c;在程序运行时依靠指定的参数类型由编译器临时生成函数对象。 1、auto自动类型推导 auto关键字可以取代变量声明时的函数类型&#xff0c;其实实际上会由编译器帮你把…

智能私信神器,转化率飙升的秘密!

在当今信息爆炸的时代&#xff0c;企业和商家面临着巨大的竞争压力&#xff0c;如何有效地吸引潜在客户、提高客户转化率成为摆在每一位市场营销人员面前的难题。随着人工智能技术的不断发展&#xff0c;智能私信软件应运而生&#xff0c;为企业提供了一个高效、便捷的解决方案…

前端发起网络请求的几种常见方式(XMLHttpRequest、FetchApi、jQueryAjax、Axios)

摘要 前端发起网络请求的几种常见方式包括&#xff1a; XMLHttpRequest (XHR)&#xff1a; 这是最传统和最常见的方式之一。它允许客户端与服务器进行异步通信。XHR API 提供了一个在后台发送 HTTP 请求和接收响应的机制&#xff0c;使得页面能够在不刷新的情况下更新部分内容…

HSDB使用教程

HSDB&#xff1a;Hostspot Debugger&#xff0c;JVM内置的工具&#xff0c;用于深入分析JVM运行时的内部状态 启动HSDB java -cp D:/tools/jdk-1.8/lib/sa-jdi.jar sun.jvm.hotspot.HSDB 获取进程id jps 连接到指定进程 查找类 通过查询查找对象 输入查询语句 select d from …

扫雷实现详解【递归展开+首次必展开+标记雷+取消标记雷】

扫雷 一.扫雷设计思路二.扫雷代码逐步实现1.创建游戏菜单2.初始化棋盘3.打印棋盘4.随机布置雷5.统计周围雷的个数6.递归展开棋盘7.标记雷8.删除雷的标记9.保证第一次排雷的安全性棋盘必定展开10.排查雷11.判断输赢 三.扫雷总代码四.截图 一.扫雷设计思路 1.创建游戏菜单。  2.…

Vue入门到关门之Vue项目工程化

一、创建Vue项目 1、安装node环境 官网下载&#xff0c;无脑下一步&#xff0c;注意别放c盘就行 Node.js — Run JavaScript Everywhere (nodejs.org) 需要两个命令 npm---->pipnode—>python 装完检查一下&#xff0c;hello world检测&#xff0c;退出crtlc 2、搭建vu…