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

目标:通过这一个系列课程的学习,开发出一个简易的在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:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           RISC-V
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          10340 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         21
  Section 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.o

hello.o:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <main>:
#include<stdio.h>

void main()
{
   0:   ff010113                addi    sp,sp,-16
   4:   00112623                sw      ra,12(sp)
   8:   00812423                sw      s0,8(sp)
   c:   01010413                addi    s0,sp,16
    printf("hello world!");
  10:   000007b7                lui     a5,0x0
  14:   00078513                mv      a0,a5
  18:   00000097                auipc   ra,0x0
  1c:   000080e7                jalr    ra # 18 <main+0x18>
}
  20:   00000013                nop
  24:   00c12083                lw      ra,12(sp)
  28:   00812403                lw      s0,8(sp)
  2c:   01010113                addi    sp,sp,16
  30:   00008067                ret
  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值