中国建设银行招聘官方网站,响水做网站,职业规划网站,企业网站建设晋升文章目录 前提嵌入式开发交叉编译GDB调试#xff0c;QEMU#xff0c;MAKEFILE练习 目标#xff1a;通过这一个系列课程的学习#xff0c;开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提
这个系列的大部分文章和知识来自于#xff1a;[完结] 循序渐进#x… 文章目录 前提嵌入式开发交叉编译GDB调试QEMUMAKEFILE练习 目标通过这一个系列课程的学习开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提
这个系列的大部分文章和知识来自于[完结] 循序渐进学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春以及相关的github地址。
在这个过程中这个系列相当于是我的学习笔记做个记录。
嵌入式开发
搞过5132单片机的同学应该能明白什么是嵌入式开发。嵌入式开发是一种系统级别的与硬件结合比较紧密的软件开发结束。
交叉编译
参与编译与运行的机器根据角色可以分为三类
构建(build)系统执行编译构建动作的计算机主机(host)系统运行build系统生成可执行程序的计算机系统目标(target)系统特别地当以上生成的可执行程序是GCC时我们用target来描述用来运行GCC生成的可执行程序的计算机系统。
那么交叉编译就是build host ! target 大白话就是你编出来的可执行文件是在另一个不同的系统上运行的。所以你要用可以编译出在目标系统可运行的执行文件的编译器。比如如果你在x86上使用gcc编译出的程序它只能在x86上运行无法在risc-v上运行。要想编译出的程序可以在risc-v上运行你就要使用risc-v的编译器。
GDB调试QEMUMAKEFILE
GDB调试这里不多阐述因为我也不太懂还在学习阶段后面可能会出一两期关于gdb的博客。这里可以参考视频。这三者都是工具网上有很多资料供大家学习。
练习 编写一个简单的打印 “hello world” 的程序源文件hello.c #includestdio.hvoid main()
{printf(hello world!);
} 对源文件进行编译生成针对支持 rv32ima 指令集架构处理器的目标文件 hello.o。 $riscv64-unknown-elf-gcc -marchrv32ima -mabiilp32 -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上的编译器-marchrv32ima指定了程序是运行在risc-v32位整数(i)支持整数乘法和除法(m)原子操作(a)的CPU上其他的扩展指令集名称如下。使用file命令就可以看出这个这个hello.o是risc-v文件。
查看 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: 2s 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查看 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)对 hello.o 反汇编并查看 hello.c 的 C 程序源码和机器指令的对应关系。
$riscv64-unknown-elf-objdump -S hello.ohello.o: file format elf32-littleriscvDisassembly of section .text:00000000 main:
#includestdio.hvoid 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 main0x18
}20: 00000013 nop24: 00c12083 lw ra,12(sp)28: 00812403 lw s0,8(sp)2c: 01010113 addi sp,sp,1630: 00008067 ret