当前位置: 首页 > 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程序一…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

CSS3相关知识点

CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...

Oracle实用参考(13)——Oracle for Linux物理DG环境搭建(2)

13.2. Oracle for Linux物理DG环境搭建 Oracle 数据库的DataGuard技术方案,业界也称为DG,其在数据库高可用、容灾及负载分离等方面,都有着非常广泛的应用,对此,前面相关章节已做过较为详尽的讲解,此处不再赘述。 需要说明的是, DG方案又分为物理DG和逻辑DG,两者的搭建…...

轻量安全的密码管理工具Vaultwarden

一、Vaultwarden概述 Vaultwarden主要作用是提供一个自托管的密码管理器服务。它是Bitwarden密码管理器的第三方轻量版,由国外开发者在Bitwarden的基础上,采用Rust语言重写而成。 (一)Vaultwarden镜像的作用及特点 轻量级与高性…...

SDU棋界精灵——硬件程序ESP32实现opus编码

一、 ​​音频处理框架​ 该项目基于Espressif的音频处理框架构建,核心组件包括 ESP-ADF 和 ESP-SR,以下是完整的音频处理框架实现细节: 1.核心组件 (1) 音频前端处理 (AFE - Audio Front-End) ​​main/components/audio_pipeline/afe_processor.c​​功能​​: 声学回声…...

python学习day39

图像数据与显存 知识点回顾 1.图像数据的格式:灰度和彩色数据 2.模型的定义 3.显存占用的4种地方 a.模型参数梯度参数 b.优化器参数 c.数据批量所占显存 d.神经元输出中间状态 4.batchisize和训练的关系 import torch import torchvision import torch.nn as nn imp…...