当前位置: 首页 > news >正文

从零学习开发一个RISC-V操作系统(二)丨GCC编译器和ELF格式

本篇文章的内容

  • 一、GCC(GUN Compiler Collection)
    • 1.1 GCC的命令格式
    • 1.2 GCC的主要执行步骤
    • 1.3 GCC涉及的文件类型
  • 二、ELF简介
    • 2.1 ELF文件格式图
    • 2.2 ELF文件处理的相关工具
    • 2.3 练习


  本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记,计划从RISC-V的底层汇编指令学起,结合C语言,在Ubuntu 20.04上开发一个简易的操作系统。一个目的是通过实践操作学习和了解什么是操作系统,第二个目的是为之后学习RISC-V的集成电路设计打下一定基础。本系列持续不定期更新,分享出来和大家一同交流进步。
  博主是微电子科学与工程专业的学生,对软件和操作系统难免有理解不到位的地方。如有谬误敬请不吝告知,不胜感激。

  参考课程及文章:
  【Bilibili】[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春


一、GCC(GUN Compiler Collection)

  GCC是一个由GNU(一个自由软件基金会组织)开发的,遵循GPL许可证发行的编译器套件,是一个编译器的集合。支持 C、C++、Objective-C、Fortran、Ada 和 Go 语言等多种语言前端,已被移植到多种计算机体系架构上,如 x86、ARM、RISC-V 等。在之后的课程中使用的也是GCC作为编译工具。GCC 的初衷是为 GNU 操作系统专门编写一款编译器,现已被大多数 “Unix-like”操作系统(如 Linux、BSD、MacOS 等)采纳为标准的编译器。

1.1 GCC的命令格式

  • GCC 操作选项 文件名
常用操作选项含义
-E只做预处理(将包含的宏语言头文件转化为C语言文件)
-c只编译(生成机器指令)不链接(与库文件相连),生成目标文件.o
-S生成汇编代码
-o file将输出的文件生成到由file指定文件名的文件中
-g在输出的文件中加入支持调试的信息
-v显示输出详细的命令执行过程信息

1.2 GCC的主要执行步骤

在这里插入图片描述

  1. 编译

  编译(使用cc1程序,这里针对 C 语言,不同的语言有自己的编译器):编译器完成 “预处理” 和 “编译”,“预处理” 指处理源文件中以 “#” 开头的预处理指令,譬如 #include、#define 等;“编译” 则针对预处理的结果进行一系列的词法分析、语法分析、语义分析,优化后生成汇编指令,存放在 .o 为后缀的目标文件中。

  1. 汇编

  汇编(使用as程序):汇编器将汇编语言代码转换为机器(CPU)可以执行的指令。

  1. 链接

  链接(使用ld程序):链接器将汇编器生成的目标文件和一些标准库(譬如 libc)的.o文件组合,形成最终可执行的应用程序。

在这里插入图片描述

1.3 GCC涉及的文件类型

  • .c:C 源文件
  • .cc/.cxx/.cpp:C++ 源文件
  • .i:经过预处理的 C 源文件
  • .s/.S:汇编语言源文件(.S文件中还包含宏指令,.s`文件中是纯汇编指令)
  • .h:头(header)文件
  • .o:目标(object)文件
  • .a/.so:编译后的静态库(archive)文件和共享库(shared object)文件
  • a.out:可执行文件,常见于Unix系统

二、ELF简介

  ELF(Executable Linkable Format)是一种 Unix-like系统上的二进制文件格式标准。ELF文件格式对于底层的操作系统开发非常重要,当程序需要在底层进行优化,调试,排错等操作时,ELF文件可以更好地帮助程序员完成任务。ELF 标准中定义的采用 ELF 格式的文件分为以下4类:
在这里插入图片描述

2.1 ELF文件格式图

在这里插入图片描述
  ELF格式是在程序编译链接过程中生成的文件采用的通用格式。如果直接用文本编辑器或二进制编辑器打开该文件,无法直接看出文件中包含的信息,因为该文件是用二进制书写的。但是其中每一个字节都有其特定的含义,这些字节的排布遵从ELF文件格式。ELF文件中最主要的部分包括ELF文件头(ELF Header)、程序头表(Program Header Table)和节头表(Section Header Table)
  ELF文件头(ELF Header)中包含了该文件的一些基本信息,例如该文件运行在哪种体系架构上,运行的版本号等。
  ELF文件的主体部分是多个程序节(Section)。如上图所示,.text中一般存放指令(程序的具体操作),.init中一般存放一些初始化操作,.data中存放程序要操作的数据,例如在程序中定义的全局变量等。
  在程序加载到内存前,一般都要对各个节进行对齐操作。例如,当程序按4KB进行分节时,如果.test节中的内容本身很少,且不加任何操作,它就会按4KB的大小独占一部分区域。为了节省内存空间,我们对各个节的内容按属性进行归并,例如.text.init都存放了一些程序运行的指令,所以我们可以对齐进行归并,形成了程序段(Segment)。一个程序段可以由多个程序节构成。
  ELF程序头表(Program Header Table)从运行角度描述了程序的内容,它是程序运行视图的体现。程序头表中包含了该文件中哪几个节要归并成一个段,每一个段占用的大小,入口地址等信息。其中包含的信息只有在运行时才会用到。
  ELF节头表(Section Header Table)中存放的该文件中包含的节的信息,包括节的名称,节的入口地址,节的大小等。节头表从链接的角度描述了程序的内容,它是程序链接视图的体现。其中的信息只有链接时才会用到。

2.2 ELF文件处理的相关工具

  对程序员而言,手动查看和调试ELF文件的过程是十分繁琐的,GNU为程序员提供了相关的处理工具软件,存放在Binutils工具包中。该工具包中的小程序如下:

  • ar:归档文件,将多个文件打包成一个大文件。
  • as:被 gcc 调用,输入汇编文件,输出目标文件供链接器 ld 连接。
  • ld:GNU 链接器。被 gcc 调用,它把目标文件和各种库文件结合在一起,重定位数据,并链接符号引用。
  • objcopy:执行文件格式转换。
  • objdump:显示 ELF 文件的信息。
  • readelf:显示更多 ELF 格式文件的信息(包括DWARF 调试信息)。

2.3 练习

使用gcc编译代码并使用Binutlis工具对生成的目标文件和可执行文件(ELF格式)进行分析,具体要求如下:

  • 编写一个简单的打印“Hello world!”的程序源文件hello.c
  • 对源文件进行本地编译,生成针对支持x86_64指令集架构处理器的目标文件hello.o
  • 查看hello.o的文件的ELF文件头信息
  • 查看hello.o的节头表
  • hello.o进行反汇编,并查看hello.c的程序源码和机器指令的对应关系

  首先,在Vim编辑器中编写一个简单的hello.c程序:
在这里插入图片描述
  如果我们需要hello.o文件,说明只需要编译,不需要链接,所以在终端中输入如下代码:

$ gcc -c hello.c -o hello.o

  查看hello.o文件中ELF文件头信息(-h就表示查看文件头header):

$ readelf -h hello.o

在这里插入图片描述
  查看hello.o的节头表(-SW表示显示节头表,并展宽表示):

$ readelf -SW hello.o

在这里插入图片描述
  要对文件进行反汇编,首先要重新编译程序,并使用gdb使其携带调试信息,之后使用objdump对程序hello.o进行反汇编。可以看到每一条C语句对应的汇编指令,可以利用该工具对程序进行调试和优化。

$ rm hello.o
$ gcc -g -c hello.c
$ objdump -S hello.o

在这里插入图片描述


  原创笔记,码字不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!博主将持续更新有关嵌入式开发、机器学习方面的学习笔记。


相关文章:

从零学习开发一个RISC-V操作系统(二)丨GCC编译器和ELF格式

本篇文章的内容 一、GCC(GUN Compiler Collection)1.1 GCC的命令格式1.2 GCC的主要执行步骤1.3 GCC涉及的文件类型 二、ELF简介2.1 ELF文件格式图2.2 ELF文件处理的相关工具2.3 练习 本系列是博主参考B站课程学习开发一个RISC-V的操作系统的学习笔记&…...

论文阅读_大语言模型_Llama2

英文名称: Llama 2: Open Foundation and Fine-Tuned Chat Models 中文名称: Llama 2:开源的基础模型和微调的聊天模型 文章: http://arxiv.org/abs/2307.09288 代码: https://github.com/facebookresearch/llama 作者: Hugo Touvron 日期: 2023-07-19 引用次数: 11…...

当量因子法、InVEST、SolVES模型等多技术融合在生态系统服务功能社会价值评估中的应用及论文写作、拓展分析

生态系统服务是人类从自然界中获得的直接或间接惠益,可分为供给服务、文化服务、调节服务和支持服务4类,对提升人类福祉具有重大意义,且被视为连接社会与生态系统的桥梁。自从启动千年生态系统评估项目(Millennium Ecosystem Asse…...

k8s Limits 限制内存

Limits 限制内存 在 Kubernetes (K8s) 中,可以使用 Limits(资源限制)来限制 Pod(容器)使用的内存数量。此处的 Limits 表示 Pod 在 K8s 集群中可用的最大内存量。一旦 Pod 内存使用超过这个限制,可能会触发…...

单片机第三季-第三课:STM32开发板原理图、配置、浮点运算单元

目录 1,开发板原理图 2,浮点运算单元(FPU) 1,开发板原理图 课程视频比较早,介绍了三款开发板。观看视频时用的开发板说和51单片机共板的STM32核心板,将51单片机从底座拆下来后,安…...

观察者模式 发布-订阅模式(设计模式与开发实践 P8)

文章目录 观察者模式运用实现 观察者模式 定义:他用来定义对象之间一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖他的对象都会得到通知 运用 如果我们使用过 DOM 上的事件函数,那就接触过观察者模式 document.body…...

【日常业务开发】Java实现异步编程

【日常业务开发】Java实现异步编程 Java实现异步编程什么是异步异步的八种实现方式异步编程线程异步Future异步CompletableFuture实现异步Spring的Async异步Spring ApplicationEvent事件实现异步消息队列ThreadUtil异步工具类Guava异步 CompletableFuture异步编排工具类创建异步…...

学习笔记|模数转换器|ADC原理|STC32G单片机视频开发教程(冲哥)|第十七集:ADC采集

文章目录 1.模数转换器(ADC)是什么?手册说明: 2.STC32G单片机ADC使用原理19.1.1 ADC控制寄存器(ADC_CONTR)19.1.2 ADC配置寄存器(ADCCFG)19.1.4ADC时序控制寄存器(ADCTIM)19.3 ADC相…...

OpenCV实现“蓝线挑战“特效

原理 算法原理可以分为三个流程: 1、将视频(图像)从(顶->底)或(左->右)逐行(列)扫描图像。 2、将扫描完成的行(列)像素重新生成定格图像…...

容器管理工具 Docker生态架构及部署

目录 一、Docker生态架构 1.1 Docker Containers Are Everywhere 1.2 生态架构 1.2.1 Docker Host 1.2.2 Docker daemon 1.2.3 Registry 1.2.4 Docker client 1.2.5 Image 1.2.6 Container 1.2.7 Docker Dashboard 1.3 Docker版本 二、Docker部署 2.1 使用YUM源部署…...

js判断数据类型的方法

简单数据类型用:typeof, // 可以直接typeof空格接数据的方式,也可以typeof(数据)的方式使用 console.log(typeof ""); //string(检验字符串没问题) console.log(typeof 1); //number(检验数字没问题) console.log(typ…...

达梦数据库随系统开机自动启动脚本

写一个脚本,实现在服务器开机后自动启动达梦数据库的功能。 1. 在/etc/init.d/目录下,编写脚本,并将脚本命名为startdm.sh。脚本内容实现如下: #!/bin/bash #chkconfig:2345 80 90 #decription:启动达梦# 切换到 dmdba 用户 su …...

Python开发利器之VS Code

Python官方提供了一个Python集成开发环境(IDE): IDLE (Integrated Development and Learning Environment)。 它提供了一个图形用户界面,可以让开发者编写、调试和执行Python程序。IDLE包含Python解释器、代码编辑器、调试器和文件…...

【Axure视频教程】输入框控制滑动评分条

今天教大家在Axure里如何制作输入框控制滑动评分条的原型模板,可以通过鼠标左右拖动滑块,也可以点击条形让滑块移动到指定位置,标签和输入框里会返回具体的分值,分值由滑块所在的位置动态计算而成;也可以在输入框里输入…...

【学习笔记】[AGC064C] Erase and Divide Game

有点难😅,看到比自己低一级的选手场切这道题就更绷不住了😇 考虑 从低到高位 建立 trie \text{trie} trie 树,但是因为是对反串建立的,所以编号连续的点在 trie \text{trie} trie 树上的位置是分散的😅 …...

算法通关村-----数组中元素出现次数问题

数组中出现次数超过一半的数字 问题描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。详见剑指offer39 问题分析 最直接的方式就是使用hashMap,遍历给定数组&#xff0c…...

Qt-键盘消息的传递-键盘消息的获取-C++

文章目录 1.概述2.焦点3.强制获取键盘消息4.键盘常用组合方法5.总结 1.概述 QKeyEvent 类用来描述一个键盘事件。当键盘按键被按下或者被释放时,键盘事件便会被发送给拥有键盘输人焦点的部件。 QKeyEvent 的 key() 函数可以获取具体的按键,对于 Qt 中给…...

数据结构与算法(五)--链表概念以及向链表添加元素

一、前言 今天我们学习另一种非常重要的线性数据结构–链表,之前我们已经学习了三种线性数据结构,分别是动态数组,栈和队列。其中队列我们额外学习了队列的另一种实现方式–循环队列。其实我们自己实现过前三个数据结构就知道,它…...

计算机视觉与深度学习-图像分割-视觉识别任务02-目标检测-【北邮鲁鹏】

目录标题 参考目标检测定义深度学习对目标检测的作用单目标检测多任务框架多任务损失预训练模型姿态估计 多目标检测问题滑动窗口(Sliding Window)滑动窗口缺点 AdaBoost(Adaptive Boosting)参考 区域建议 selective search 思想慢…...

Flink——Flink检查点(checkpoint)、保存点(savepoint)的区别与联系

Flink checkpoint Checkpoint是Flink实现容错机制最核心的功能,能够根据配置周期性地基于Stream中各个Operator的状态来生成Snapshot,从而将这些状态数据定期持久化存储下来,从而将这些状态数据定期持久化存储下来,当Flink程序一…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

<6>-MySQL表的增删查改

目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表&#xf…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

【机器视觉】单目测距——运动结构恢复

ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛&#xf…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...