macOS 下的 ARM 裸机嵌入式开发入门- 第二部分:实现第一个裸机应用并且调试

在这里插入图片描述

1、准备二进制运行程序镜像

利用 QEMU 仿真一个完整的系统,并创建最简单的“Hello world!”示例。

QEMU 模拟器支持 VersatilePB 平台,该平台包含一个 ARM926EJ-S 核心,以及其他外设,四个 UART 串行端口;特别是第一个串行端口(UART0)在使用 -nographic 或 “-serial stdio” qemu 选项时充当终端。UART0 被映射的地址:0x101f1000

为了实现简单的“Hello world!”打印,编写test.c 文件如下:

volatile unsigned int * const UART0DR = (unsigned int *)0x101f1000;void print_uart0(const char *s) {while(*s != '\0') { /* 循环直到字符串结束 */*UART0DR = (unsigned int)(*s); /* 传输字符 */s++; /* 下一个字符 */}
}void c_entry() {print_uart0("Hello world!\n");
}

代码非常简单;一些细节:

  • volatile 关键字是必要的,以指示编译器 UART0DR 指向的内存可以独立于程序改变或产生影响。 unsigned int类型强制执行 32 位读写访问。

  • QEMU 模型的 PL011 串行端口忽略了传输 FIFO 功能;在实际的系统芯片中,必须在
    UARTFR 寄存器中检查“传输 FIFO 满”标志,然后才在 UARTDR 寄存器上写入。

  • -kernel 选项将二进制文件(通常是 Linux 内核)加载到系统内存中,从地址0x00010000 开始。模拟器从地址 0x00000000 开始执行,其中一些指令(已经就位)用于跳转到内核映像的开头。ARM核心的中断表通常位于地址 0x00000000。

startup.s 汇编器文件内容如下:

.global _Reset
_Reset:LDR sp, =stack_topBL c_entryB .

链接器脚本 test.ld:

ENTRY(_Reset)
SECTIONS
{. = 0x10000;.startup . : { startup.o(.text) }.text : { *(.text) }.data : { *(.data) }.bss : { *(.bss COMMON) }. = ALIGN(8);. = . + 0x1000; /* 4kB 的堆栈内存 */stack_top = .;
}

运行的命令,生成相应的elf和bin文件:

$ arm-none-eabi-as -mcpu=arm926ej-s -g startup.s -o startup.o
$ arm-none-eabi-gcc -c -mcpu=arm926ej-s -g test.c -o test.o
$ arm-none-eabi-ld -T test.ld test.o startup.o -o test.elf
$ arm-none-eabi-objcopy -O binary test.elf test.bin

2、执行和调试二进制文件

在模拟器中运行程序,命令是:

$ qemu-system-arm -M versatilepb -m 128M -nographic -kernel test.bin

-M 选项指定了被模拟的系统。程序在终端打印 “Hello world!” 并无限期运行;要退出 QEMU,请按 “Ctrl + a” 然后按 “x”。

QEMU 实现了一个使用 TCP 连接的 gdb 连接器。按照以下方式运行模拟器:

$ qemu-system-arm -M versatilepb -m 128M -nographic -s -S -kernel test.bin

此命令在执行任何客户代码之前冻结系统,并在 TCP 端口 1234 上等待连接。从另一个终端,我运行 arm-none-eabi-gdb 并输入命令:

target remote localhost:1234
file test.elf

这连接到 QEMU 系统并加载测试程序的调试符号,其二进制图像已经加载在系统内存中。从那里,可以使用 continue 命令运行程序,单步执行程序并进行一般调试。gdb 中的 exit 命令关闭了调试器和模拟器。
编译和运行命令的参考结果见下图,左边是编译和执行的情况,右边是用arm-none-eabi-gdb工具调试的情况:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【网络面试篇】其他面试题——Cookie、Session、DNS、CDN、SSL/TLS、加密概念

目录 一、HTTP 相关问题 1. Cookie 和 Session 是什么? (1)Cookie (2)Session 2. Cookie 的工作原理? 3. Session 的工作原理? 4. Cookie 和 Session 有什么区别? 二、其他问…

【数值分析】复习1---牛顿迭代法

首先,我们先来回顾一下牛顿迭代法的概念。 这里注意的是,牛顿迭代法是一种线性方法,它在点 x k x_k xk​处进行线性展开,而且展开成一阶泰勒公式!注意是一阶,不是二阶,不是更高阶,所…

文本语义分块、RAG 系统的分块难题:小型语言模型如何找到最佳断点

文本语义分块、RAG 系统的分块难题:小型语言模型如何找到最佳断点? 转自jina最新的关于文本语义分块的分享和模型 之前我们聊过RAG 里文档分块 (Chunking) 的挑战,也介绍了 迟分 (Late Chunking) 的概念,它可以在向量化的时候减…

PostgreSQL中如果有Left Join的时候索引怎么加

在PostgreSQL中,当你的查询包含多个LEFT JOIN和WHERE条件时,合理地添加索引可以显著提高查询性能。以下是一些具体的优化步骤和建议: 1. 分析查询 使用 EXPLAIN ANALYZE 命令分析你的查询,了解查询的执行计划,识别出连…

温度虽寒,其道犹变:OpenAI接口之温度参数设置为0,为何每次回复仍有不确定性?

问题描述 调用openai API,使用templature 0,每次返回的内容仍有一些不同 >>> client OpenAI( ... api_keyapi_key, ... base_urlapi_base) #第一次尝试 >>> response client.chat.completions.create(mo…

