IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 嵌入式系统裸机程序开发与调试 -> 正文阅读

[系统运维]嵌入式系统裸机程序开发与调试

🌹1.GUN工具的使用

GUN是一个开源的组织,给我们带来了很多开源软件和编译工具,如我们常用的

  • C编译器 :gcc
  • 预处理器 :cpp
  • C++编译器 g++
  • 汇编器 :as
  • 链接器 :ld
  • 二进制工具集 :objcopy
    二进制工具集的含义:他们专门用于控制和将二进制目标代码从一种格式转换为另一种格式,这些工具被称作为objcopy和objdump,许多linux机器使用的底层软件在编译阶段都非常依赖这些工具。调试的时候也需要他们。objcopy用于从一个文件拷贝目标代码到另一个文件,并在这个过程中进行转换。这样外面可以在不同的目标代码格式之间进行自动的转换并操纵这个过程中的内容。他们可以任何方式来操作二进制文件。

🚀1.1符号显示器nm

可通过arm-linux-gcc -v 查看是否有arm-linux-gcc这个编译器

显示符号 $nm -n main_elf
显示内容:
?第一列为符号地址
?第二列为符号所在段
?第三列为符号名称
比如我执行arm-linux -nm -n demo,demo是我的一个可执行程序,会出现如下信息
在这里插入图片描述
这些符号的含义如下图所示:
在这里插入图片描述

这个符号显示器很有用,可以看到绝大部分的信息,但是局部变量是看不到的,因为他分配在栈里面

💒1.2objdump:信息查看器

objdump 有点像那个快速查看之类的工具,就是以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。对于一般只想让自己程序跑起来的程序员,这个命令没有更多意义,对于想进一步了解系统的程序员,应该掌握这种工具,至少你可以自己写写shellcode了,或者看看人家给的 exploit 中的 shellcode 是什么东西。

? 查看所有段信息 $objdump -h main_elf
? 查看文件头信息 $objdump -f main_elf
? 查看反汇编 $objdump -d main_elf
? 查看内嵌反汇编 $objdump -S -d main_elf
我一一演示一遍这些命令的使用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

🎪1.3objcopy:段剪辑器

objcopy被用来复制一个目标文件的内容到另一个文件中,可以使用不同于源文件的格式来输出目的文件,即可以进行格式转换

去除elf格式信息
$objcopy -O binary -S main_elf main.bin

??2.程序编译过程

程序编译4步骤:
在这里插入图片描述
(1)预处理
C/C++源文件中,以“#”开头的命令被称为预处理命令,如包含命令“#include”、宏定义命令“#define”、条件编译命令“#if”、“#ifdef”等。预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到一个“.i”文件中等待进一步处理。
(2)编译
编译就是把C/C++代码(比如上述的“.i”文件)“翻译”成汇编代码。
(3)汇编
汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现为ELF目标文件(OBJ文件)。“反汇编”是指将机器代码转换为汇编代码,这在调试程序时常常用到。
(4)链接
链接就是将上步生成的OBJ文件和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。

  • 一个标准应用程序通常都由链接器采用默认链接脚本(arm-linux-ld --verbose)将“用户程序” 和“库” 共同链接生成可执行程序

?2.1程序链接过程

链接过程中需要一个标号(_start)作为程序入口
标号(_start)的作用是: 将用户程序从汇编带到了C语言程序入口, 即main()函数, 从此开始我们的应用程序之旅

2.2指定头文件

头文件在哪里?

  • 系统目录

    • 系统目录在哪?工具链里的某个include目录

    • 怎么确定?

      echo 'main(){}'| gcc -E -v -  // 它会列出头文件目录、库目录(LIBRARY_PATH)
      
    • 可以不使用系统include目录吗?可以,编译时指定参数-nostdinc

  • 可以自己指定头文件目录

-I <头文件目录>

🎪2.3 指定库文件

库文件在哪里?

  • 系统目录

    • 系统目录在哪?工具链里的某个lib目录

    • 怎么确定?

      echo 'main(){}'| gcc -E -v -  // 它会列出头文件目录、库目录(LIBRARY_PATH)
      
    • 可以不使用系统lib目录吗?可以,编译时指定参数-nostdlib

  • 可以自己指定库文件目录

-L <库文件目录>
  • 指定库文件
-l  <abc>   // 链接 libabc.so 或 lib.a

?3.裸机开发流程

*假设你写了一个程序名字为uart_test.c

  1. 使用命令编译:arm-linux-gcc uart_test.c -c -o uart.o

  2. 链接并强行指定main入口为0x48000000:arm-none-linux-gnueabi-ld uart.o -o uart-test -e main -Ttext=0x48000000

  3. 把elf文件变为bin结尾的二进制文件arm-none-linux-gnueabi-objcopy -O binary -S uart

  4. 把生成的.bin结尾的文件放到windows

  5. linux板子终端进入uboot修改环境变量执行setenv loadaddr 0x48000000修改并通过saveenv进行保存,注意环境变量的地址为你强行指定main函数的地址在这里插入图片描述

  6. 在uboot敲loadb命令等待文件传输

  7. 打开超级终端serucecrt把.bin文件传输到板子里在这里插入图片描述

  8. 通过go 0x48000000 执行main函数,这时一个完整的程序就可以执行了,可以在里面执行最简单的点灯操作,如下图所示
    在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 20:02:38  更:2021-11-09 20:02:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 23:17:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码