如何为SoC做ARM CPU适配——以裸核使用malloc为例

本文任务:为陌生的SoC平台编写基础软件,适配 malloc() 函数

0 如何为SoC做ARM CPU适配

今时不同往日,我们平时开发/娱乐接触到的消费级MCU/MPU基本山都是包含处理核与一系列外设的SoC。如果熟悉裸片开发,一定会在厂家提供的标准库或者SDK包里找到命名类似 startup.s 的汇编文件;如果熟悉 Linux 移植,则不难联想到 arch/arm/kernel 或者 arch/arm/boot 目录下也有类似的文件。

1 Start.s 是什么

startup.s 文件是引导程序的入口点,通常包含引导加载程序需要执行的初始化代码。这些代码负责设置堆栈、加载内核映像到内存中以及跳转到内核入口点。该文件中常见的内容包括:

  • 中断向量和异常处理程序(interrupt handlers):操作系统需要处理各种中断和异常情况,startup.s 文件通常包含中断向量表的定义和异常处理程序的初始化代码。它会设置和配置中断控制器,并将中断向量指向相应的处理函数。

  • 硬件初始化(init):startup.s 文件可能包含对硬件设备的初始化代码,例如启动时钟、初始化串口、启用内存管理单元(MMU)等。这些代码为操作系统提供了基本的硬件支持。

  • 运行环境设置(config):startup.s 文件可能包含设置运行环境所需的代码。例如,它可以设置执行状态,如处理器模式、特权级别等。还可能设置全局变量或数据结构来存储关键的运行时信息。

  • 内核入口点(entry point):最后,startup.s 文件通常将控制权传递给内核的入口函数。这个内核入口点是操作系统初始化的起点,它接收传递的参数和启动信息,并开始执行操作系统的初始化过程。

熟悉意法半导体的 STM32 微控制器的,就知道类似于中断向量表这些最最最最最基本的配置,一般都是放在 startup.s 里面的。宽泛地说,所有围绕 startup.s 文件开展的工作,就是芯片原厂需要做的 SoC 处理器软件适配,具体到ARM Cortex-A,则可以称作是 CPU软件适配。

2 需要考虑哪些问题?

2.1 提供 malloc 函数实现

既然目标在是在裸核上调用 malloc(),那首先得提供一个它的实现吧。

malloc 函数是 C 标准库中的动态内存分配函数。它用于在程序运行时从堆(Heap)中分配指定大小的内存块,并返回该内存块的起始地址。

使用 malloc 函数可以动态地分配内存,避免了在编译时静态地分配内存的限制。这对于需要在运行时根据需要分配或释放内存的情况非常有用。

malloc 函数的原型如下:

void *malloc(size_t size);

参数 size 指定所需内存块的大小,以字节为单位。返回值是一个指向分配的内存块起始地址的指针,类型为 void*。如果分配失败,则返回 NULL。

malloc这种标准函数,处理器厂商都会提供专门优化的实现,比如 ARM 就针对 ARM 处理器提供买了MicroLib库。这是一个精简的 C 标准库,包含常见的标准库函数,例如内存分配和释放(通过 mallocfree)、字符串操作(例如 strcpystrlen)以及输入输出函数(如 printfscanf)。一般在IDE的工程属性设置中勾选包含即可。

在这里插入图片描述

2.2 提供入口点(entry point)

处理器上电以后从预定位置执行ROM程序,而后跳转到RAM上指定位置执行应用程序,虽然C程序的主流程在main函数中描述,但无论是ROM还是RAM,第一条指令都不是main的入口,那么就需要咱提供跳转到main函数的指令,形如:

	.global main_app.balign 0x10
_reset:B	main_app

解析每条指令的含义如下:

.global main_app: 这是一个指令宏,用于声明 main_app 是一个全局标识符,该标识符可以在其他文件中引用。

.balign 0x10: 这是对齐指令,将下一个标签或指令地址对齐到 16 字节边界。这种对齐可能对于某些处理器或内存访问要求是必要的,例如某些 ARM 处理器可能需要特定的对齐方式以获得最佳性能。

