Changeset 701 for trunk/softs
- Timestamp:
- May 25, 2014, 5:35:37 PM (11 years ago)
- Location:
- trunk/softs/tsar_boot
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/softs/tsar_boot/Makefile
r662 r701 65 65 -ggdb \ 66 66 -mlong-calls \ 67 -O2 \ 67 68 -Werror 68 69 … … 89 90 all: $(TARGET) 90 91 91 92 $(BUILD_DIR)/version.o: $(BUILD_DIR) $(OBJS) version version.sh 92 93 $(ECHO) "[version.sh]" 93 94 ./version.sh > $(BUILD_DIR)/version.c -
trunk/softs/tsar_boot/include/defs.h
r586 r701 5 5 #define RESET_STACKS_SIZE 0x11000 /* 64 bytes * 1024 + 4 Kbytes (for P0) = 68 Kbytes */ 6 6 #define BOOT_LOADER_LBA 2 7 #define PHDR_ARRAY_SIZE 7 #define PHDR_ARRAY_SIZE 16 8 8 9 #define BLOCK_SIZE 512 10 11 // vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab 12 -
trunk/softs/tsar_boot/include/reset_utils.h
r655 r701 10 10 #include <elf-types.h> 11 11 #include <reset_tty.h> 12 #include <defs_platform.h> 12 #include <reset_ioc.h> 13 #include <defs.h> 13 14 #include <mcc.h> 14 15 #include <io.h> 15 16 17 /******************************************************************** 18 * Integer types definition 19 ********************************************************************/ 20 typedef unsigned int size_t; 21 typedef unsigned int addr_t; 22 23 /******************************************************************** 24 * Other types definition 25 ********************************************************************/ 26 27 /* 28 * cache line aligned disk block (sector) buffer 29 */ 30 struct aligned_blk 31 { 32 char b[BLOCK_SIZE]; 33 } __attribute__((aligned(CACHE_LINE_SIZE))); 34 35 /******************************************************************** 36 * Utility functions definition 37 ********************************************************************/ 38 16 39 extern unsigned int proctime(); 17 40 18 extern void* memcpy(void *_dst, const void *_src, unsigned int size);41 extern int pread(size_t file_offset, void *buf, size_t nbyte, size_t offset); 19 42 20 extern void* memset(void *_dst, const int value, unsigned int size); 43 extern void* memcpy(void *_dst, const void *_src, size_t n); 44 extern void* memset(void *_dst, int c, size_t len); 21 45 46 extern void check_elf_header(Elf32_Ehdr *ehdr); 22 47 extern void reset_print_elf_phdr(Elf32_Phdr * elf_phdr_ptr); 23 48 24 49 #if USE_IOB 25 void reset_mcc_invalidate ( const void * buffer, 26 unsigned int size); 50 void reset_mcc_invalidate (const void * buf, size_t size); 27 51 #endif /* USE_IOB */ 28 52 29 53 #if (CACHE_COHERENCE == 0) || USE_IOB 30 void reset_buf_invalidate ( const void * buffer, 31 unsigned int line_size, 32 unsigned int size); 54 void reset_buf_invalidate (const void * buf, size_t line_size, size_t size); 33 55 #endif /* (CACHE_COHERENCE == 0) || USE_IOB */ 34 56 #endif /* BOOT_UTILS_H */ -
trunk/softs/tsar_boot/src/reset_elf_loader.c
r694 r701 16 16 #include <defs.h> 17 17 18 #if (RESET_DEBUG == 1) 19 static char const * const init_state_str[] = 18 /////////////////////////////////////////////////////////////////////////////// 19 void * reset_elf_loader(size_t lba) 20 /////////////////////////////////////////////////////////////////////////////// 20 21 { 21 "ELF_HEADER_STATE", 22 "ELF_PROGRAM_HEADER_STATE", 23 "ELF_OFFSET_STATE", 24 "ELF_SEGMENT_STATE", 25 "ELF_END_STATE" 26 }; 27 #endif 28 29 unsigned char reset_elf_loader_buffer[512] __attribute__((aligned(CACHE_LINE_SIZE))); 30 31 ///////////////////////////////////////////////////////////////////////////////////// 32 void * reset_elf_loader(unsigned int lba) 33 ///////////////////////////////////////////////////////////////////////////////////// 34 { 35 /* 36 * Temporary variables used by the loader 37 */ 38 Elf32_Ehdr elf_header; 39 Elf32_Phdr elf_pht[PHDR_ARRAY_SIZE]; 40 41 unsigned char * buffer_ptr = 0; 42 Elf32_Ehdr * elf_ehdr_ptr; 43 Elf32_Phdr * elf_phdr_ptr; 44 45 unsigned int nb_available; 46 unsigned int nb_rest; 47 unsigned int nb_read; 48 unsigned int nb_block; 49 unsigned int offset; 50 51 unsigned char * pseg_ptr; 52 unsigned int pseg_start; 53 unsigned int pseg_end; 54 unsigned int pseg_remainder; 55 unsigned int pseg; 56 57 /* 58 * Loader state machine definition 59 */ 60 typedef enum 61 { 62 ELF_HEADER_STATE, 63 ELF_PROGRAM_HEADER_STATE, 64 ELF_OFFSET_STATE, 65 ELF_SEGMENT_STATE, 66 ELF_END_STATE 67 } elf_loader_t; 68 69 elf_loader_t init_state; 70 init_state = ELF_HEADER_STATE; 71 72 #if (RESET_DEBUG == 1) 73 elf_loader_t init_state_debug; 74 init_state_debug = ELF_END_STATE; 75 #endif 22 size_t file_offset = lba * BLOCK_SIZE; 76 23 77 24 reset_puts("\n[RESET] Start reset_elf_loader at cycle "); … … 79 26 reset_puts("\n"); 80 27 81 nb_block = lba; 82 nb_available = 0; 83 nb_rest = sizeof(Elf32_Ehdr); 84 pseg = 0; 85 offset = 0; 86 elf_ehdr_ptr = (Elf32_Ehdr *) &elf_header; 87 elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0]; 28 /* 29 * Load ELF HEADER 30 */ 31 Elf32_Ehdr elf_header; 32 if (pread(file_offset, (void*)&elf_header, sizeof(Elf32_Ehdr), 0) < 0) { 33 goto error; 34 } 35 check_elf_header(&elf_header); 88 36 89 while(init_state != ELF_END_STATE) 37 /* 38 * Load ELF PROGRAM HEADER TABLE 39 */ 40 Elf32_Phdr elf_pht[PHDR_ARRAY_SIZE]; 41 size_t phdr_nbyte = sizeof(Elf32_Phdr) * elf_header.e_phnum; 42 size_t phdr_off = elf_header.e_phoff; 43 if (pread(file_offset, (void*)&elf_pht, phdr_nbyte, phdr_off) < 0) { 44 goto error; 45 } 46 47 /* 48 * Search for loadable segments in the ELF file 49 */ 50 int pseg; 51 for (pseg = 0; pseg < elf_header.e_phnum; pseg++) 90 52 { 91 if (nb_available == 0 ) 92 { 93 buffer_ptr = &reset_elf_loader_buffer[0]; 53 if(elf_pht[pseg].p_type != PT_LOAD) continue; 94 54 95 if (reset_ioc_read(nb_block , buffer_ptr, 1)) 96 { 97 reset_puts ("[RESET ERROR] reset_ioc_read() failed\n"); 98 reset_exit(); 99 } 55 #if (RESET_DEBUG == 1) 56 reset_puts("[RESET DEBUG] Loadable segment found:\n"); 57 reset_print_elf_phdr(&elf_pht[pseg]); 58 #endif 100 59 101 nb_block += 1; 102 nb_available = 512; 60 addr_t p_paddr = elf_pht[pseg].p_paddr; 61 size_t p_filesz = elf_pht[pseg].p_filesz; 62 size_t p_memsz = elf_pht[pseg].p_memsz; 63 size_t p_offset = elf_pht[pseg].p_offset; 64 65 /* 66 * Copy program segment from ELF executable into corresponding physical 67 * address 68 */ 69 if (pread(file_offset, (void*)p_paddr, p_filesz, p_offset) < 0) { 70 goto error; 103 71 } 104 72 105 nb_read = (nb_rest <= nb_available) ? nb_rest : nb_available; 106 offset += nb_read; 73 /* 74 * Fill remaining bytes with zero (filesz < memsz) 75 */ 76 char* pseg_ptr = (char*)p_paddr; 77 memset((void*)&pseg_ptr[p_filesz], 0, (p_memsz - p_filesz)); 107 78 108 #if (RESET_DEBUG == 1) 109 if (init_state != init_state_debug) 110 { 111 reset_puts("\ninit_state = "); 112 reset_puts(init_state_str[init_state]); 113 reset_puts("\n"); 114 init_state_debug = init_state; 115 } 116 #endif 117 118 switch(init_state) 119 { 120 /* 121 * Reading ELF executable header 122 */ 123 case ELF_HEADER_STATE: 124 memcpy(elf_ehdr_ptr, buffer_ptr, nb_read); 125 126 nb_rest -= nb_read; 127 128 if(nb_rest == 0) 129 { 130 nb_rest = elf_ehdr_ptr->e_phnum * elf_ehdr_ptr->e_phentsize; 131 /* 132 * Verification of ELF Magic Number 133 */ 134 if ( (elf_ehdr_ptr->e_ident[EI_MAG0] != ELFMAG0) || 135 (elf_ehdr_ptr->e_ident[EI_MAG1] != ELFMAG1) || 136 (elf_ehdr_ptr->e_ident[EI_MAG2] != ELFMAG2) || 137 (elf_ehdr_ptr->e_ident[EI_MAG3] != ELFMAG3) ) 138 { 139 reset_puts("[RESET ERROR] boot-loader file is not an ELF format\n"); 140 reset_exit(); 141 } 142 143 /* 144 * Verification of Program Headers table size. It must be 145 * smaller than the work size allocated for the 146 * elf_pht[PHDR_ARRAY_SIZE] array 147 */ 148 if (elf_ehdr_ptr->e_phnum > PHDR_ARRAY_SIZE) 149 { 150 reset_puts("[RESET ERROR] ELF PHDR table size too large\n"); 151 reset_exit(); 152 } 153 154 init_state = ELF_PROGRAM_HEADER_STATE; 155 } 156 157 break; 158 159 /* 160 * Reading ELF program headers 161 */ 162 case ELF_PROGRAM_HEADER_STATE: 163 memcpy(elf_phdr_ptr, buffer_ptr, nb_read); 164 165 elf_phdr_ptr = 166 (Elf32_Phdr *)((unsigned char *) elf_phdr_ptr + nb_read); 167 168 nb_rest -= nb_read; 169 170 if(nb_rest == 0) 171 { 172 elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0]; 173 174 /* 175 * Search the first not NULL segment in the ELF file 176 */ 177 for (pseg = 0; pseg < elf_ehdr_ptr->e_phnum; pseg++) 178 { 179 if(elf_phdr_ptr[pseg].p_type == PT_LOAD) 180 { 181 #if (RESET_DEBUG == 1) 182 reset_puts("loadable segment found:\n"); 183 reset_print_elf_phdr(&elf_phdr_ptr[pseg]); 184 #endif 185 if (elf_phdr_ptr[pseg].p_offset < offset) 186 { 187 /* 188 * Case where the segment to load includes the 189 * elf and program headers 190 */ 191 nb_rest = elf_phdr_ptr[pseg].p_filesz - offset; 192 init_state = ELF_SEGMENT_STATE; 193 } 194 else 195 { 196 /* 197 * Segment to load is further away in ELF file 198 */ 199 nb_rest = elf_phdr_ptr[pseg].p_offset - offset; 200 init_state = ELF_OFFSET_STATE; 201 } 202 break; 203 } 204 } 205 206 if (pseg == elf_ehdr_ptr->e_phnum) 207 { 208 reset_puts("[RESET ERROR] No PT_LOAD found\n"); 209 reset_exit(); 210 } 211 212 } 213 214 break; 215 216 /* 217 * Go to the offset of the first not null program segment in the 218 * ELF file 219 * 220 * TODO: 221 * No need to read from the disk the useless bytes. Try to compute 222 * the next usefull lba 223 */ 224 case ELF_OFFSET_STATE: 225 nb_rest -= nb_read; 226 227 if (nb_rest == 0) 228 { 229 nb_rest = elf_phdr_ptr[pseg].p_filesz; 230 init_state = ELF_SEGMENT_STATE; 231 } 232 233 break; 234 235 /* 236 * Reading ELF segments 237 * 238 * TODO: 239 * Do not pass by block buffer but write directly in target memory 240 * address 241 */ 242 case ELF_SEGMENT_STATE: 243 /* 244 * Verify that loadable segment does not conflict with 245 * pre-loader memory space 246 */ 247 pseg_start = elf_phdr_ptr[pseg].p_paddr; 248 249 pseg_end = elf_phdr_ptr[pseg].p_paddr + 250 elf_phdr_ptr[pseg].p_memsz; 251 252 if ((pseg_start >= 0xBFC00000 && pseg_start <= 0xBFC10000) || 253 (pseg_end >= 0xBFC00000 && pseg_end <= 0xBFC10000) || 254 (pseg_start < 0xBFC00000 && pseg_end > 0xBFC10000)) 255 { 256 reset_puts("[RESET ERROR] conflict with pre-loader memory space\n"); 257 reset_exit(); 258 } 259 260 /* 261 * Copy the ELF segment data in memory using the 262 * virtual address obtained from the ELF file 263 */ 264 pseg_ptr = (unsigned char *) 265 elf_phdr_ptr[pseg].p_paddr + 266 elf_phdr_ptr[pseg].p_filesz - 267 nb_rest; 268 269 memcpy(pseg_ptr, buffer_ptr, nb_read); 270 271 nb_rest -= nb_read; 272 273 if (nb_rest == 0) 274 { 275 /* 276 * Fill remaining bytes with zeros (filesz < memsz) 277 */ 278 pseg_remainder = 279 elf_phdr_ptr[pseg].p_memsz - 280 elf_phdr_ptr[pseg].p_filesz ; 281 282 pseg_ptr = (unsigned char *) 283 elf_phdr_ptr[pseg].p_paddr + 284 elf_phdr_ptr[pseg].p_filesz ; 285 286 memset(pseg_ptr, 0, pseg_remainder); 287 288 reset_puts("\n[RESET] Segment loaded : address = "); 289 reset_putx(elf_phdr_ptr[pseg].p_paddr); 290 reset_puts(" / size = "); 291 reset_putx(elf_phdr_ptr[pseg].p_filesz); 292 reset_puts("\n"); 293 294 /* 295 * Search the next first not NULL segment in the ELF file 296 */ 297 for (pseg += 1; pseg < elf_ehdr_ptr->e_phnum; pseg++) 298 { 299 if(elf_phdr_ptr[pseg].p_type == PT_LOAD) 300 { 301 #if (RESET_DEBUG == 1) 302 reset_puts("loadable segment found:\n"); 303 reset_print_elf_phdr(&elf_phdr_ptr[pseg]); 304 #endif 305 nb_rest = elf_phdr_ptr[pseg].p_offset - offset; 306 break; 307 } 308 } 309 310 /* 311 * Program loading finished 312 */ 313 if(pseg == elf_ehdr_ptr->e_phnum) 314 { 315 init_state = ELF_END_STATE; 316 break; 317 } 318 319 init_state = ELF_OFFSET_STATE; 320 } 321 break; 322 323 default: 324 break; 325 } 326 327 buffer_ptr += nb_read; 328 nb_available -= nb_read; 79 reset_puts("\n[RESET] Segment loaded : address = "); 80 reset_putx(p_paddr); 81 reset_puts(" / size = "); 82 reset_putx(p_filesz); 83 reset_puts("\n"); 329 84 } 330 85 … … 332 87 reset_putd( proctime() ); 333 88 reset_puts(" / boot entry = "); 334 reset_putx( ( unsigned int)(elf_ehdr_ptr->e_entry) );89 reset_putx( (addr_t)(elf_header.e_entry) ); 335 90 reset_puts("\n"); 336 91 337 return ((void *) elf_ehdr_ptr->e_entry); 92 return ((void *) elf_header.e_entry); 93 94 error: 95 reset_puts("\n[RESET ERROR] Error while loading ELF file"); 96 reset_exit(); 97 return 0; 338 98 } 339 99 -
trunk/softs/tsar_boot/src/reset_utils.c
r691 r701 9 9 #include <reset_utils.h> 10 10 11 /* 12 * pread(size_t file_offset, void* buf, size_t nbyte, size_t offset) 13 * 14 * read from disk into buffer "nbyte" bytes from (file_offset + offset) 15 * 16 * \param file_offset: Disk relative offset of file 17 * \param buf: Destination buffer 18 * \param nbyte: Number of bytes to read 19 * \param offset: File relative offset 20 * 21 * \note Absolute disk offset (in bytes) is (file_offset + offset) 22 */ 23 int pread(size_t file_offset, void *buf, size_t nbyte, size_t offset) { 24 if (nbyte == 0) return 0; 25 26 /* 27 * Cache block data buffer and cached block index 28 */ 29 static struct aligned_blk blk_buf; 30 static int blk_buf_idx = -1; 31 32 char *dst; 33 int offset_blk; 34 int unaligned_nbyte; 35 int read_nbyte; 36 37 dst = (char*) buf; 38 39 /* 40 * Offset parameter is relative to file, therefore compute disk relative 41 * offset (in bytes) 42 */ 43 offset += file_offset; 44 45 /* 46 * Read unaligned bytes at start of segment passing by block cache 47 */ 48 offset_blk = (offset / BLOCK_SIZE); 49 offset = (offset % BLOCK_SIZE); 50 unaligned_nbyte = BLOCK_SIZE - offset; 51 read_nbyte = 0; 52 if (offset) { 53 /* 54 * Check cache block hit: if miss, read new block else, use cache block 55 * data 56 */ 57 if (offset_blk != blk_buf_idx) { 58 if (reset_ioc_read(offset_blk, (void*)&blk_buf, 1)) { 59 return -1; 60 } 61 } 62 blk_buf_idx = offset_blk; 63 read_nbyte = (nbyte > unaligned_nbyte) ? unaligned_nbyte : nbyte; 64 memcpy((void*)dst, (void*)&blk_buf.b[offset], read_nbyte); 65 nbyte -= read_nbyte; 66 offset_blk += 1; 67 } 68 69 /* 70 * Read aligned bytes directly to buffer 71 */ 72 size_t nblk = nbyte / BLOCK_SIZE; 73 if (nblk) { 74 if (reset_ioc_read(offset_blk, (void*)&dst[read_nbyte], nblk)) { 75 return -1; 76 } 77 read_nbyte += (nblk * BLOCK_SIZE); 78 nbyte -= read_nbyte; 79 offset_blk += nblk; 80 } 81 82 /* 83 * Read unaligned bytes at the end of segment passing by block cache 84 */ 85 if (nbyte) { 86 if (reset_ioc_read(offset_blk, (void*)&blk_buf, 1)) { 87 return -1; 88 } 89 blk_buf_idx = offset_blk; 90 memcpy((void*)&dst[read_nbyte], (void*)&blk_buf, nbyte); 91 read_nbyte += nbyte; 92 } 93 return read_nbyte; 94 } 95 11 96 /******************************************************************** 12 97 * proctime() … … 31 116 * 32 117 ********************************************************************/ 33 void * memcpy(void *_dst, const void *_src, unsigned int size)118 void* memcpy(void *_dst, const void *_src, size_t n) 34 119 { 35 120 unsigned int *dst = _dst; … … 37 122 if ( !((unsigned int)dst & 3) && !((unsigned int)src & 3) ) 38 123 { 39 while ( size> 3)124 while (n > 3) 40 125 { 41 126 *dst++ = *src++; 42 size-= 4;127 n -= 4; 43 128 } 44 129 } … … 46 131 unsigned char *cdst = (unsigned char*) dst; 47 132 unsigned char *csrc = (unsigned char*) src; 48 49 while (size--) 133 while (n--) 50 134 { 51 135 *cdst++ = *csrc++; … … 64 148 * 65 149 ********************************************************************/ 66 void * memset(void *_dst, const int value, unsigned int size) 67 { 68 unsigned char val = (unsigned char) value; 69 int word = (val << 24) | (val << 16) | (val << 8 ) | val; 150 void* memset(void *_dst, int c, size_t len) 151 { 152 if (len == 0) return _dst; 153 154 unsigned char val = (unsigned char) c; 155 unsigned int word = (val << 24) | (val << 16) | (val << 8 ) | val; 70 156 71 157 /* … … 76 162 if ( !((unsigned int)dst & 3) ) 77 163 { 78 while ( size> 3)164 while (len > 3) 79 165 { 80 166 *dst++ = word; 81 size-= 4;167 len -= 4; 82 168 } 83 169 } … … 87 173 * or size is smaller than 4 88 174 */ 89 char* cdst = (char*) _dst;90 while( size--)91 { 92 *cdst++ = ( char) value;175 unsigned char* cdst = (unsigned char*) _dst; 176 while(len--) 177 { 178 *cdst++ = (unsigned char) c; 93 179 } 94 180 95 181 return _dst; 182 } 183 184 /******************************************************************** 185 * check_elf_header(Elf32_Ehdr*) 186 * 187 * Verify that ELF file is valid and that the number of program 188 * headers does not exceed the defined maximum 189 * 190 * \param ehdr : ELF header pointer 191 * 192 ********************************************************************/ 193 void check_elf_header(Elf32_Ehdr *ehdr) 194 { 195 /* 196 * Verification of ELF Magic Number 197 */ 198 if ((ehdr->e_ident[EI_MAG0] != ELFMAG0) || 199 (ehdr->e_ident[EI_MAG1] != ELFMAG1) || 200 (ehdr->e_ident[EI_MAG2] != ELFMAG2) || 201 (ehdr->e_ident[EI_MAG3] != ELFMAG3)) 202 { 203 reset_puts("[RESET ERROR] Unrecognized file format (not an ELF format)\n"); 204 reset_exit(); 205 } 206 207 /* 208 * Verification of Program Headers table size. It must be 209 * smaller than the work size allocated for the 210 * elf_pht[PHDR_ARRAY_SIZE] array 211 */ 212 if (ehdr->e_phnum > PHDR_ARRAY_SIZE) 213 { 214 reset_puts("[RESET ERROR] ELF PHDR table size too large\n"); 215 reset_exit(); 216 } 96 217 } 97 218 … … 108 229 reset_puts("- type : "); 109 230 reset_putx(elf_phdr_ptr->p_type); 110 111 231 reset_puts("\n- offset : "); 112 232 reset_putx(elf_phdr_ptr->p_offset); 113 114 233 reset_puts("\n- vaddr : "); 115 234 reset_putx(elf_phdr_ptr->p_vaddr); 116 117 235 reset_puts("\n- paddr : "); 118 236 reset_putx(elf_phdr_ptr->p_paddr); 119 120 237 reset_puts("\n- filesz : "); 121 238 reset_putx(elf_phdr_ptr->p_filesz); 122 123 239 reset_puts("\n- memsz : "); 124 240 reset_putx(elf_phdr_ptr->p_memsz); 125 126 241 reset_puts("\n- flags : "); 127 242 reset_putx(elf_phdr_ptr->p_flags); 128 129 243 reset_puts("\n- align : "); 130 244 reset_putx(elf_phdr_ptr->p_align); 245 reset_puts("\n"); 131 246 } 132 247 … … 139 254 ********************************************************************/ 140 255 #if USE_IOB 141 void reset_mcc_invalidate ( const void * buffer, 142 unsigned int size) 143 { 144 unsigned int * mcc_address = (unsigned int *)MCC_PADDR_BASE; 256 void reset_mcc_invalidate (const void * buffer, size_t size) 257 { 258 addr_t *mcc_address = (addr_t*)MCC_PADDR_BASE; 145 259 146 260 // get the hard lock assuring exclusive access to MEMC … … 167 281 ********************************************************************/ 168 282 #if (CACHE_COHERENCE == 0) || USE_IOB 169 void reset_buf_invalidate ( const void * buffer, 170 unsigned int line_size, 171 unsigned int size) 283 void reset_buf_invalidate (const void * buffer, size_t line_size, size_t size) 172 284 { 173 285 unsigned int i;
Note: See TracChangeset
for help on using the changeset viewer.