[rendering] Add batch mode to the simple code
[wikipediardware.git] / mbr / rs232-loader.c
blob460def1c2640ba67e73fcf5ceb59b309ff60e19f
1 /*
2 e07 bootloader suite
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"
22 #include <string.h>
24 #define ET_EXEC 2
25 #define EM_C33 0x6b
27 #define ELFMAG0 0x7f
28 #define ELFMAG1 0x45
29 #define ELFMAG2 0x4c
30 #define ELFMAG3 0x46
32 typedef struct {
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;
49 typedef struct {
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();
83 rs232_elf_load();
84 APPLICATION_FINALISE(0, 0);
87 void rs232_elf_load(void)
89 u32 file_size;
90 elf32_hdr *hdr;
91 unsigned int i;
92 void *exec;
93 elf32_sec *sec;
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");
112 return;
115 if (hdr->e_type != ET_EXEC) {
116 print("invalid ELF file type\n");
117 return;
120 if (hdr->e_machine != EM_C33) {
121 print("FAIL: machine\n");
122 return;
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) {
129 case SHT_PROGBITS:
130 memcpy((u8 *)sec->sh_addr, BUFFER + sec->sh_offset, sec->sh_size);
131 print("PROG: ");
132 print_u32(sec->sh_addr);
133 print("\n");
134 break;
135 case SHT_NOBITS:
136 /* clean .bss sections */
137 memset((u8 *)sec->sh_addr, 0, sec->sh_size);
138 break;
139 default:
140 break;
144 print("EXEC from serial: ");
145 print_u32(hdr->e_entry);
146 print("\n");
148 exec = (void *)hdr->e_entry;
149 ((void (*) (void)) exec) ();