_reset:: 这是一个标签,用于将 _reset 和下一个指令或数据相关联。标签可以用于跳转、调用或在汇编代码中创建有意义的位置。

B main_app: 这是无条件分支指令(Branch),将程序流转移到名为 main_app 的位置。B 指令将控制权直接跳转到指定的地址。

这段汇编代码的意图是:通过 _reset 标签将程序引导到 main_app 代码的入口点。在 _reset 处,执行一个无条件的分支指令 B,将控制权转移到 main_app 标签/符号(涉及编译原理)处的代码。

2.3 初始化堆栈指针

跳转到main函数的最终目的,是调用malloc函数,而arm处理器上执行函数调用势必发生压栈、出栈等堆栈操作,故而需要提前设置好堆栈,于是我们修改 startup.s 为:

	.set stack_top, 0x2E009000.global main_app
.balign 0x10
_reset:ldr r3, =stack_topmov sp, r3B	main_app

.set stack_top, 0x2E009000: 这是一个宏定义,表示将标识符 stack_top 的值设置为 0x2E009000。在这里,stack_top 被用来表示栈顶的地址,即堆栈将会从这个地址开始增长。

ldr r3, =stack_top: 这条指令将 stack_top 的值加载到寄存器 r3 中。

mov sp, r3: 这条指令将 r3 中的值移动到堆栈指针寄存器 sp 中。

2.4 整个程序应该放在什么地方运行?

自然是RAM中啦,软件设计人员应该找系统设计人员要一张系统架构图/地址分配表,据之明确片上存储器的位置和存储容量,然后才能确定如何编写链接文件。

啥是链接文件啊?链接文件(Linker file),也称为链接脚本(Linker script)或连接器脚本,是用于指导链接器(Linker)如何将多个目标文件(Object file)组合在一起以生成可执行文件的文本文件。

我们目前的地址分配表是这样的:
在这里插入图片描述
可以看到 System RAM 的起始地址是0x2E000000,存储容量是64KB,这就是我们的程序在运行时所处的位置(不考虑更上层的Cache和寄存器)。大概划分一下用途,前面 0x9000 的空间用来放指令,从 0x200E9000 开始的空间则用作堆(heap),即 mallocfree 函数管理的空间。
在这里插入图片描述
对应的链接脚本可以写成:

LOAD_REGION 0x2E000000 0x10000
{P0 +0{start_up.o}P1 +0{*(+ro)*(+rw, +zi)}ARM_LIB_STACK	+0 ALIGN 8 EMPTY 0x1000 {}ARM_LIB_HEAP 0x2E009000 EMPTY 0x7000 ; Heap region growing up{ }
}

可视化的效果为:
在这里插入图片描述

2.5 堆栈指针的初始值是怎么确定的?

原则就一句话——只要保证栈不会和堆或者代码段发生交叠(overlap)就行。这里我把栈放在代码段后面(0x200E9000之前),故而初始值设为:

.set stack_top, 0x2E009000

3 怎么验证适配效果?

答案是不外乎仿真、实测、反汇编三板斧。

3.1 实测验证

前两个很明白,写个测试程序看看适配的函数行为是否符合预期就行,例如用下面这个程序测试 mallocfree

/** author water cutter* */
#include <stdlib.h>unsigned int* ptrs[32] = {0};
unsigned int allocByteNum = 1;void main_app(){ptrs[0] = (unsigned int*)malloc(allocByteNum);ptrs[1] = (unsigned int*)malloc(allocByteNum);ptrs[2] = (unsigned int*)malloc(allocByteNum);free(ptrs);ptrs[3] = (unsigned int*)malloc(allocByteNum);while(1){ asm("nop"); }
}

比较ptrs[2]和ptrs[3]的值,一致则说明malloc和free功能正确(保证所有分配的地址都在堆空间范围内的前提下):

在这里插入图片描述

3.2 通过反汇编检验

.axf 或者 .out 文件反汇编,在反汇编文件中找到对应的实现,分析确认其功能正确即可。

free() 的反汇编:
在这里插入图片描述
malloc() 的反汇编:
在这里插入图片描述

源码

源码仓库:soc_port_method

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

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

