1
1
package main
2
2
3
3
import (
4
+ "bytes"
5
+ "encoding/binary"
4
6
"flag"
5
7
"fmt"
6
8
"os"
@@ -10,6 +12,8 @@ func main() {
10
12
var output = flag .String ("output" , "" , "Output to a specific file (default: add .dfu suffix)" )
11
13
var debug = flag .Bool ("debug" , false , "Enable debugging mode" )
12
14
var linked = flag .Bool ("prelinked" , false , "Provided file has already been linked to Zephyr" )
15
+ var force = flag .Bool ("force" , false , "Ignore safety checks and overwrite the header" )
16
+ var add_header = flag .Bool ("add_header" , false , "Add space for the header to the file" )
13
17
14
18
flag .Parse ()
15
19
if flag .NArg () != 1 {
@@ -26,16 +30,57 @@ func main() {
26
30
return
27
31
}
28
32
29
- // Get the length of the file content
30
- length := len (content )
33
+ var ELF_HEADER = []byte { 0x7f , 0x45 , 0x4c , 0x46 }
34
+ var elf_header_found = bytes .Compare (ELF_HEADER , content [0 :4 ]) == 0
35
+ if * add_header || (! * force && ! elf_header_found ) {
36
+ fmt .Printf ("File does not have an ELF header, adding empty space\n " )
31
37
32
- // Create the new content with the length in front
33
- len_str := fmt .Sprintf ("%d" , length )
34
- newContent := append ([]byte (len_str ), 0 , byte (* debug ), byte (* linked ))
35
- // make newContent 16 bytes
36
- tmp := make ([]byte , 16 - len (newContent ))
37
- newContent = append (newContent , tmp ... )
38
- newContent = append (newContent , content ... )
38
+ var newContent = make ([]byte , len (content )+ 16 )
39
+ copy (newContent [16 :], content )
40
+ content = newContent
41
+ }
42
+
43
+ // Create and fill custom header
44
+ var header struct {
45
+ ver uint8 // @ 0x07
46
+ len uint32 // @ 0x08
47
+ magic uint16 // @ 0x0c
48
+ flags uint8 // @ 0x0e
49
+ }
50
+
51
+ header .ver = 1
52
+ header .magic = 0x2341 // Arduino USB VID
53
+ header .len = uint32 (len (content ))
54
+
55
+ header .flags = 0
56
+ if * debug {
57
+ header .flags |= 0x01
58
+ }
59
+ if * linked {
60
+ header .flags |= 0x02
61
+ }
62
+
63
+ var bytes = make ([]byte , 9 )
64
+ _ , err = binary .Encode (bytes , binary .LittleEndian , header )
65
+ if err != nil {
66
+ fmt .Printf ("Error encoding header: %v\n " , err )
67
+ return
68
+ }
69
+
70
+ // Bytes 7 to 15 are free to use in current ELF specification. We will
71
+ // use them to store the debug and linked flags.
72
+ // Check if the target area is empty
73
+ if ! * force {
74
+ for i := 7 ; i < 16 ; i ++ {
75
+ if content [i ] != 0 {
76
+ fmt .Printf ("Target ELF header area is not empty. Use --force to overwrite\n " )
77
+ return
78
+ }
79
+ }
80
+ }
81
+
82
+ // Change the header bytes in the content
83
+ copy (content [7 :16 ], bytes )
39
84
40
85
// Create a new filename for the copy
41
86
newFilename := * output
@@ -44,13 +89,7 @@ func main() {
44
89
}
45
90
46
91
// Write the new content to the new file
47
- err = os .WriteFile (newFilename , []byte (newContent ), 0644 )
48
- if err != nil {
49
- fmt .Printf ("Error writing to file: %v\n " , err )
50
- return
51
- }
52
- // Copy in .bin
53
- err = os .WriteFile (newFilename + ".bin" , []byte (newContent ), 0644 )
92
+ err = os .WriteFile (newFilename , content , 0644 )
54
93
if err != nil {
55
94
fmt .Printf ("Error writing to file: %v\n " , err )
56
95
return
0 commit comments