Hallo Community! Wie kann man im GNU Linker Script ein unterschiedliches Section und Datei Alignment erzielen? Würde es für eine EFI Applikation benötigen. Hier wird ja das PE+ (Microsoft's Portable Executable Format) verwendet. Dieses kennt ja beide Alignment Typen:
1 | /** |
2 | * PE+: Optional header Windows-specific fields |
3 | */ |
4 | header_win: |
5 | .quad 0 /* ImageBase */ |
6 | .word 0x1000 /* SectionAlignment */ |
7 | .word 0x1000 /* FileAlignment */ |
Folgendes simple Linker Script verwende ich derzeit:
1 | OUTPUT_FORMAT(elf64-littleriscv) |
2 | |
3 | ENTRY(_start) |
4 | |
5 | SECTIONS {
|
6 | . = 0x0; |
7 | _image_s = .; |
8 | |
9 | .peheader : {
|
10 | KEEP(*(.peheader)) |
11 | } |
12 | |
13 | .text : ALIGN(0x1000) {
|
14 | _text_s = .; |
15 | *(.text) |
16 | *(.text*) |
17 | _text_e = .; |
18 | } |
19 | |
20 | .reloc : ALIGN(0x1000) {
|
21 | _reloc_s = .; |
22 | *(.reloc) |
23 | *(.reloc*) |
24 | _reloc_e = .; |
25 | } |
26 | |
27 | .rodata : ALIGN(0x1000) {
|
28 | _rodata_s = .; |
29 | *(.rodata) |
30 | *(.rodata*) |
31 | _rodata_e = .; |
32 | } |
33 | |
34 | _image_e = .; |
35 | |
36 | /DISCARD/ : {
|
37 | *(.note) |
38 | *(.note.*) |
39 | *(.header) |
40 | } |
41 | } |
Bei großen Programmen, fällt das nicht so ins Gewicht. Aber bei einem simplen "Hello World!" Programm hat die Datei schon mal 12KiB an Größe. Hier für RISC-V:
1 | .set EFI_SUCCESS, 0 |
2 | |
3 | /** |
4 | * .text Section |
5 | */ |
6 | .text |
7 | |
8 | /** |
9 | * Main entry point of the application |
10 | * |
11 | * Simple outputs the string "Hello World!" on the EFI console |
12 | * and exists. |
13 | */ |
14 | .global _start |
15 | .func _start |
16 | .type _start,%function |
17 | _start: |
18 | addi sp, sp, -16 |
19 | sd ra, 8(sp) |
20 | sd fp, 0(sp) |
21 | addi fp, sp, 16 |
22 | |
23 | /** |
24 | * Save address of EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL from |
25 | * EFI_SYSTEM_TABLE to register A0. |
26 | */ |
27 | ld a0, 64(a1) |
28 | |
29 | /** |
30 | * Save address of EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL->OutputString() |
31 | * to register T0. |
32 | */ |
33 | ld t0, 8(a0) |
34 | |
35 | /** |
36 | * Load address of string 'string_hello' into register A1. |
37 | */ |
38 | la a1, string_hello |
39 | |
40 | /** |
41 | * Call/Invoke EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL->OutputString() |
42 | */ |
43 | jalr t0 |
44 | |
45 | li a0, EFI_SUCCESS |
46 | |
47 | ld ra, 8(sp) |
48 | ld fp, 0(sp) |
49 | addi sp, sp, 16 |
50 | ret |
51 | .endfunc |
52 | |
53 | /** |
54 | * .rodata Section |
55 | */ |
56 | .section .rodata |
57 | |
58 | /* UTF-16LE (CHAR16) encoded output string */ |
59 | string_hello: |
60 | .byte 'H' |
61 | .byte 0 |
62 | .byte 'e' |
63 | .byte 0 |
64 | .byte 'l' |
65 | .byte 0 |
66 | .byte 'l' |
67 | .byte 0 |
68 | .byte 'o' |
69 | .byte 0 |
70 | .byte ' ' |
71 | .byte 0 |
72 | .byte 'W' |
73 | .byte 0 |
74 | .byte 'o' |
75 | .byte 0 |
76 | .byte 'r' |
77 | .byte 0 |
78 | .byte 'l' |
79 | .byte 0 |
80 | .byte 'd' |
81 | .byte 0 |
82 | .byte '!' |
83 | .byte 0 |
84 | .byte '\r' |
85 | .byte 0 |
86 | .byte '\n' |
87 | .byte 0 |
88 | .byte 0 |
89 | .byte 0 |
Then vollen Code findet man unter meinen GitHub repo: https://github.com/Krotti83/EFI-bare-metal-riscv64