相关文章

铁电材料极化高压放大器ATA-7025技术指标及使用说明

铁电材料是一类具有特殊电学性质的材料&#xff0c;在现代电子技术和器件中具有广泛的应用。铁电材料的极化是其重要的特征之一&#xff0c;极化测试是评估铁电材料性能的关键方法之一。一般铁电极化测试&#xff0c;是通过根据外电场施加的电压变化来观察材料产生的极化效应。…

结构型模式 - 组合模式

概述 对于这个图片肯定会非常熟悉&#xff0c;上图我们可以看做是一个文件系统&#xff0c;对于这样的结构我们称之为树形结构。在树形结构中可以通过调用某个方法来遍历整个树&#xff0c;当我们找到某个叶子节点后&#xff0c;就可以对叶子节点进行相关的操作。可以将这颗树理…

微信合并转发的图片如何批量保存

今天遇到一个场景&#xff1a;朋友给转发来了一个合并的聊天记录&#xff0c;里面是几十张图片&#xff0c;希望能打印出来。逐张保存太费手了。下面是批量保存图片的方法&#xff1a; 1、登录PC端微信&#xff1b; 2、将要保存图片的这条合并转发的聊天记录收藏&#xff1b;…

Camtasia Studio 2023怎么导出mp4格式的视频的详细教程介绍

很多用户刚接触Camtasia Studio 2023&#xff0c;不熟悉如何保存mp4格式的视频。在今天的文章中小编为大家带来了Camtasia Studio 2023保存为mp4格式的视频的详细教程介绍。 Camtasia Studio 2023保存为mp4格式的视频的详细教程 1、 打开Camtasia Studio。 Camtasia Studio- …

解决appium-doctor报ffmpeg cannot be found

一、下载ffmpeg安装包 https://ffmpeg.org/download.html 找到如图所示红框位置点击下载ffmpeg安装包。 二、配置ffmpeg环境变量 三、检查ffmpeg版本信息 重新管理员打开dos系统cmd命令提示符&#xff0c;输入ffmpeg查看是否出现版本信息&#xff0c;安装完好。 ffmpeg

短视频矩阵系统源码--开发实践

短视频矩阵系统源码开发技术&#xff1a; 1. 数据采集&#xff1a;使用Python的requests库进行数据爬取&#xff0c;使用Selenium模拟浏览器操作&#xff0c;解决抖音反爬虫机制。 2. 数据处理&#xff1a;使用Python的正则表达式、BeautifulSoup等库进行数据处理。 3. 关键…

使用Python和Scrapy实现抓取网站数据

Scrapy是一个功能强大的网络爬虫框架&#xff0c;允许开发者轻松地抓取和解析网站内容&#xff0c;这篇文章主要为大家介绍了如何使用Python的Scrapy库进行网站数据抓取&#xff0c;需要的可以参考一下 在本文中&#xff0c;我们将介绍如何使用Python的Scrapy库进行网站数据抓…

selenium-多窗口和frame处理

1.切换窗口 适用场景&#xff1a;点击按钮后&#xff0c;重新打开一个窗口&#xff0c;想要在新的窗口定位操作&#xff0c;就需要切换窗口 原理&#xff1a;获取窗口的唯一标识就是句柄&#xff0c;获取到句柄&#xff0c;就可以切换到对应的窗口了 处理方法&#xff1a; …

安达发|高级计划与智能排程APS软件的发展史进程

从泰勒的科学管理理论出发&#xff0c;率先追求科学的管理理论和管理工具&#xff0c;在计算机成为企业日常管理的基本工具之后&#xff0c;信息系统已经成为提高工厂管理水平的重要支柱。 在工厂计划领域&#xff0c;开始了从MRP到MRPII再到ERP的演变过程。MRPII指的是制造…

自动化测试工具比传统测试工具的优势体现在哪里?

随着软件行业的快速发展和扩张&#xff0c;自动化测试工具在提高测试效率和质量方面起到了不可或缺的作用&#xff0c;那你知道自动化测试工具比传统测试工具的优势体现在哪里吗&#xff1f; 首先&#xff0c;自动化测试工具能够大大缩短测试周期。相比于传统手动测试&#xff…

