ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

循序渐进学习开发RISCV-OS

2022-02-09 22:03:30  阅读:247  来源: 互联网

标签:00 RISCV 00000000 0000000000000000 headers 循序渐进 section OS hello


exercises

ch3 编译与链接

练习3-1

使⽤ gcc 编译代码并使⽤ binutils ⼯具对⽣

成的⽬标文件和可执⾏文件(ELF 格式)进⾏分析。具体要求如下:

  • 编写⼀个简单的打印 “hello world!” 的程序源文件:hello.c
#include <stdio.h>

int main(void)
{
    printf("hello world!\n");
    return 0;
}
  • 对源文件进⾏本地编译,⽣成针对⽀持 x86_64 指令集架构处理器的⽬标文件 hello.o
 gcc hello.c -c -o hello.o

补充gcc常用选项:

gcc [options] [filename]

常用选项含义
-E只做预处理
-c只编译不连接,生成目标文件".o"
-S生成汇编代码
-o file把输出生成到由file指定文件名的文件中
-g在输出的文件中加入支持调试的信息
-v显示输出详细的命令执行过程信息
  • 查看 hello.o 的文件的文件头信息。
readelf -h hell.o

信息如下:

ELF 头:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              REL (可重定位文件)
  系统架构:                          Advanced Micro Devices X86-64
  版本:                              0x1
  入口点地址:               0x0
  程序头起点:          0 (bytes into file)
  Start of section headers:          792 (bytes into file)
  标志:             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         14
  Section header string table index: 13
  • 查看 hello.o 的 Section header table。
readelf -SW hello.c

