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

从头开发一个RISC-V的操作系统(四)嵌入式开发介绍

文章目录

  • 前提
  • 嵌入式开发
  • 交叉编译
  • GDB调试,QEMU,MAKEFILE
  • 练习

目标:通过这一个系列课程的学习,开发出一个简易的在RISC-V指令集架构上运行的操作系统。

前提

这个系列的大部分文章和知识来自于:[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春,以及相关的github地址。

在这个过程中,这个系列相当于是我的学习笔记,做个记录。

嵌入式开发

搞过51,32单片机的同学应该能明白什么是嵌入式开发。嵌入式开发是一种系统级别的与硬件结合比较紧密的软件开发结束。

交叉编译

参与编译与运行的机器根据角色可以分为三类:

  • 构建(build)系统:执行编译构建动作的计算机
  • 主机(host)系统:运行build系统生成可执行程序的计算机系统
  • 目标(target)系统:特别地,当以上生成的可执行程序是GCC时,我们用target来描述用来运行GCC生成的可执行程序的计算机系统。

那么交叉编译就是:build == host != target
在这里插入图片描述
大白话就是:你编出来的可执行文件是在另一个不同的系统上运行的。所以你要用可以编译出在目标系统可运行的执行文件的编译器。比如如果你在x86上使用gcc编译出的程序,它只能在x86上运行,无法在risc-v上运行。要想编译出的程序可以在risc-v上运行,你就要使用risc-v的编译器。

GDB调试,QEMU,MAKEFILE

GDB调试这里不多阐述,因为我也不太懂,还在学习阶段,后面可能会出一两期关于gdb的博客。这里可以参考视频。这三者都是工具,网上有很多资料供大家学习。

练习

  1. 编写一个简单的打印 “hello world!” 的程序源文件:hello.c

    #include<stdio.h>void main()
    {printf("hello world!");
    }
  2. 对源文件进行编译,生成针对支持 rv32ima 指令集架构处理器的目标文件 hello.o。

    $riscv64-unknown-elf-gcc -march=rv32ima -mabi=ilp32 -c hello.c -o hello.o
    $file hello.o
    hello.o: ELF 32-bit LSB relocatable, UCB RISC-V, version 1 (SYSV), not stripped
    

因为是交叉编译,所以这里使用的是risc-v上的编译器,-march=rv32ima指定了程序是运行在risc-v32位整数(i),支持整数乘法和除法(m),原子操作(a)的CPU上,其他的扩展指令集名称如下。使用file命令就可以看出这个这个hello.o是risc-v文件。
在这里插入图片描述

  1. 查看 hello.o 的文件的文件头信息。
$riscv64-unknown-elf-readelf -h hello.o
ELF Header:Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF32Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              REL (Relocatable file)Machine:                           RISC-VVersion:                           0x1Entry point address:               0x0Start of program headers:          0 (bytes into file)Start of section headers:          10340 (bytes into file)Flags:                             0x0Size of this header:               52 (bytes)Size of program headers:           0 (bytes)Number of program headers:         0Size of section headers:           40 (bytes)Number of section headers:         21Section header string table index: 20
  1. 查看 hello.o 的 Section header table
$ riscv64-unknown-elf-readelf -S hello.o
There are 21 section headers, starting at offset 0x2864:Section Headers:[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al[ 0]                   NULL            00000000 000000 000000 00      0   0  0[ 1] .text             PROGBITS        00000000 000034 000034 00  AX  0   0  4[ 2] .rela.text        RELA            00000000 002020 000048 0c   I 18   1  4[ 3] .data             PROGBITS        00000000 000068 000000 00  WA  0   0  1[ 4] .bss              NOBITS          00000000 000068 000000 00  WA  0   0  1[ 5] .rodata           PROGBITS        00000000 000068 00000d 00   A  0   0  4[ 6] .debug_info       PROGBITS        00000000 000075 000928 00      0   0  1[ 7] .rela.debug_info  RELA            00000000 002068 000678 0c   I 18   6  4[ 8] .debug_abbrev     PROGBITS        00000000 00099d 0001ba 00      0   0  1[ 9] .debug_aranges    PROGBITS        00000000 000b57 000020 00      0   0  1[10] .rela.debug_arang RELA            00000000 0026e0 000030 0c   I 18   9  4[11] .debug_line       PROGBITS        00000000 000b77 00011d 00      0   0  1[12] .rela.debug_line  RELA            00000000 002710 000054 0c   I 18  11  4[13] .debug_str        PROGBITS        00000000 000c94 0004c3 01  MS  0   0  1[14] .comment          PROGBITS        00000000 001157 000029 01  MS  0   0  1[15] .debug_frame      PROGBITS        00000000 001180 000038 00      0   0  4[16] .rela.debug_frame RELA            00000000 002764 000048 0c   I 18  15  4[17] .riscv.attributes RISCV_ATTRIBUTE 00000000 0011b8 000026 00      0   0  1[18] .symtab           SYMTAB          00000000 0011e0 0009e0 10     19 156  4[19] .strtab           STRTAB          00000000 001bc0 00045f 00      0   0  1[20] .shstrtab         STRTAB          00000000 0027ac 0000b5 00      0   0  1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings), I (info),L (link order), O (extra OS processing required), G (group), T (TLS),C (compressed), x (unknown), o (OS specific), E (exclude),p (processor specific)
  1. 对 hello.o 反汇编,并查看 hello.c 的 C 程序源码和机器指令的对应关系。
$riscv64-unknown-elf-objdump -S hello.ohello.o:     file format elf32-littleriscvDisassembly of section .text:00000000 <main>:
#include<stdio.h>void main()
{0:   ff010113                addi    sp,sp,-164:   00112623                sw      ra,12(sp)8:   00812423                sw      s0,8(sp)c:   01010413                addi    s0,sp,16printf("hello world!");10:   000007b7                lui     a5,0x014:   00078513                mv      a0,a518:   00000097                auipc   ra,0x01c:   000080e7                jalr    ra # 18 <main+0x18>
}20:   00000013                nop24:   00c12083                lw      ra,12(sp)28:   00812403                lw      s0,8(sp)2c:   01010113                addi    sp,sp,1630:   00008067                ret
http://www.lryc.cn/news/333925.html

相关文章:

  • Web漏洞-文件上传常见验证
  • 如何在 Node.js 中使用 bcrypt 对密码进行哈希处理
  • 嵌入式学习49-单片机2
  • 汽车EDI:如何与奔驰建立EDI连接?
  • 性能分析--内存知识
  • 目标检测标签分配策略,难样本挖掘策略
  • Java | Leetcode Java题解之第16题最接近的三数之和
  • FIN和RST的区别,几种TCP连接出现RST的情况
  • 2024/4/1—力扣—删除字符使频率相同
  • Spring源码解析-容器基本实现
  • Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果
  • 蓝牙学习十(扫描)
  • (26)4.7 字符函数和字符串函数
  • 交换机与队列的简介
  • 1.docker
  • ThinkPHP审计(2) Thinkphp反序列化链5.1.X原理分析从0编写POC
  • KingbsaeES数据库分区表的详细用法
  • MySQL 索引底层探索:为什么是B+树?
  • XML HTTP传输 小结
  • 相机标定——四个坐标系介绍
  • C++:MySQL数据库的增删改(三)
  • golang - 简单实现linux上的which命令
  • 推荐一个好用的数据库映射架构
  • (013)window的Idea运行程序 Amazon java.nio.file.AccessDeniedException
  • LeetCode 1684. 统计一致字符串的数目
  • uniapp-设置UrlSchemes从外部浏览器H5打开app
  • 校园圈子小程序,大学校园圈子,三段交付,源码交付,支持二开
  • 基于kmeans的聚类微博舆情分析系统
  • 【Docker常用命令(四)】
  • 黑豹程序员-Spring Task实现定时任务