vue-h5:在h5中实现相机拍照加上身份证人相框和国徽框

参考: https://blog.csdn.net/weixin_45148022/article/details/135696629 https://juejin.cn/post/7327353533618978842?searchId20241101133433B2BB37A081FD6A02DA60 https://www.freesion.com/article/67641324321/ https://github.com/AlexKratky/vue-camer…

国标GB28181视频平台EasyCVR私有化部署视频平台对接监控录像机NVR时,录像机“资源不足”是什么原因?

EasyCVR视频融合云平台,是TSINGSEE青犀视频“云边端”架构体系中的“云平台”系列之一,是一款针对大中型项目设计的跨区域、网络化、视频监控综合管理系统平台,通过接入视频监控设备及视频平台,实现视频数据的集中汇聚、融合管理、…

【Android、IOS、Flutter、鸿蒙、ReactNative 】标题栏

Android 标题栏 参考 Android Studio版本 配置gradle镜像 阿里云 Android使用 android:theme 显示标题栏 添加依赖 dependencies {implementation("androidx.appcompat:appcompat:1.6.1")implementation("com.google.android.material:material:1.9.0")…

歌尔微拟赴港IPO,揭示AI+终端升级的供给革命

1959年,美国物理学家理查德费曼在他著名的演讲“底部有足够的空间”中,首次提出了将机器小型化到原子和分子尺度的想法。这个充满想象力的观点,为世界科技发展开启了一扇新的窗口。 时至今日,应这一理念而生的MEMS产品已经成为各…

ROS第七梯:ROS+VSCode+Python环境配置

第一步:Python版本的ROS项目和C++版本的ROS项目前期创建功能包的步骤基本一致,具体可参考第二章。 第二步:在功能包的目录下创建一个与src目录平级的文件夹,名称写作scripts: 第三步:在scripts文件夹下创建python的节点代码文件,此处以一个订阅节点代码文件为例:

洛谷解题日记||基础篇3

#include <iostream> #include <iomanip> // 用于设置输出格式 using namespace std;double a, b, c, d;// 定义方程 f(x) ax^3 bx^2 cx d double fc(double x) {return a * x * x * x b * x * x c * x d; }int main() {double l, r, m, x1, x2;int s 0;/…

软件测试学习记录 Day1

根据黑马程序员最新版的软件测试课程所做的笔记&#xff0c;需要原件后台私信&#xff1a; 练习提取测试点&#xff1a; 博主的答案&#xff0c;有不一样看法的可评论区讨论&#xff1a;

代码随想录刷题记录(二十七)——55. 右旋字符串

&#xff08;一&#xff09;问题描述 55. 右旋字符串&#xff08;第八期模拟笔试&#xff09;https://kamacoder.com/problempage.php?pid1065字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k&#xff0c;请编写一个函数&…

FreeRTOS 24:事件组EventGroup等待、清零、获取操作

等待事件标志位xEventGroupWaitBits() 既然标记了事件的发生&#xff0c;那么我怎么知道他到底有没有发生&#xff0c;这也是需要一个函数来获 取 事 件 是 否 已 经 发 生 &#xff0c; FreeRTOS 提 供 了 一 个 等 待 指 定 事 件 的 函 数 — — xEventGroupWaitBits()&…

信息安全数学基础(47)域的结构

一、域的定义 设F为一个非空集合&#xff0c;在其上定义两种运算&#xff1a;加法和乘法。如果这两种运算在集合上封闭&#xff0c;且满足以下条件&#xff0c;则称F对于规定的乘法和加法构成一个域&#xff1a; F中所有元素对于加法形成加法交换群&#xff0c;即加法满足交换律…

#渗透测试#SRC漏洞挖掘#CSRF漏洞的防御

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

HarmonyOS 沉浸式状态实现的多种方式

1. HarmonyOS 沉浸式状态实现的多种方式 HarmonyOS 沉浸式状态实现的多种方式 1.1. 方法一 1.1.1. 实现讲解 &#xff08;1&#xff09;首先设置setWindowLayoutFullScreen(true)&#xff08;设置全屏布局&#xff09;。   布局将从屏幕最顶部开始到最底部结束&#xff0c…

在API接口数据获取过程中,如何确保数据的安全性和隐私性?

在API接口数据获取过程中&#xff0c;确保数据的安全性和隐私性至关重要。以下是一些关键措施&#xff0c;可以帮助开发者和管理者保护API接口的数据安全和隐私性&#xff1a; 身份认证和授权 身份认证&#xff1a;确认用户身份的过程&#xff0c;常用的身份认证方式包括用户…

C++常用的特性-->day05

友元的拓展语法 声明一个类为另外一个类的友元时&#xff0c;不再需要使用class关键字&#xff0c;并且还可以使用类的别名&#xff08;使用 typedef 或者 using 定义&#xff09;。 #include <iostream> using namespace std;// 类声明 class Tom; // 定义别名 using …

python-27-Python ORM系列之彻底搞明白ORM概念,对ORM进行封装结合FastAPI实现数据库的增删改查,联表查询等接口

python-27-Python ORM系列之彻底搞明白ORM概念&#xff0c;对ORM进行封装结合FastAPI实现数据库的增删改查&#xff0c;联表查询等接口 一.简介 在Python基础系列ORM部分为大家介绍了如何搭建MySQL数据和MySQL一些访问配置&#xff0c;同时也介绍了pymysql库的封装来实现对数…