Spring AOP知识点详解

Spring AOP是 Spring最核心的能力&#xff0c;那到底什么是AOP呢&#xff0c;今天了不起带大家了解一下。 AOP是什么 AOP(Aspect Oriented Programming):面向切面编程&#xff0c;是OOP(面向对象编程)的一个延续&#xff0c;其和OOP一样&#xff0c;也是一种编程思想&#xff0…

大模型时代,腾讯云“复制”腾讯|WAIC2023

点击关注 文&#xff5c;郝鑫 编&#xff5c;刘雨琦 刚过去的WAIC&#xff08;世界人工智能大会&#xff09;俨然成为了大模型厂商的成果汇报大会。 百度文心大模型升级到3.5版本&#xff0c;训练速度提升2倍&#xff0c;推理速度提升30倍&#xff1b;华为云发布盘古大模型3…

《无畏契约》游戏分析

文章目录 介绍游戏继承性《守望先锋》游戏美术对比游戏机制对比 《CSGO》游戏美术对比游戏机制对比 《英雄联盟》游戏美术对比游戏机制对比 《无畏契约》的优点《无畏契约》的缺点该游戏值得学习之处总结 介绍 《无畏契约&#xff08;VALORANT&#xff09;》是一款由拳头游戏&…

计算机vcruntime140.dll丢失的解决方法,重新安装教程

vcruntime140.dll是Microsoft Visual C Redistributable文件中的一个动态链接库&#xff08;DLL&#xff09;。这个文件是由Microsoft开发的&#xff0c;用于支持C编程语言的运行环境。vcruntime140.dll是Windows系统非常重要的文件&#xff0c;通常会被一些应用程序或游戏所需…

AR气象博物馆模拟体验提升青少年认知

国际气象节主要目的是唤起人们对气象工作的重视和热爱。近年来&#xff0c;极端天气频发&#xff0c;人们需要提高警惕&#xff0c;AR气象远程普利用ar技术特有的沉浸式的体感互动&#xff0c;通过模拟演练提升体验者的安全防范意识和求生技巧。 系统结合VR虚拟现实、AR增强现实…

准备WebUI自动化测试面试?这30个问题你必须掌握(二)

本文共有11000字&#xff0c;包含了后十五个问题&#xff0c;如需要前十五个问题&#xff0c;可查看文末链接~ 16. 在WebUI自动化测试中&#xff0c;你如何处理验证码或图像识别的问题&#xff1f; 1. 人工识别&#xff1a;一种简单但费时费力的方法是使用人工手动识别验证码。…

事件传播机制和事件委托

DOM事件流 DOM事件流&#xff08;event flow &#xff09;存在三个阶段&#xff1a;事件捕获阶段、处于目标阶段、事件冒泡阶段。事件捕获&#xff08;event capturing&#xff09;&#xff1a;通俗的理解就是&#xff0c;当鼠标点击或者触发dom事件时&#xff0c;浏览器会从…

(学习笔记-TCP连接建立)TCP 为什么是三次握手?不是两次、四次?

常规回答&#xff1a;“因为三次握手才能保证双方具有接收和发送的能力” 原因一&#xff1a;避免历史连接 三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。 假设&#xff1a;客户端先发送了SYN(seq90)报文&#xff0c;然后客户端宕机了&#xff0c;而且这个SYN报…

NOSQL简单实战

目录 实战一&#xff1a; 1、 string类型数据的命令操作&#xff1a; &#xff08;1&#xff09; 设置键值&#xff1a; &#xff08;2&#xff09; 读取键值&#xff1a; &#xff08;3&#xff09; 数值类型自增1&#xff1a; &#xff08;4&#xff09; 数值类型自减1&…

图像标注是什么?及其类型和应用

什么是图像标注&#xff1f; 图像标注是与您交互的许多人工智能产品的基础&#xff0c;并且是计算机视觉&#xff08;CV&#xff09;领域重要的过程之一。在图像标注过程中&#xff0c;数据标注员使用标签或元数据来标记AI模型学习识别的数据特征。然后&#xff0c;这些图像标…