信息如下:

 There are 14 section headers, starting at offset 0x318:
 
  节头:
    [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
    [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
    [ 1] .text             PROGBITS        0000000000000000 000040 00001b 00  AX  0   0  1
    [ 2] .rela.text        RELA            0000000000000000 000258 000030 18   I 11   1  8
    [ 3] .data             PROGBITS        0000000000000000 00005b 000000 00  WA  0   0  1
    [ 4] .bss              NOBITS          0000000000000000 00005b 000000 00  WA  0   0  1
    [ 5] .rodata           PROGBITS        0000000000000000 00005b 00000d 00   A  0   0  1
    [ 6] .comment          PROGBITS        0000000000000000 000068 00002b 01  MS  0   0  1
    [ 7] .note.GNU-stack   PROGBITS        0000000000000000 000093 000000 00      0   0  1
    [ 8] .note.gnu.property NOTE            0000000000000000 000098 000020 00   A  0   0  8
    [ 9] .eh_frame         PROGBITS        0000000000000000 0000b8 000038 00   A  0   0  8
    [10] .rela.eh_frame    RELA            0000000000000000 000288 000018 18   I 11   9  8
    [11] .symtab           SYMTAB          0000000000000000 0000f0 000138 18     12  10  8
    [12] .strtab           STRTAB          0000000000000000 000228 000029 00      0   0  1
    [13] .shstrtab         STRTAB          0000000000000000 0002a0 000074 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),
    l (large), p (processor specific)
  • hello.o 反汇编,并查看 hello.c 的 C 程序源码和机器指令的对应关系。
objdump -S hello.o

反汇编:

hello.o:     文件格式 elf64-x86-64


Disassembly of section .text:

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

int main(void)
{
   0:   f3 0f 1e fa             endbr64 
   4:   55                      push   %rbp
   5:   48 89 e5                mov    %rsp,%rbp
    printf("hello world!\n");
   8:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # f <main+0xf>
   f:   e8 00 00 00 00          callq  14 <main+0x14>
    return 0;
  14:   b8 00 00 00 00          mov    $0x0,%eax
  19:   5d                      pop    %rbp
  1a:   c3                      retq   

练习3-2

如下例⼦ C 语⾔代码:

#include <stdio.h>
int global_init = 0x11111111;
const int global_const = 0x22222222;
void main()
{
    static int static_var = 0x33333333;
    static int static_var_uninit;
    int auto_var = 0x44444444;
    printf("hello world!\n");
    return;
}

请问编译为 .o 文件后,global_init, global_const, static_var, static_var_uninit, auto_var 这些变 量分别存放在那些 section ⾥,“hello world!\n” 这个字符串⼜在哪⾥?并尝试⽤⼯具查看并验证你的猜测。

  • global_init -------> .data

  • global_const -------> .data .rodata

  • static_var -------> .data

  • static_var_uninit -------> .bss

  • auto_var -------> 栈区

    使用objdump -s -x -d test.o可以得到以下信息

    SYMBOL TABLE:
    0000000000000000 l    df *ABS*  0000000000000000 test.c
    0000000000000000 l    d  .text  0000000000000000 .text
    0000000000000000 l    d  .data  0000000000000000 .data
    0000000000000000 l    d  .bss   0000000000000000 .bss
    0000000000000000 l    d  .rodata        0000000000000000 .rodata
    0000000000000000 l     O .bss   0000000000000004 static_var_uninit.2318
    0000000000000004 l     O .data  0000000000000004 static_var.2317
    0000000000000000 l    d  .note.GNU-stack        0000000000000000 .note.GNU-stack
    0000000000000000 l    d  .note.gnu.property     0000000000000000 .note.gnu.property
    0000000000000000 l    d  .eh_frame      0000000000000000 .eh_frame
    0000000000000000 l    d  .comment       0000000000000000 .comment
    0000000000000000 g     O .data  0000000000000004 global_init
    0000000000000000 g     O .rodata        0000000000000004 global_const
    0000000000000000 g     F .text  0000000000000022 main
    0000000000000000         *UND*  0000000000000000 _GLOBAL_OFFSET_TABLE_
    0000000000000000         *UND*  0000000000000000 puts
    

ch4 嵌入式开发介绍

练习4-1

熟悉交叉编译概念,使⽤ riscv gcc 编译代码并使⽤ binutils ⼯具对⽣成的⽬标文件和可执⾏文件(ELF 格式) 进⾏分析。具体要求如下:

  • 编写⼀个简单的打印"hello world!"的程序源文件hello.c
#include <stdio.h>

int main(void)
{
    printf("hello world!\n");
    return 0;
}

  • 对源文件进⾏编译,⽣成针对⽀持 rv32ima 指令集架构处理器的⽬标文件hello.o
riscv64-unknown-elf-gcc -march=rv32ima -mabi=ilp32 -c hello.c
  • 查看hello.o的文件的文件头信息。
readelf -h hello.o

信息如下:

ELF 头:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF32
  数据:                              2 补码,小端序 (little endian)
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              REL (可重定位文件)
  系统架构:                          RISC-V
  版本:                              0x1
  入口点地址:               0x0
  程序头起点:          0 (bytes into file)
  Start of section headers:          556 (bytes into file)
  标志:             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:         11
  Section header string table index: 10
  • 查看 hello.o 的 Section header table。
readelf -S hello.o

信息如下:

There are 11 section headers, starting at offset 0x22c:

节头:
  [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 000038 00  AX  0   0  4
  [ 2] .rela.text        RELA            00000000 000190 000048 0c   I  8   1  4
  [ 3] .data             PROGBITS        00000000 00006c 000000 00  WA  0   0  1
  [ 4] .bss              NOBITS          00000000 00006c 000000 00  WA  0   0  1
  [ 5] .rodata           PROGBITS        00000000 00006c 00000d 00   A  0   0  4
  [ 6] .comment          PROGBITS        00000000 000079 000029 01  MS  0   0  1
  [ 7] .riscv.attributes RISCV_ATTRIBUTE 00000000 0000a2 000026 00      0   0  1
  [ 8] .symtab           SYMTAB          00000000 0000c8 0000b0 10      9   9  4
  [ 9] .strtab           STRTAB          00000000 000178 000018 00      0   0  1
  [10] .shstrtab         STRTAB          00000000 0001d8 000054 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 程序源码和机器指令的对应关系。

    **注意:**直接使用objdump不行,因为不支持riscv架构,所以使用以下命令

    riscv64-unknown-elf-objdump -S hello.o
    

    信息如下:

    hello.o:     文件格式 elf32-littleriscv
    
    
    Disassembly of section .text:
    
    00000000 <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
      10:   000007b7                lui     a5,0x0
      14:   00078513                mv      a0,a5
      18:   00000097                auipc   ra,0x0
      1c:   000080e7                jalr    ra # 18 <main+0x18>
      20:   00000793                li      a5,0
      24:   00078513                mv      a0,a5
      28:   00c12083                lw      ra,12(sp)
      2c:   00812403                lw      s0,8(sp)
      30:   01010113                addi    sp,sp,16
      34:   00008067                ret
    

练习4-2

基于 练习 4-1 继续熟悉 qemu/gdb 等⼯具的使⽤,具体要求如下:

  • hello.c 编译成可调式版本的可执⾏程序 a.out
riscv64-unknown-elf-gcc -g -march=rv32ima -mabi=ilp32  hello.c
  • 先执⾏ qemu-riscv32 运⾏ a.out
qemu-riscv32 ./a.out

可以看到控制台输出以下内容:

hello world!
  • 使⽤ qemu-riscv32 和 gdb 调试 a.out

标签:00,RISCV,00000000,0000000000000000,headers,循序渐进,section,OS,hello
来源: https://blog.csdn.net/qq_42913442/article/details/122850401

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有