3 Copyright (c) 2008 Daniel Mack <daniel@caiaq.de>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #define APPLICATION_TITLE "rs232 loader"
21 #include "application.h"
33 u8 e_ident
[16]; /* ELF "magic number" */
34 u16 e_type
; /* Identifies object file type */
35 u16 e_machine
; /* Specifies required architecture */
36 u32 e_version
; /* Identifies object file version */
37 u32 e_entry
; /* Entry point virtual address */
38 u32 e_phoff
; /* Program header table file offset */
39 u32 e_shoff
; /* Section header table file offset */
40 u32 e_flags
; /* Processor-specific flags */
41 u16 e_ehsize
; /* ELF header size in bytes */
42 u16 e_phentsize
; /* Program header table entry size */
43 u16 e_phnum
; /* Program header table entry count */
44 u16 e_shentsize
; /* Section header table entry size */
45 u16 e_shnum
; /* Section header table entry count */
46 u16 e_shstrndx
; /* Section header string table index */
47 } __attribute__((packed
)) elf32_hdr
;
50 u32 sh_name
; /* Section name, index in string tbl */
51 u32 sh_type
; /* Type of section */
52 u32 sh_flags
; /* Miscellaneous section attributes */
53 u32 sh_addr
; /* Section virtual addr at execution */
54 u32 sh_offset
; /* Section file offset */
55 u32 sh_size
; /* Size of section in bytes */
56 u32 sh_link
; /* Index of another section */
57 u32 sh_info
; /* Additional section information */
58 u32 sh_addralign
; /* Section alignment */
59 u32 sh_entsize
; /* Entry size if section holds table */
60 } __attribute__((packed
)) elf32_sec
;
62 #define SHT_NULL 0 /* Section header table entry unused */
63 #define SHT_PROGBITS 1 /* Program specific (private) data */
64 #define SHT_SYMTAB 2 /* Link editing symbol table */
65 #define SHT_STRTAB 3 /* A string table */
66 #define SHT_RELA 4 /* Relocation entries with addends */
67 #define SHT_HASH 5 /* A symbol hash table */
68 #define SHT_DYNAMIC 6 /* Information for dynamic linking */
69 #define SHT_NOTE 7 /* Information that marks file */
70 #define SHT_NOBITS 8 /* Section occupies no space in file */
71 #define SHT_REL 9 /* Relocation entries, no addends */
72 #define SHT_SHLIB 10 /* Reserved, unspecified semantics */
73 #define SHT_DYNSYM 11 /* Dynamic linking symbol table */
75 #define BUFFER (u8 *)(0x10000000 + 16 * 1024 * 1024)
77 void rs232_elf_load(void);
79 // this must be the first executable code as the loader executes from the first program address
80 ReturnType
rs232_loader(int block
, int status
)
82 APPLICATION_INITIALISE();
84 APPLICATION_FINALISE(0, 0);
87 void rs232_elf_load(void)
95 print("Waiting for file from the serial line ... \n");
97 for (i
= 0; i
< sizeof(u32
); i
++) {
98 ((unsigned char *)&file_size
)[i
] = serial_input_char();
101 for (i
= 0; i
< file_size
; i
++) {
102 (BUFFER
)[i
] = serial_input_char();
105 hdr
= (elf32_hdr
*)BUFFER
;
107 if (hdr
->e_ident
[0] != ELFMAG0
||
108 hdr
->e_ident
[1] != ELFMAG1
||
109 hdr
->e_ident
[2] != ELFMAG2
||
110 hdr
->e_ident
[3] != ELFMAG3
) {
111 print("invalid ELF magic\n");
115 if (hdr
->e_type
!= ET_EXEC
) {
116 print("invalid ELF file type\n");
120 if (hdr
->e_machine
!= EM_C33
) {
121 print("FAIL: machine\n");
125 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
126 sec
= (elf32_sec
*)(BUFFER
+ (hdr
->e_shoff
+ (sizeof(elf32_sec
) * i
)));
128 switch (sec
->sh_type
) {
130 memcpy((u8
*)sec
->sh_addr
, BUFFER
+ sec
->sh_offset
, sec
->sh_size
);
132 print_u32(sec
->sh_addr
);
136 /* clean .bss sections */
137 memset((u8
*)sec
->sh_addr
, 0, sec
->sh_size
);
144 print("EXEC from serial: ");
145 print_u32(hdr
->e_entry
);
148 exec
= (void *)hdr
->e_entry
;
149 ((void (*) (void)) exec
) ();