• linker script 连接脚本


    [root@centos7 aarch64-bare-metal-qemu]# gcc -c test64.c -o test64.o
    [root@centos7 aarch64-bare-metal-qemu]# as -c startup64.s -o startup64.o
    [root@centos7 aarch64-bare-metal-qemu]# ld -Ttest64.ld test64.o startup64.o -o test64.elf
    [root@centos7
    [root@centos7 aarch64-bare-metal-qemu]# qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -kernel test64.elf
    Hello world!

    [root@centos7 aarch64-bare-metal-qemu]# objdump -s -d test64.o > test64.txt
    [root@centos7 aarch64-bare-metal-qemu]# objdump -s -d startup64.o > startup64.txt
    [root@centos7 aarch64-bare-metal-qemu]# objdump -s -d test64.elf > test64.elf.txt
    [root@centos7 aarch64-bare-metal-qemu]# cat test64.txt
    
    test64.o:     file format elf64-littleaarch64
    
    Contents of section .text:
     0000 ff4300d1 e00700f9 08000014 0020a1d2  .C........... ..
     0010 e10740f9 21004039 010000b9 e00740f9  ..@.!.@9......@.
     0020 00040091 e00700f9 e00740f9 00004039  ..........@...@9
     0030 1f001f6b c1feff54 ff430091 c0035fd6  ...k...T.C...._.
     0040 fd7bbfa9 fd030091 00000090 00000091  .{..............
     0050 00000094 fd7bc1a8 c0035fd6           .....{...._.    
    Contents of section .rodata:
     0000 00000009 00000000 48656c6c 6f20776f  ........Hello wo
     0010 726c6421 0a00                        rld!..          
    Contents of section .comment:
     0000 00474343 3a202847 4e552920 342e382e  .GCC: (GNU) 4.8.
     0010 35203230 31353036 32332028 52656420  5 20150623 (Red 
     0020 48617420 342e382e 352d3434 2900      Hat 4.8.5-44).  
    Contents of section .eh_frame:
     0000 10000000 00000000 017a5200 04781e01  .........zR..x..
     0010 1b0c1f00 14000000 18000000 00000000  ................
     0020 40000000 00410e10 4e0e0000 20000000  @....A..N... ...
     0030 30000000 00000000 1c000000 00410e10  0............A..
     0040 9d029e01 410d1d44 dedd0c1f 00000000  ....A..D........
    
    Disassembly of section .text:
    
    0000000000000000 <print_uart0>:
       0:   d10043ff        sub     sp, sp, #0x10
       4:   f90007e0        str     x0, [sp,#8]
       8:   14000008        b       28 <print_uart0+0x28>
       c:   d2a12000        mov     x0, #0x9000000                  // #150994944
      10:   f94007e1        ldr     x1, [sp,#8]
      14:   39400021        ldrb    w1, [x1]
      18:   b9000001        str     w1, [x0]
      1c:   f94007e0        ldr     x0, [sp,#8]
      20:   91000400        add     x0, x0, #0x1
      24:   f90007e0        str     x0, [sp,#8]
      28:   f94007e0        ldr     x0, [sp,#8]
      2c:   39400000        ldrb    w0, [x0]
      30:   6b1f001f        cmp     w0, wzr
      34:   54fffec1        b.ne    c <print_uart0+0xc>
      38:   910043ff        add     sp, sp, #0x10
      3c:   d65f03c0        ret
    
    0000000000000040 <c_entry>:
      40:   a9bf7bfd        stp     x29, x30, [sp,#-16]!
      44:   910003fd        mov     x29, sp
      48:   90000000        adrp    x0, 0 <print_uart0>
      4c:   91000000        add     x0, x0, #0x0
      50:   94000000        bl      0 <print_uart0>
      54:   a8c17bfd        ldp     x29, x30, [sp],#16
      58:   d65f03c0        ret
    [root@centos7 aarch64-bare-metal-qemu]# cat startup64.txt 
    
    startup64.o:     file format elf64-littleaarch64
    
    Contents of section .text:
     0000 9e000058 df030091 00000094 00000014  ...X............
     0010 00000000 00000000                    ........        
    
    Disassembly of section .text:
    
    0000000000000000 <_Reset>:
       0:   5800009e        ldr     x30, 10 <_Reset+0x10>
       4:   910003df        mov     sp, x30
       8:   94000000        bl      0 <c_entry>
       c:   14000000        b       c <_Reset+0xc>
            ...
    [root@centos7 aarch64-bare-metal-qemu]# cat test64.elf.txt
    
    test64.elf:     file format elf64-littleaarch64
    
    Contents of section .startup:
     40000000 9e000058 df030091 14000094 00000014  ...X............
     40000010 e8100040 00000000                    ...@....        
    Contents of section .text:
     40000018 ff4300d1 e00700f9 08000014 0020a1d2  .C........... ..
     40000028 e10740f9 21004039 010000b9 e00740f9  ..@.!.@9......@.
     40000038 00040091 e00700f9 e00740f9 00004039  ..........@...@9
     40000048 1f001f6b c1feff54 ff430091 c0035fd6  ...k...T.C...._.
     40000058 fd7bbfa9 fd030091 00000090 00000291  .{..............
     40000068 ecffff97 fd7bc1a8 c0035fd6           .....{...._.    
    Contents of section .rodata:
     40000078 00000009 00000000 48656c6c 6f20776f  ........Hello wo
     40000088 726c6421 0a00                        rld!..          
    Contents of section .eh_frame:
     40000090 14000000 00000000 017a5200 04781e01  .........zR..x..
     400000a0 1b0c1f00 00000000 14000000 1c000000  ................
     400000b0 68ffffff 40000000 00410e10 4e0e0000  h...@....A..N...
     400000c0 24000000 34000000 90ffffff 1c000000  $...4...........
     400000d0 00410e10 9d029e01 410d1d44 dedd0c1f  .A......A..D....
     400000e0 00000000 00000000                    ........        
    Contents of section .comment:
     0000 4743433a 2028474e 55292034 2e382e35  GCC: (GNU) 4.8.5
     0010 20323031 35303632 33202852 65642048   20150623 (Red H
     0020 61742034 2e382e35 2d343429 00        at 4.8.5-44).   
    
    Disassembly of section .startup:
    
    0000000040000000 <_Reset>:
        40000000:   5800009e        ldr     x30, 40000010 <_Reset+0x10>
        40000004:   910003df        mov     sp, x30
        40000008:   94000014        bl      40000058 <c_entry>
        4000000c:   14000000        b       4000000c <_Reset+0xc>
        40000010:   400010e8        .word   0x400010e8
        40000014:   00000000        .word   0x00000000
    
    Disassembly of section .text:
    
    0000000040000018 <print_uart0>:
        40000018:   d10043ff        sub     sp, sp, #0x10
        4000001c:   f90007e0        str     x0, [sp,#8]
        40000020:   14000008        b       40000040 <print_uart0+0x28>
        40000024:   d2a12000        mov     x0, #0x9000000                  // #150994944
        40000028:   f94007e1        ldr     x1, [sp,#8]
        4000002c:   39400021        ldrb    w1, [x1]
        40000030:   b9000001        str     w1, [x0]
        40000034:   f94007e0        ldr     x0, [sp,#8]
        40000038:   91000400        add     x0, x0, #0x1
        4000003c:   f90007e0        str     x0, [sp,#8]
        40000040:   f94007e0        ldr     x0, [sp,#8]
        40000044:   39400000        ldrb    w0, [x0]
        40000048:   6b1f001f        cmp     w0, wzr
        4000004c:   54fffec1        b.ne    40000024 <print_uart0+0xc>
        40000050:   910043ff        add     sp, sp, #0x10
        40000054:   d65f03c0        ret
    
    0000000040000058 <c_entry>:
        40000058:   a9bf7bfd        stp     x29, x30, [sp,#-16]!
        4000005c:   910003fd        mov     x29, sp
        40000060:   90000000        adrp    x0, 40000000 <_Reset>
        40000064:   91020000        add     x0, x0, #0x80
        40000068:   97ffffec        bl      40000018 <print_uart0>
        4000006c:   a8c17bfd        ldp     x29, x30, [sp],#16
        40000070:   d65f03c0        ret

    链接脚本和栈指针

    C函数栈指针

     链接地址

    1. The address to load the program to should be changed too. '0x10000' is not valid RAM or ROM address for -M virt. According to virt.c, '0x40000000' is OK to use. So my linker script is modified and named test64.ld

    0x40000000

    [root@centos7 aarch64-bare-metal-qemu]# cat test64.ld 
    ENTRY(_Reset)
    SECTIONS
    {
            . = 0x40000000;
            .startup . : { startup64.o(.text) }
            .text : { *(.text) }
            .data : { *(.data) }
            .bss : { *(.bss COMMON) }
            . = ALIGN(8);
            . = . + 0x1000; /* 4kB of stack memory */
            stack_top = .;
    }
    Disassembly of section .startup:
    
    0000000040000000 <_Reset>:
        40000000:   5800009e        ldr     x30, 40000010 <_Reset+0x10>
        40000004:   910003df        mov     sp, x30
        40000008:   94000014        bl      40000058 <c_entry>
        4000000c:   14000000        b       4000000c <_Reset+0xc>
        40000010:   400010e8        .word   0x400010e8
        40000014:   00000000        .word   0x00000000
    
    Disassembly of section .text:
    
    0000000040000018 <print_uart0>:
        40000018:   d10043ff        sub     sp, sp, #0x10
        4000001c:   f90007e0        str     x0, [sp,#8]
        40000020:   14000008        b       40000040 <print_uart0+0x28>
        40000024:   d2a12000        mov     x0, #0x9000000                  // #150994944
        40000028:   f94007e1        ldr     x1, [sp,#8]
        4000002c:   39400021        ldrb    w1, [x1]
        40000030:   b9000001        str     w1, [x0]
        40000034:   f94007e0        ldr     x0, [sp,#8]
        40000038:   91000400        add     x0, x0, #0x1
        4000003c:   f90007e0        str     x0, [sp,#8]
        40000040:   f94007e0        ldr     x0, [sp,#8]
        40000044:   39400000        ldrb    w0, [x0]
        40000048:   6b1f001f        cmp     w0, wzr
        4000004c:   54fffec1        b.ne    40000024 <print_uart0+0xc>
        40000050:   910043ff        add     sp, sp, #0x10
        40000054:   d65f03c0        ret
    
    0000000040000058 <c_entry>:
        40000058:   a9bf7bfd        stp     x29, x30, [sp,#-16]!
        4000005c:   910003fd        mov     x29, sp
        40000060:   90000000        adrp    x0, 40000000 <_Reset>
        40000064:   91020000        add     x0, x0, #0x80
        40000068:   97ffffec        bl      40000018 <print_uart0>
        4000006c:   a8c17bfd        ldp     x29, x30, [sp],#16
        40000070:   d65f03c0        ret

    链接地址0x10000

    [root@centos7 aarch64-bare-metal-qemu]# cat test64.ld 
    ENTRY(_Reset)
    SECTIONS
    {
            . = 0x10000;
            .startup . : { startup64.o(.text) }
            .text : { *(.text) }
            .data : { *(.data) }
            .bss : { *(.bss COMMON) }
            . = ALIGN(8);
            . = . + 0x1000; /* 4kB of stack memory */
            stack_top = .;
    }
    [root@centos7 aarch64-bare-metal-qemu]# ld -Ttest64.ld test64.o startup64.o -o test64.elf
    [root@centos7 aarch64-bare-metal-qemu]# objdump -s -d test64.elf > test64.elf.txt2
    [root@centos7 aarch64-bare-metal-qemu]# cat test64.elf.txt2
    [root@centos7 aarch64-bare-metal-qemu]# cat test64.elf.txt2
    
    test64.elf:     file format elf64-littleaarch64
    
    Contents of section .startup:
     10000 9e000058 df030091 14000094 00000014  ...X............
     10010 e8100100 00000000                    ........        
    Contents of section .text:
     10018 ff4300d1 e00700f9 08000014 0020a1d2  .C........... ..
     10028 e10740f9 21004039 010000b9 e00740f9  ..@.!.@9......@.
     10038 00040091 e00700f9 e00740f9 00004039  ..........@...@9
     10048 1f001f6b c1feff54 ff430091 c0035fd6  ...k...T.C...._.
     10058 fd7bbfa9 fd030091 00000090 00000291  .{..............
     10068 ecffff97 fd7bc1a8 c0035fd6           .....{...._.    
    Contents of section .rodata:
     10078 00000009 00000000 48656c6c 6f20776f  ........Hello wo
     10088 726c6421 0a00                        rld!..          
    Contents of section .eh_frame:
     10090 14000000 00000000 017a5200 04781e01  .........zR..x..
     100a0 1b0c1f00 00000000 14000000 1c000000  ................
     100b0 68ffffff 40000000 00410e10 4e0e0000  h...@....A..N...
     100c0 24000000 34000000 90ffffff 1c000000  $...4...........
     100d0 00410e10 9d029e01 410d1d44 dedd0c1f  .A......A..D....
     100e0 00000000 00000000                    ........        
    Contents of section .comment:
     0000 4743433a 2028474e 55292034 2e382e35  GCC: (GNU) 4.8.5
     0010 20323031 35303632 33202852 65642048   20150623 (Red H
     0020 61742034 2e382e35 2d343429 00        at 4.8.5-44).   
    
    Disassembly of section .startup:
    
    0000000000010000 <_Reset>:
       10000:       5800009e        ldr     x30, 10010 <_Reset+0x10>
       10004:       910003df        mov     sp, x30
       10008:       94000014        bl      10058 <c_entry>
       1000c:       14000000        b       1000c <_Reset+0xc>
       10010:       000110e8        .word   0x000110e8
       10014:       00000000        .word   0x00000000
    
    Disassembly of section .text:
    
    0000000000010018 <print_uart0>:
       10018:       d10043ff        sub     sp, sp, #0x10
       1001c:       f90007e0        str     x0, [sp,#8]
       10020:       14000008        b       10040 <print_uart0+0x28>
       10024:       d2a12000        mov     x0, #0x9000000                  // #150994944
       10028:       f94007e1        ldr     x1, [sp,#8]
       1002c:       39400021        ldrb    w1, [x1]
       10030:       b9000001        str     w1, [x0]
       10034:       f94007e0        ldr     x0, [sp,#8]
       10038:       91000400        add     x0, x0, #0x1
       1003c:       f90007e0        str     x0, [sp,#8]
       10040:       f94007e0        ldr     x0, [sp,#8]
       10044:       39400000        ldrb    w0, [x0]
       10048:       6b1f001f        cmp     w0, wzr
       1004c:       54fffec1        b.ne    10024 <print_uart0+0xc>
       10050:       910043ff        add     sp, sp, #0x10
       10054:       d65f03c0        ret
    
    0000000000010058 <c_entry>:
       10058:       a9bf7bfd        stp     x29, x30, [sp,#-16]!
       1005c:       910003fd        mov     x29, sp
       10060:       90000000        adrp    x0, 10000 <_Reset>
       10064:       91020000        add     x0, x0, #0x80
       10068:       97ffffec        bl      10018 <print_uart0>
       1006c:       a8c17bfd        ldp     x29, x30, [sp],#16
       10070:       d65f03c0        ret

    没有helloworld 输出

    [root@centos7 aarch64-bare-metal-qemu]# qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -kernel test64.elf
    Killed

    heap

    [root@centos7 aarch64-bare-metal-qemu]# cat test64.ld 
    ENTRY(_Reset)
    SECTIONS
    {
            . = 0x40000000;
            .startup . : { startup64.o(.text) }
            .text : { *(.text) }
            .data : { *(.data) }
            .bss : { *(.bss COMMON) }
            . = ALIGN(8);
            heap_low = .; /* for _sbrk */
            . = . + 0x10000; /* 64kB of heap memory */
            heap_top = .; /* for _sbrk */
            . = . + 0x1000; /* 4kB of stack memory */
            stack_top = .;
    }
    [root@centos7 aarch64-bare-metal-qemu]# ld -Ttest64.ld test64.o startup64.o -o test64.elf
    [root@centos7 aarch64-bare-metal-qemu]# ld -Ttest64.ld test64.o startup64.o -o test64.elf
    [root@centos7 aarch64-bare-metal-qemu]# objdump -s -d test64.elf > test64.elf.txt3
    [root@centos7 aarch64-bare-metal-qemu]# cat test64.elf.txt3
    
    test64.elf:     file format elf64-littleaarch64
    
    Contents of section .startup:
     40000000 9e000058 df030091 14000094 00000014  ...X............
     40000010 e8100140 00000000                    ...@....        
    Contents of section .text:
     40000018 ff4300d1 e00700f9 08000014 0020a1d2  .C........... ..
     40000028 e10740f9 21004039 010000b9 e00740f9  ..@.!.@9......@.
     40000038 00040091 e00700f9 e00740f9 00004039  ..........@...@9
     40000048 1f001f6b c1feff54 ff430091 c0035fd6  ...k...T.C...._.
     40000058 fd7bbfa9 fd030091 00000090 00000291  .{..............
     40000068 ecffff97 fd7bc1a8 c0035fd6           .....{...._.    
    Contents of section .rodata:
     40000078 00000009 00000000 48656c6c 6f20776f  ........Hello wo
     40000088 726c6421 0a00                        rld!..          
    Contents of section .eh_frame:
     40000090 14000000 00000000 017a5200 04781e01  .........zR..x..
     400000a0 1b0c1f00 00000000 14000000 1c000000  ................
     400000b0 68ffffff 40000000 00410e10 4e0e0000  h...@....A..N...
     400000c0 24000000 34000000 90ffffff 1c000000  $...4...........
     400000d0 00410e10 9d029e01 410d1d44 dedd0c1f  .A......A..D....
     400000e0 00000000 00000000                    ........        
    Contents of section .comment:
     0000 4743433a 2028474e 55292034 2e382e35  GCC: (GNU) 4.8.5
     0010 20323031 35303632 33202852 65642048   20150623 (Red H
     0020 61742034 2e382e35 2d343429 00        at 4.8.5-44).   
    
    Disassembly of section .startup:
    
    0000000040000000 <_Reset>:
        40000000:   5800009e        ldr     x30, 40000010 <_Reset+0x10>
        40000004:   910003df        mov     sp, x30
        40000008:   94000014        bl      40000058 <c_entry>
        4000000c:   14000000        b       4000000c <_Reset+0xc>
        40000010:   400110e8        .word   0x400110e8
        40000014:   00000000        .word   0x00000000
    
    Disassembly of section .text:
    
    0000000040000018 <print_uart0>:
        40000018:   d10043ff        sub     sp, sp, #0x10
        4000001c:   f90007e0        str     x0, [sp,#8]
        40000020:   14000008        b       40000040 <print_uart0+0x28>
        40000024:   d2a12000        mov     x0, #0x9000000                  // #150994944
        40000028:   f94007e1        ldr     x1, [sp,#8]
        4000002c:   39400021        ldrb    w1, [x1]
        40000030:   b9000001        str     w1, [x0]
        40000034:   f94007e0        ldr     x0, [sp,#8]
        40000038:   91000400        add     x0, x0, #0x1
        4000003c:   f90007e0        str     x0, [sp,#8]
        40000040:   f94007e0        ldr     x0, [sp,#8]
        40000044:   39400000        ldrb    w0, [x0]
        40000048:   6b1f001f        cmp     w0, wzr
        4000004c:   54fffec1        b.ne    40000024 <print_uart0+0xc>
        40000050:   910043ff        add     sp, sp, #0x10
        40000054:   d65f03c0        ret
    
    0000000040000058 <c_entry>:
        40000058:   a9bf7bfd        stp     x29, x30, [sp,#-16]!
        4000005c:   910003fd        mov     x29, sp
        40000060:   90000000        adrp    x0, 40000000 <_Reset>
        40000064:   91020000        add     x0, x0, #0x80
        40000068:   97ffffec        bl      40000018 <print_uart0>
        4000006c:   a8c17bfd        ldp     x29, x30, [sp],#16
        40000070:   d65f03c0        ret

    链接脚本定义堆

    [root@centos7 aarch64-bare-metal-qemu]# gcc -c test64.c -o test64.o   -nostdlib
    test64.c: In function ‘_sbrk’:
    test64.c:40:2: warning: passing argument 1 of ‘print_pointer’ makes pointer from integer without a cast [enabled by default]
      print_pointer(heap_low);
      ^
    test64.c:12:6: note: expected ‘const char *’ but argument is of type ‘charvoid print_pointer(const char *s) {
          ^
    test64.c:41:2: warning: passing argument 1 of ‘print_pointer’ makes pointer from integer without a cast [enabled by default]
      print_pointer(heap_top);
      ^
    test64.c:12:6: note: expected ‘const char *’ but argument is of type ‘charvoid print_pointer(const char *s) {
          ^
    test64.c:51:9: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
      return (caddr_t) prev_heap_end;
             ^
    [root@centos7 aarch64-bare-metal-qemu]# as -c startup64.s -o startup64.o
    [root@centos7 aarch64-bare-metal-qemu]# ld -Ttest64.ld test64.o startup64.o -o test64.elf
    [root@centos7 aarch64-bare-metal-qemu]# qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -kernel test64.elf
    Hello world!
    0000
    0000
    Killed
    [root@centos7 aarch64-bare-metal-qemu]# ls
    ans  ans.o  ans.s  hello  hello.o  hello.txt  libc.s  LICENSE  Makefile  README.md  startup64.o  startup64.s  startup64.txt  sys  sys.o  sys.s  test64.c  test64.elf  test64.elf.txt  test64.elf.txt2  test64.elf.txt3  test64.ld  test64.o  test64.txt
    [root@centos7 aarch64-bare-metal-qemu]# cat test64.ld 
    ENTRY(_Reset)
    SECTIONS
    {
            . = 0x40000000;
            .startup . : { startup64.o(.text) }
            .text : { *(.text) }
            .data : { *(.data) }
            .bss : { *(.bss COMMON) }
            . = ALIGN(8);
            heap_low = .; /* for _sbrk */
            . = . + 0x10000; /* 64kB of heap memory */
            heap_top = .; /* for _sbrk */
            . = . + 0x1000; /* 4kB of stack memory */
            stack_top = .;
    }
    volatile unsigned int * const UART0DR = (unsigned int *) 0x09000000;
     
    typedef  unsigned int caddr_t;
    caddr_t _sbrk(int incr) ;
    
    void print_uart0(const char *s) {
        while(*s != '\0') {                 /* Loop until end of string */
             *UART0DR = (unsigned int)(*s); /* Transmit char */
              s++;                          /* Next char */
        }
    }
    void print_pointer(const char *s) {
         int new_value[4]; 
         char buf_temp[4]; 
         int temp,x; 
         for (x = 0; x < 4; x++) 
         { 
             new_value[x] = temp % 10;
             temp = temp / 10;
             buf_temp[x] = new_value[x] +48;
             *UART0DR = (unsigned int)(buf_temp[x]); /* Transmit char */
         }
             *UART0DR = '\n'; /* Transmit char */
    }
     
    void c_entry() {
         print_uart0("Hello world!\n");
         _sbrk(16);
    }
    char *heap_end = 0;
    
    caddr_t _sbrk(int incr) {
     extern char heap_low; /* Defined by the linker */
     extern char heap_top; /* Defined by the linker */
     char *prev_heap_end;
     
     if (heap_end == 0) {
      heap_end = &heap_low;
     }
     print_pointer(heap_low);
     print_pointer(heap_top);
    
     prev_heap_end = heap_end;
     
     if (heap_end + incr > &heap_top) {
      /* Heap and stack collision */
      return (caddr_t)0;
     }
     
     heap_end += incr;
     return (caddr_t) prev_heap_end;
     }

    C代码中如何使用链接脚本中定义的变量

     SECTIONS
    {
           .....
            . = ALIGN(4);
            .rodata : { *(.rodata) }
    
            . = ALIGN(4);
            .data : { *(.data) }
    
            . = ALIGN(4);
            .got : { *(.got) }
    
            . = ALIGN(4);
            __bss_start = .;
            .bss : { *(.bss) }
            _end = .;
    }
    

    其中__bss_start, _end 表示BSS段的起始、终止地址。
    我们想对这段空间清零时,
    1.在汇编代码中,可以直接引用__bss_start,  _end,比如:

    ldr r0, =__bss_start
    ldr r1, =_end

    在C代码中,我们不能直接引用它们,要这样做:

    void clean_bss(void)
    {
        extern int __bss_start, _end;
        int *p = &__bss_start;
        
        for (; p < &_end; p++)
            *p = 0;
    }

    _bss_start, _end不是表示某个值吗?在C代码中为什么要使用取址符号 & ?

    原因:
    在C代码中,这样的语句:

    int foo = 1000;

    会导致2件事情发生:
    1. 在代码中,留出4字节的空间,保存数值1000
    2.在C语言的symbole talbe,即符号表中,有一个名为foo的项,它里面存有那4字节空间的地址。

    我们执行 foo = 1时,会先去符号表中找到foo对应的地址,然后把数值1填到那个地址对应的内存;
    我们执行 int *a = &foo时,会直接把符号表中foo的地址,写给a。
     在链接脚本中,假设

    __bss_start = 1000

    __bss_start并不是一个变量,它只是一个值,并不需要在内存中留出一段空间来保存它;
    在C语言中,符号表中会有一个名为__bss_start的项,这个项目中的值(地址值)是1000;
    注意,这个1000并没有实际存在的内存。

    所以:在C语言中,要去使用链接脚本中定义的值时,应该这样做:

    extern int __bss_start;
    int val = &__bss_start;

    使用取址符号&去得到它在符号表中的值。

    [root@centos7 aarch64-bare-metal-qemu]# vim test64.c
    volatile unsigned int * const UART0DR = (unsigned int *) 0x09000000;
    
    typedef  unsigned int caddr_t;
    caddr_t _sbrk(int incr) ;
    
    void print_uart0(const char *s) {
        while(*s != '\0') {                 /* Loop until end of string */
             *UART0DR = (unsigned int)(*s); /* Transmit char */
              s++;                          /* Next char */
        }
    }
    void print_pointer(int pointer) {
         int new_value[4];
         char buf_temp[4];
         int temp,x;
         temp = pointer;
         for (x = 0; x < 4; x++)
         {
             new_value[x] = temp % 10;
             temp = temp / 10;
             buf_temp[x] = new_value[x] +48;
             *UART0DR = (unsigned int)(buf_temp[x]); /* Transmit char */  从低到高输出,反了
         }
             *UART0DR = '\n'; /* Transmit char */
    }
    
    void c_entry() {
         print_uart0("Hello world!\n");
         _sbrk(16);
    }
    char *heap_end = 0;
    
    caddr_t _sbrk(int incr) {
     extern int heap_low; /* Defined by the linker */
     extern int heap_top; /* Defined by the linker */
     char *prev_heap_end;
    
     if (heap_end == 0) {
      heap_end = &heap_low;
     }
     print_pointer(&heap_low);
     print_pointer(&heap_top);
    
     prev_heap_end = heap_end;
    
     if (heap_end + incr > &heap_top) {
      /* Heap and stack collision */
      return (caddr_t)0;
     }
    
     heap_end += incr;
     return (caddr_t) prev_heap_end;
     }
    [root@centos7 aarch64-bare-metal-qemu]# qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -kernel test64.elf
    Hello world!
    4452 
    0808
    Killed
    [root@centos7 aarch64-bare-metal-qemu]# objdump -s -d test64.elf > test64.elf.txt3
    [root@centos7 aarch64-bare-metal-qemu]# cat test64.elf.txt3
    
    test64.elf:     file format elf64-littleaarch64
    
    Contents of section .startup:
     40000000 9e000058 df030091 4d000094 00000014  ...X....M.......
     40000010 d0120140 00000000                    ...@....        
    Contents of section .text:
     40000018 ff4300d1 e00700f9 08000014 0020a1d2  .C........... ..
     40000028 e10740f9 21004039 010000b9 e00740f9  ..@.!.@9......@.
     40000038 00040091 e00700f9 e00740f9 00004039  ..........@...@9
     40000048 1f001f6b c1feff54 ff430091 c0035fd6  ...k...T.C...._.
     40000058 ff0301d1 e00700f9 e00740f9 e03f00b9  ..........@..?..
     40000068 ff3b00b9 2c000014 e13f40b9 40018052  .;..,....?@.@..R
     40000078 220cc01a e003022a 00741e53 0000020b  "......*.t.S....
     40000088 00781f53 2100004b e2630091 e03b80b9  .x.S!..K.c...;..
     40000098 00f47ed3 4000008b 010000b9 e13f40b9  ..~.@........?@.
     400000a8 e0cc8c52 c0ccac72 207c209b 00fc60d3  ...R...r | ...`.
     400000b8 027c0213 207c1f13 4000004b e03f00b9  .|.. |..@..K.?..
     400000c8 e1630091 e03b80b9 00f47ed3 2000008b  .c...;....~. ...
     400000d8 000040b9 001c0053 00c00011 011c0053  ..@....S.......S
     400000e8 e03b80b9 e2030191 4000008b 01001d38  .;......@......8
     400000f8 0020a1d2 e13b80b9 e2030191 4100018b  . ...;......A...
     40000108 21005d38 010000b9 e03b40b9 00040011  !.]8.....;@.....
     40000118 e03b00b9 e03b40b9 1f1c0071 6dfaff54  .;...;@....qm..T
     40000128 0020a1d2 41018052 010000b9 ff030191  . ..A..R........
     40000138 c0035fd6 fd7bbfa9 fd030091 00000090  .._..{..........
     40000148 00800891 b3ffff97 00028052 03000094  ...........R....
     40000158 fd7bc1a8 c0035fd6 fd7bbda9 fd030091  .{...._..{......
     40000168 a01f00b9 00000090 00200b91 000040f9  ......... ....@.
     40000178 1f001feb c1000054 00000090 00200b91  .......T..... ..
     40000188 01000090 21400b91 010000f9 00000090  ....!@..........
     40000198 00400b91 afffff97 80000090 00400b91  .@...........@..
     400001a8 acffff97 00000090 00200b91 000040f9  ......... ....@.
     400001b8 a01700f9 00000090 00200b91 010040f9  ......... ....@.
     400001c8 a01f80b9 2100008b 80000090 00400b91  ....!........@..
     400001d8 3f0000eb 69000054 00008052 0a000014  ?...i..T...R....
     400001e8 00000090 00200b91 010040f9 a01f80b9  ..... ....@.....
     400001f8 2100008b 00000090 00200b91 010000f9  !........ ......
     40000208 a01740f9 fd7bc3a8 c0035fd6           ..@..{...._.    
    Contents of section .rodata:
     40000218 00000009 00000000 48656c6c 6f20776f  ........Hello wo
     40000228 726c6421 0a00                        rld!..          
    Contents of section .eh_frame:
     40000230 14000000 00000000 017a5200 04781e01  .........zR..x..
     40000240 1b0c1f00 00000000 14000000 1c000000  ................
     40000250 c8fdffff 40000000 00410e10 4e0e0000  ....@....A..N...
     40000260 14000000 34000000 f0fdffff e4000000  ....4...........
     40000270 00410e40 770e0000 24000000 4c000000  .A.@w...$...L...
     40000280 bcfeffff 24000000 00410e10 9d029e01  ....$....A......
     40000290 410d1d46 dedd0c1f 00000000 00000000  A..F............
     400002a0 24000000 74000000 b8feffff b4000000  $...t...........
     400002b0 00410e30 9d069e05 410d1d6a dedd0c1f  .A.0....A..j....
     400002c0 00000000 00000000                    ........        
    Contents of section .comment:
     0000 4743433a 2028474e 55292034 2e382e35  GCC: (GNU) 4.8.5
     0010 20323031 35303632 33202852 65642048   20150623 (Red H
     0020 61742034 2e382e35 2d343429 00        at 4.8.5-44).   
    
    Disassembly of section .startup:
    
    0000000040000000 <_Reset>:
        40000000:   5800009e        ldr     x30, 40000010 <_Reset+0x10>
        40000004:   910003df        mov     sp, x30
        40000008:   9400004d        bl      4000013c <c_entry>
        4000000c:   14000000        b       4000000c <_Reset+0xc>
        40000010:   400112d0        .word   0x400112d0
        40000014:   00000000        .word   0x00000000
    
    Disassembly of section .text:
    
    0000000040000018 <print_uart0>:
        40000018:   d10043ff        sub     sp, sp, #0x10
        4000001c:   f90007e0        str     x0, [sp,#8]
        40000020:   14000008        b       40000040 <print_uart0+0x28>
        40000024:   d2a12000        mov     x0, #0x9000000                  // #150994944
        40000028:   f94007e1        ldr     x1, [sp,#8]
        4000002c:   39400021        ldrb    w1, [x1]
        40000030:   b9000001        str     w1, [x0]
        40000034:   f94007e0        ldr     x0, [sp,#8]
        40000038:   91000400        add     x0, x0, #0x1
        4000003c:   f90007e0        str     x0, [sp,#8]
        40000040:   f94007e0        ldr     x0, [sp,#8]
        40000044:   39400000        ldrb    w0, [x0]
        40000048:   6b1f001f        cmp     w0, wzr
        4000004c:   54fffec1        b.ne    40000024 <print_uart0+0xc>
        40000050:   910043ff        add     sp, sp, #0x10
        40000054:   d65f03c0        ret
    
    0000000040000058 <print_pointer>:
        40000058:   d10103ff        sub     sp, sp, #0x40
        4000005c:   f90007e0        str     x0, [sp,#8]
        40000060:   f94007e0        ldr     x0, [sp,#8]
        40000064:   b9003fe0        str     w0, [sp,#60]
        40000068:   b9003bff        str     wzr, [sp,#56]
        4000006c:   1400002c        b       4000011c <print_pointer+0xc4>
        40000070:   b9403fe1        ldr     w1, [sp,#60]
        40000074:   52800140        mov     w0, #0xa                        // #10
        40000078:   1ac00c22        sdiv    w2, w1, w0
        4000007c:   2a0203e0        mov     w0, w2
        40000080:   531e7400        lsl     w0, w0, #2
        40000084:   0b020000        add     w0, w0, w2
        40000088:   531f7800        lsl     w0, w0, #1
        4000008c:   4b000021        sub     w1, w1, w0
        40000090:   910063e2        add     x2, sp, #0x18
        40000094:   b9803be0        ldrsw   x0, [sp,#56]
        40000098:   d37ef400        lsl     x0, x0, #2
        4000009c:   8b000040        add     x0, x2, x0
        400000a0:   b9000001        str     w1, [x0]
        400000a4:   b9403fe1        ldr     w1, [sp,#60]
        400000a8:   528ccce0        mov     w0, #0x6667                     // #26215
        400000ac:   72acccc0        movk    w0, #0x6666, lsl #16
        400000b0:   9b207c20        smull   x0, w1, w0
        400000b4:   d360fc00        lsr     x0, x0, #32
        400000b8:   13027c02        asr     w2, w0, #2
        400000bc:   131f7c20        asr     w0, w1, #31
        400000c0:   4b000040        sub     w0, w2, w0
        400000c4:   b9003fe0        str     w0, [sp,#60]
        400000c8:   910063e1        add     x1, sp, #0x18
        400000cc:   b9803be0        ldrsw   x0, [sp,#56]
        400000d0:   d37ef400        lsl     x0, x0, #2
        400000d4:   8b000020        add     x0, x1, x0
        400000d8:   b9400000        ldr     w0, [x0]
        400000dc:   53001c00        uxtb    w0, w0
        400000e0:   1100c000        add     w0, w0, #0x30
        400000e4:   53001c01        uxtb    w1, w0
        400000e8:   b9803be0        ldrsw   x0, [sp,#56]
        400000ec:   910103e2        add     x2, sp, #0x40
        400000f0:   8b000040        add     x0, x2, x0
        400000f4:   381d0001        sturb   w1, [x0,#-48]
        400000f8:   d2a12000        mov     x0, #0x9000000                  // #150994944
        400000fc:   b9803be1        ldrsw   x1, [sp,#56]
        40000100:   910103e2        add     x2, sp, #0x40
        40000104:   8b010041        add     x1, x2, x1
        40000108:   385d0021        ldurb   w1, [x1,#-48]
        4000010c:   b9000001        str     w1, [x0]
        40000110:   b9403be0        ldr     w0, [sp,#56]
        40000114:   11000400        add     w0, w0, #0x1
        40000118:   b9003be0        str     w0, [sp,#56]
        4000011c:   b9403be0        ldr     w0, [sp,#56]
        40000120:   71001c1f        cmp     w0, #0x7
        40000124:   54fffa6d        b.le    40000070 <print_pointer+0x18>
        40000128:   d2a12000        mov     x0, #0x9000000                  // #150994944
        4000012c:   52800141        mov     w1, #0xa                        // #10
        40000130:   b9000001        str     w1, [x0]
        40000134:   910103ff        add     sp, sp, #0x40
        40000138:   d65f03c0        ret
    
    000000004000013c <c_entry>:
        4000013c:   a9bf7bfd        stp     x29, x30, [sp,#-16]!
        40000140:   910003fd        mov     x29, sp
        40000144:   90000000        adrp    x0, 40000000 <_Reset>
        40000148:   91088000        add     x0, x0, #0x220
        4000014c:   97ffffb3        bl      40000018 <print_uart0>
        40000150:   52800200        mov     w0, #0x10                       // #16
        40000154:   94000003        bl      40000160 <_sbrk>
        40000158:   a8c17bfd        ldp     x29, x30, [sp],#16
        4000015c:   d65f03c0        ret
    
    0000000040000160 <_sbrk>:
        40000160:   a9bd7bfd        stp     x29, x30, [sp,#-48]!
        40000164:   910003fd        mov     x29, sp
        40000168:   b9001fa0        str     w0, [x29,#28]
        4000016c:   90000000        adrp    x0, 40000000 <_Reset>
        40000170:   910b2000        add     x0, x0, #0x2c8
        40000174:   f9400000        ldr     x0, [x0]
        40000178:   eb1f001f        cmp     x0, xzr
        4000017c:   540000c1        b.ne    40000194 <_sbrk+0x34>
        40000180:   90000000        adrp    x0, 40000000 <_Reset>
        40000184:   910b2000        add     x0, x0, #0x2c8
        40000188:   90000001        adrp    x1, 40000000 <_Reset>
        4000018c:   910b4021        add     x1, x1, #0x2d0
        40000190:   f9000001        str     x1, [x0]
        40000194:   90000000        adrp    x0, 40000000 <_Reset>
        40000198:   910b4000        add     x0, x0, #0x2d0
        4000019c:   97ffffaf        bl      40000058 <print_pointer>
        400001a0:   90000080        adrp    x0, 40010000 <heap_low+0xfd30>
        400001a4:   910b4000        add     x0, x0, #0x2d0
        400001a8:   97ffffac        bl      40000058 <print_pointer>
        400001ac:   90000000        adrp    x0, 40000000 <_Reset>
        400001b0:   910b2000        add     x0, x0, #0x2c8
        400001b4:   f9400000        ldr     x0, [x0]
        400001b8:   f90017a0        str     x0, [x29,#40]
        400001bc:   90000000        adrp    x0, 40000000 <_Reset>
        400001c0:   910b2000        add     x0, x0, #0x2c8
        400001c4:   f9400001        ldr     x1, [x0]
        400001c8:   b9801fa0        ldrsw   x0, [x29,#28]
        400001cc:   8b000021        add     x1, x1, x0
        400001d0:   90000080        adrp    x0, 40010000 <heap_low+0xfd30>
        400001d4:   910b4000        add     x0, x0, #0x2d0
        400001d8:   eb00003f        cmp     x1, x0
        400001dc:   54000069        b.ls    400001e8 <_sbrk+0x88>
        400001e0:   52800000        mov     w0, #0x0                        // #0
        400001e4:   1400000a        b       4000020c <_sbrk+0xac>
        400001e8:   90000000        adrp    x0, 40000000 <_Reset>
        400001ec:   910b2000        add     x0, x0, #0x2c8
        400001f0:   f9400001        ldr     x1, [x0]
        400001f4:   b9801fa0        ldrsw   x0, [x29,#28]
        400001f8:   8b000021        add     x1, x1, x0
        400001fc:   90000000        adrp    x0, 40000000 <_Reset>
        40000200:   910b2000        add     x0, x0, #0x2c8
        40000204:   f9000001        str     x1, [x0]
        40000208:   f94017a0        ldr     x0, [x29,#40]
        4000020c:   a8c37bfd        ldp     x29, x30, [sp],#48
        40000210:   d65f03c0        ret
    [root@centos7 aarch64-bare-metal-qemu]# 
    volatile unsigned int * const UART0DR = (unsigned int *) 0x09000000;
     
    typedef  unsigned int caddr_t;
    caddr_t _sbrk(int incr) ;
    
    void print_uart0(const char *s) {
        while(*s != '\0') {                 /* Loop until end of string */
             *UART0DR = (unsigned int)(*s); /* Transmit char */
              s++;                          /* Next char */
        }
    }
    void print_pointer(int pointer) {
         int new_value[8]; 
         char buf_temp[8]; 
         int temp,x; 
         temp = pointer;
         for (x = 0; x < 8; x++) 
         { 
             new_value[x] = temp % 10;
             temp = temp / 10;
             buf_temp[x] = new_value[x] +48;
             //*UART0DR = (unsigned int)(buf_temp[x]); /* Transmit char */
             if (0 == temp)
             {
                 break;
             }
         }
         for (x; x > 0; --x) 
         { 
             *UART0DR = (unsigned int)(buf_temp[x-1]); /* Transmit char */
         }
             *UART0DR = '\n'; /* Transmit char */
    }
     
    void c_entry() {
         print_uart0("Hello world!\n");
         _sbrk(16);
    }
    char *heap_end = 0;
    
    caddr_t _sbrk(int incr) {
     extern int heap_low; /* Defined by the linker */
     extern int heap_top; /* Defined by the linker */
     char *prev_heap_end;
     
     if (heap_end == 0) {
      heap_end = &heap_low;
     }
     print_pointer(&heap_low);
     print_pointer(&heap_top);
    
     prev_heap_end = heap_end;
     
     if (heap_end + incr > &heap_top) {
      /* Heap and stack collision */
      return (caddr_t)0;
     }
     
     heap_end += incr;
     return (caddr_t) prev_heap_end;
     }

     

    aarch64-bare-metal-qemu

  • 相关阅读:
    页面get请求 中文参数方法乱码问题
    java版ftp简易客户端(可以获取文件的名称及文件大小)
    文件下载
    kafka:一个分布式消息系统
    Executor的线程代码
    验证码的生成
    二维码的简单实现
    rsync实现大致流程描述
    C++中模板生成时机
    gcc虚函数表生成时机
  • 原文地址:https://www.cnblogs.com/dream397/p/15632137.html
Copyright © 2020-2023  润新知