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 :
   0:   d10043ff        sub     sp, sp, #0x10
   4:   f90007e0        str     x0, [sp,#8]
   8:   14000008        b       28 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 0xc>
  38:   910043ff        add     sp, sp, #0x10
  3c:   d65f03c0        ret

0000000000000040 :
  40:   a9bf7bfd        stp     x29, x30, [sp,#-16]!
  44:   910003fd        mov     x29, sp
  48:   90000000        adrp    x0, 0 
  4c:   91000000        add     x0, x0, #0x0
  50:   94000000        bl      0 
  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:   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 
    4000000c:   14000000        b       4000000c <_Reset+0xc>
    40000010:   400010e8        .word   0x400010e8
    40000014:   00000000        .word   0x00000000

Disassembly of section .text:

0000000040000018 :
    40000018:   d10043ff        sub     sp, sp, #0x10
    4000001c:   f90007e0        str     x0, [sp,#8]
    40000020:   14000008        b       40000040 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 0xc>
    40000050:   910043ff        add     sp, sp, #0x10
    40000054:   d65f03c0        ret

0000000040000058 :
    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 
    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 
    4000000c:   14000000        b       4000000c <_Reset+0xc>
    40000010:   400010e8        .word   0x400010e8
    40000014:   00000000        .word   0x00000000

Disassembly of section .text:

0000000040000018 :
    40000018:   d10043ff        sub     sp, sp, #0x10
    4000001c:   f90007e0        str     x0, [sp,#8]
    40000020:   14000008        b       40000040 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 0xc>
    40000050:   910043ff        add     sp, sp, #0x10
    40000054:   d65f03c0        ret

0000000040000058 :
    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 
    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 
   1000c:       14000000        b       1000c <_Reset+0xc>
   10010:       000110e8        .word   0x000110e8
   10014:       00000000        .word   0x00000000

Disassembly of section .text:

0000000000010018 :
   10018:       d10043ff        sub     sp, sp, #0x10
   1001c:       f90007e0        str     x0, [sp,#8]
   10020:       14000008        b       10040 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 0xc>
   10050:       910043ff        add     sp, sp, #0x10
   10054:       d65f03c0        ret

0000000000010058 :
   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 
   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 
    4000000c:   14000000        b       4000000c <_Reset+0xc>
    40000010:   400110e8        .word   0x400110e8
    40000014:   00000000        .word   0x00000000

Disassembly of section .text:

0000000040000018 :
    40000018:   d10043ff        sub     sp, sp, #0x10
    4000001c:   f90007e0        str     x0, [sp,#8]
    40000020:   14000008        b       40000040 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 0xc>
    40000050:   910043ff        add     sp, sp, #0x10
    40000054:   d65f03c0        ret

0000000040000058 :
    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 
    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;
 }

aarch64-bare-metal-qemu

os