Changeset 425
- Timestamp:
- Jun 30, 2013, 8:28:58 PM (11 years ago)
- Location:
- trunk/softs/tsar_boot
- Files:
-
- 2 added
- 4 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/softs/tsar_boot/Makefile
r411 r425 2 2 -include ./build.mk 3 3 4 ifndef MAKECMDGOALS 5 MAKECMDGOALS=none 6 endif 4 MAKECMDGOALS ?= none 7 5 8 6 ifneq ($(MAKECMDGOALS),$(filter $(MAKECMDGOALS),clean distclean clean-doc doc)) … … 19 17 endif 20 18 endif 21 endif22 23 ifeq ($(USE_DT), 0)24 DTS=25 19 endif 26 20 … … 58 52 59 53 CFLAGS := -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 \ 60 -ggdb -mlong-calls 54 -ggdb -mlong-calls -Werror 61 55 62 C_SRCS := boot_elf_loader.c boot_ioc.c boot_ memcpy.c boot_tty.c exceptions.c56 C_SRCS := boot_elf_loader.c boot_ioc.c boot_utils.c boot_tty.c exceptions.c 63 57 64 58 ifndef SOCLIB … … 74 68 TARGET := bin.soft 75 69 76 ifndef USE_DT 77 USE_DT := 1 78 else 79 USE_DT := $(USE_DT) 80 endif 81 82 ifdef SYSCLK_FREQ 83 DEFS += -DSYSCLK_FREQ=$(SYSCLK_FREQ) 84 endif 70 USE_DT ?= 1 85 71 86 72 all: $(TARGET) … … 91 77 $(DU) -D $@ > $@.txt 92 78 79 ifeq ($(USE_DT), 1) 93 80 $(BUILD_DIR)/platform.ld: $(BUILD_DIR)/platform.dtb 94 81 $(ECHO) "[ HEXDUMP ] $(notdir $<)" 95 82 $(HEXDUMP) -v -e '"BYTE(0x" 1/1 "%02X" ")\n"' $< > $@ 83 else 84 $(BUILD_DIR)/platform.ld: 85 $(ECHO) "[ TOUCH ] $(notdir $@)" 86 touch $@ 87 endif 96 88 97 89 $(BUILD_DIR)/platform.dtb: $(DTS) 98 ifeq ($(USE_DT), 1)99 90 $(ECHO) "[ DTC ] $(notdir $<)" 100 91 ${DTC} -O dtb -o $@ $< &> /dev/null 101 else102 touch $@103 endif104 92 105 93 $(BUILD_DIR): -
trunk/softs/tsar_boot/README.txt
r390 r425 17 17 the TTY, IOC and XICU devices. 18 18 It defines also: 19 19 20 -> CACHE_COHERENCE 20 21 This constant is used by the boot_ioc_read function to know … … 22 23 must be invalidated in the dcache after the transfert has 23 24 finished. 24 0 means invalidation must be made.25 26 -> INSTRUMENTATION27 Set value different to 0 if some instrumentation of the28 bootloader is needed.29 25 30 26 -> CACHE_LINE_SIZE 27 This constant is mandatory if CACHE_COHERENCE=0 31 28 This constant defines the size in bytes of a cache line. 29 30 -> BOOT_DEBUG 31 Set value to 1 to show some debug messages during loading 32 33 -> BOOT_DEBUG_IOC 34 Set value to 1 to show some debug messages during loading 35 concerning the disk accesses. 32 36 33 37 -> IRQ_PER_PROC … … 37 41 ---> platform_soclib.dts: 38 42 39 Device tree file. It is mandatory if compiling 40 for a SOCLIB platform. If the application to execute does not use 41 a device tree file, create an empty one. 43 Device tree file. It is mandatory if compiling for a SOCLIB 44 platform and USE_DT=1. 42 45 43 46 ---> platform_fpga.dts: 44 47 45 Device tree file. It is mandatory if compiling 46 for a FPGA platform. If the application to execute does not use 47 a device tree file, create an empty one. 48 Device tree file. It is mandatory if compiling for a FPGA platform 49 and USE_DT=1. 48 50 49 51 ---> ldscript: … … 70 72 drivers 71 73 72 ---> SYSCLK_FREQ=<value hz>74 ---> USE_DT=0 73 75 74 If not SOCLIB platform, this flag allows us to choose the 75 CLK frequency used in the hardware platform (i.e. FPGA). 76 This information is used to configurate the SPI device 77 which allow us to drive a SD card device. 76 If a device tree file is not used, set this flag to 0. It 77 is set by default to 1. 78 78 79 i.e. make PLATFORM_DIR=conf/<platform_dir> SYSCLK_FREQ=50000000 80 make PLATFORM_DIR=conf/<platform_dir> SOCLIB=1 79 e.g. make PLATFORM_DIR=conf/<platform_dir> SOCLIB=1 USE_DT=0 -
trunk/softs/tsar_boot/conf/platform_fpga_de2-115/defs_platform.h
r412 r425 7 7 #define CACHE_LINE_SIZE 64//bytes 8 8 9 #define BOOT_DEBUG 09 #define BOOT_DEBUG 1 10 10 #define BOOT_DEBUG_IOC 0 11 11 … … 13 13 #define TTY_BASE 0xFC000000 14 14 #define ICU_BASE 0xFD000000 15 16 /* Mandatory argument only for FPGA platforms */ 17 18 #define SYSCLK_FREQ 25000000//Hz -
trunk/softs/tsar_boot/conf/platform_vgsb_xicu_mmu/defs_platform.h
r412 r425 7 7 #define CACHE_LINE_SIZE 16//bytes 8 8 9 #define BOOT_DEBUG 1 10 #define BOOT_DEBUG_IOC 0 11 9 12 #define ICU_BASE 0x00F00000 10 13 #define IOC_BASE 0x00F10000 -
trunk/softs/tsar_boot/conf/platform_vgsb_xicu_mmu/ldscript
r368 r425 7 7 /* Definition of the base address for all segments */ 8 8 9 seg_stack_base = 0x00 108000;9 seg_stack_base = 0x00018000; 10 10 seg_boot_base = 0xBFC00000; /* le code de boot */ 11 11 -
trunk/softs/tsar_boot/include/defs.h
r292 r425 3 3 #define BOOT_VERSION 0x00010001 4 4 5 #define BOOT_STACK_SIZE 0x 8000 /* 32KB */5 #define BOOT_STACK_SIZE 0x4000 /* 16 KB */ 6 6 #define BOOT_LOADER_LBA 2 7 7 #define PHDR_ARRAY_SIZE 16 -
trunk/softs/tsar_boot/src/boot_elf_loader.c
r415 r425 1 1 /** 2 * \file : boot_ loader_entry.c2 * \file : boot_elf_loader.c 3 3 * \date : August 2012 4 4 * \author : Cesar Fuguet … … 13 13 #include <elf-types.h> 14 14 #include <boot_tty.h> 15 #include <boot_ memcpy.h>15 #include <boot_utils.h> 16 16 #include <defs.h> 17 18 #if (BOOT_DEBUG == 1) 19 static char* init_state_str[] = { 20 "ELF_HEADER_STATE", 21 "ELF_PROGRAM_HEADER_STATE", 22 "ELF_OFFSET_STATE", 23 "ELF_SEGMENT_STATE", 24 "ELF_END_STATE" 25 }; 26 #endif 17 27 18 28 void * boot_elf_loader(unsigned int lba) 19 29 { 20 /* *30 /* 21 31 * Temporary variables used by the boot loader 22 32 */ … … 26 36 27 37 unsigned char * buffer_ptr; 28 Elf32_Ehdr * elf_ header_ptr;29 Elf32_Phdr * elf_ph t_ptr;38 Elf32_Ehdr * elf_ehdr_ptr; 39 Elf32_Phdr * elf_phdr_ptr; 30 40 31 41 unsigned int nb_available; … … 34 44 unsigned int nb_block; 35 45 unsigned int offset; 46 47 unsigned char * pseg_ptr; 48 unsigned int pseg_start; 49 unsigned int pseg_end; 50 unsigned int pseg_remainder; 36 51 unsigned int pseg; 37 unsigned int i;38 unsigned int segment_req;39 52 40 53 /* 41 54 * Loader state machine definition 42 55 */ 43 enum56 typedef enum 44 57 { 45 58 ELF_HEADER_STATE, … … 48 61 ELF_SEGMENT_STATE, 49 62 ELF_END_STATE 50 } init_state 51 #if (BOOT_DEBUG ==1) 52 , init_state_debug 53 #endif 54 ; 55 56 #if (BOOT_DEBUG == 1) 57 char* init_state_str[] = { 58 "ELF_HEADER_STATE", 59 "ELF_PROGRAM_HEADER_STATE", 60 "ELF_OFFSET_STATE", 61 "ELF_SEGMENT_STATE", 62 "ELF_END_STATE" 63 }; 64 #endif 65 63 } elf_loader_t; 64 65 elf_loader_t init_state; 66 init_state = ELF_HEADER_STATE; 67 68 #if (BOOT_DEBUG == 1) 69 elf_loader_t init_state_debug; 70 init_state_debug = ELF_END_STATE; 71 #endif 66 72 67 73 boot_puts("Starting boot_elf_loader function...\n\r"); 68 74 69 nb_block = lba; 70 71 pseg = 0; 72 nb_available = 0; 73 nb_rest = sizeof(Elf32_Ehdr); 74 offset = 0; 75 76 elf_header_ptr = (Elf32_Ehdr *) &elf_header; 77 elf_pht_ptr = (Elf32_Phdr *) &elf_pht[0]; 78 79 init_state = ELF_HEADER_STATE; 80 #if (BOOT_DEBUG == 1) 81 init_state_debug = ELF_END_STATE; 82 #endif 75 nb_block = lba; 76 nb_available = 0; 77 nb_rest = sizeof(Elf32_Ehdr); 78 pseg = 0; 79 offset = 0; 80 elf_ehdr_ptr = (Elf32_Ehdr *) &elf_header; 81 elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0]; 83 82 84 83 while(init_state != ELF_END_STATE) 85 84 { 86 if (nb_available == 0 )85 if (nb_available == 0 ) 87 86 { 88 87 buffer_ptr = &boot_elf_loader_buffer[0]; 89 88 90 if ( boot_ioc_read(nb_block , buffer_ptr, 1))89 if (boot_ioc_read(nb_block , buffer_ptr, 1)) 91 90 { 92 91 boot_puts ( 93 92 "ERROR: " 94 " IOC_FAILED"93 "boot_ioc_read() failed" 95 94 "\n" 96 95 ); … … 118 117 switch(init_state) 119 118 { 120 /* *119 /* 121 120 * Reading ELF executable header 122 121 */ 123 122 case ELF_HEADER_STATE: 124 boot_memcpy(elf_header_ptr, buffer_ptr, nb_read);123 memcpy(elf_ehdr_ptr, buffer_ptr, nb_read); 125 124 126 125 nb_rest -= nb_read; … … 128 127 if(nb_rest == 0) 129 128 { 130 nb_rest = elf_header_ptr->e_phnum * elf_header_ptr->e_phentsize; 131 132 /* Verification of ELF Magic Number */ 133 if ( 134 (elf_header_ptr->e_ident[EI_MAG0] != ELFMAG0) || 135 (elf_header_ptr->e_ident[EI_MAG1] != ELFMAG1) || 136 (elf_header_ptr->e_ident[EI_MAG2] != ELFMAG2) || 137 (elf_header_ptr->e_ident[EI_MAG3] != ELFMAG3) ) 129 nb_rest = elf_ehdr_ptr->e_phnum * elf_ehdr_ptr->e_phentsize; 130 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 138 { 139 139 boot_puts( … … 150 150 * smaller than the work size allocated for the 151 151 * elf_pht[PHDR_ARRAY_SIZE] array 152 * */153 if (elf_ header_ptr->e_phnum > PHDR_ARRAY_SIZE)152 */ 153 if (elf_ehdr_ptr->e_phnum > PHDR_ARRAY_SIZE) 154 154 { 155 155 boot_puts( 156 156 "ERROR: " 157 "ELF PHDR table size is bigger than "158 " the allocatedwork space"157 "ELF PHDR table size is bigger than the allocated" 158 "work space" 159 159 "\n" 160 160 ); … … 168 168 break; 169 169 170 /* *170 /* 171 171 * Reading ELF program headers 172 172 */ 173 173 case ELF_PROGRAM_HEADER_STATE: 174 boot_memcpy(elf_pht_ptr, buffer_ptr, nb_read); 175 176 elf_pht_ptr = (Elf32_Phdr *)((unsigned char *) elf_pht_ptr + nb_read); 177 nb_rest -= nb_read; 174 memcpy(elf_phdr_ptr, buffer_ptr, nb_read); 175 176 elf_phdr_ptr = 177 (Elf32_Phdr *)((unsigned char *) elf_phdr_ptr + nb_read); 178 179 nb_rest -= nb_read; 178 180 179 181 if(nb_rest == 0) 180 182 { 181 elf_ph t_ptr = (Elf32_Phdr *) &elf_pht[0];183 elf_phdr_ptr = (Elf32_Phdr *) &elf_pht[0]; 182 184 183 185 /* 184 186 * Search the first not NULL segment in the ELF file 185 187 */ 186 for (pseg = 0; pseg < elf_ header_ptr->e_phnum; pseg++)187 { 188 if(elf_ph t_ptr[pseg].p_type == PT_LOAD)188 for (pseg = 0; pseg < elf_ehdr_ptr->e_phnum; pseg++) 189 { 190 if(elf_phdr_ptr[pseg].p_type == PT_LOAD) 189 191 { 190 192 #if (BOOT_DEBUG == 1) 191 boot_puts("found a loadable segment:"); 192 boot_puts("\n- type : "); boot_putx(elf_pht_ptr[pseg].p_type); 193 boot_puts("\n- offset : "); boot_putx(elf_pht_ptr[pseg].p_offset); 194 boot_puts("\n- vaddr : "); boot_putx(elf_pht_ptr[pseg].p_vaddr); 195 boot_puts("\n- paddr : "); boot_putx(elf_pht_ptr[pseg].p_paddr); 196 boot_puts("\n- filesz : "); boot_putx(elf_pht_ptr[pseg].p_filesz); 197 boot_puts("\n- memsz : "); boot_putx(elf_pht_ptr[pseg].p_memsz); 198 boot_puts("\n- flags : "); boot_putx(elf_pht_ptr[pseg].p_flags); 199 boot_puts("\n- align : "); boot_putx(elf_pht_ptr[pseg].p_align); 200 #endif 201 if (elf_pht_ptr[pseg].p_offset < offset) 193 boot_puts("loadable segment found:\n"); 194 boot_print_elf_phdr(&elf_phdr_ptr[pseg]); 195 #endif 196 if (elf_phdr_ptr[pseg].p_offset < offset) 202 197 { 203 198 /* 204 * Case where the segment to load includes the elf205 * and program headers206 * */207 nb_rest = elf_ph t_ptr[pseg].p_filesz - offset;199 * Case where the segment to load includes the 200 * elf and program headers 201 */ 202 nb_rest = elf_phdr_ptr[pseg].p_filesz - offset; 208 203 init_state = ELF_SEGMENT_STATE; 209 204 } … … 212 207 /* 213 208 * Segment to load is further away in ELF file 214 * */215 nb_rest = elf_ph t_ptr[pseg].p_offset - offset;209 */ 210 nb_rest = elf_phdr_ptr[pseg].p_offset - offset; 216 211 init_state = ELF_OFFSET_STATE; 217 212 } … … 220 215 } 221 216 222 if (pseg == elf_ header_ptr->e_phnum)217 if (pseg == elf_ehdr_ptr->e_phnum) 223 218 { 224 219 boot_puts( … … 234 229 break; 235 230 236 /* *231 /* 237 232 * Go to the offset of the first not null program segment in the 238 233 * ELF file 234 * 235 * TODO: 236 * No need to read from the disk the useless bytes. Try to compute 237 * the next usefull lba 239 238 */ 240 239 case ELF_OFFSET_STATE: … … 243 242 if (nb_rest == 0) 244 243 { 245 nb_rest = elf_ph t_ptr[pseg].p_filesz;244 nb_rest = elf_phdr_ptr[pseg].p_filesz; 246 245 init_state = ELF_SEGMENT_STATE; 247 246 } … … 249 248 break; 250 249 251 /* *250 /* 252 251 * Reading ELF segments 252 * 253 * TODO: 254 * Do not pass by block buffer but write directly in target memory 255 * address 253 256 */ 254 257 case ELF_SEGMENT_STATE: 255 /* *256 * Copying ELF segment data in memory segments using the virtual257 * address got from the ELF file258 /* 259 * Verify that loadable segment does not conflict with 260 * pre-loader memory space 258 261 */ 259 segment_req = ((elf_pht_ptr[pseg].p_vaddr & 0xBFC00000) != 0xBFC00000); 260 261 if ( segment_req ) 262 { 263 boot_memcpy((unsigned char *) elf_pht_ptr[pseg].p_vaddr + 264 (elf_pht_ptr[pseg].p_filesz - nb_rest), 265 buffer_ptr, 266 nb_read); 267 } 262 pseg_start = elf_phdr_ptr[pseg].p_vaddr; 263 264 pseg_end = elf_phdr_ptr[pseg].p_vaddr + 265 elf_phdr_ptr[pseg].p_memsz; 266 267 if ((pseg_start >= 0xBFC00000 && pseg_start <= 0xBFC10000) || 268 (pseg_end >= 0xBFC00000 && pseg_end <= 0xBFC10000) || 269 (pseg_start < 0xBFC00000 && pseg_end > 0xBFC10000)) 270 { 271 boot_puts( 272 "ERROR: " 273 "Program segment conflits with pre-loader memory space" 274 "\n" 275 ); 276 boot_exit(); 277 } 278 279 /* 280 * Copy the ELF segment data in memory using the 281 * virtual address obtained from the ELF file 282 */ 283 pseg_ptr = (unsigned char *) 284 elf_phdr_ptr[pseg].p_vaddr + 285 elf_phdr_ptr[pseg].p_filesz - 286 nb_rest; 287 288 memcpy(pseg_ptr, buffer_ptr, nb_read); 268 289 269 290 nb_rest -= nb_read; 270 291 271 if ( nb_rest == 0 ) 272 { 273 if ( segment_req ) 274 { 275 boot_puts("Copied segment at address "); 276 boot_putx(elf_pht_ptr[pseg].p_vaddr); 277 boot_puts("\n"); 278 279 /* 280 * Fill remaining bytes with zeros (filesz < memsz) 281 */ 282 for ( i = 0 ; 283 i < (elf_pht_ptr[pseg].p_memsz - elf_pht_ptr[pseg].p_filesz) ; 284 i-- ) 292 if (nb_rest == 0) 293 { 294 /* 295 * Fill remaining bytes with zeros (filesz < memsz) 296 */ 297 pseg_remainder = 298 elf_phdr_ptr[pseg].p_memsz - 299 elf_phdr_ptr[pseg].p_filesz ; 300 301 pseg_ptr = (unsigned char *) 302 elf_phdr_ptr[pseg].p_vaddr + 303 elf_phdr_ptr[pseg].p_filesz ; 304 305 memset(pseg_ptr, 0, pseg_remainder); 306 307 boot_puts("Copied segment at address "); 308 boot_putx(elf_phdr_ptr[pseg].p_vaddr); 309 boot_puts("\n"); 310 311 /* 312 * Search the next first not NULL segment in the ELF file 313 */ 314 for (pseg += 1; pseg < elf_ehdr_ptr->e_phnum; pseg++) 315 { 316 if(elf_phdr_ptr[pseg].p_type == PT_LOAD) 285 317 { 286 *(unsigned char *) 287 (elf_pht_ptr[pseg].p_vaddr + elf_pht_ptr[pseg].p_filesz + i) = 0; 288 } 289 } 290 291 /* 292 * Search the first not NULL segment in the ELF file 293 */ 294 for ( pseg = pseg + 1; pseg < elf_header_ptr->e_phnum; pseg++) { 295 if(elf_pht_ptr[pseg].p_type == PT_LOAD) 296 { 297 nb_rest = elf_pht_ptr[pseg].p_offset - offset; 318 #if (BOOT_DEBUG == 1) 319 boot_puts("loadable segment found:\n"); 320 boot_print_elf_phdr(&elf_phdr_ptr[pseg]); 321 #endif 322 nb_rest = elf_phdr_ptr[pseg].p_offset - offset; 298 323 break; 299 324 } … … 303 328 * Program loading finished 304 329 */ 305 if(pseg == elf_ header_ptr->e_phnum)330 if(pseg == elf_ehdr_ptr->e_phnum) 306 331 { 307 332 init_state = ELF_END_STATE; … … 317 342 } 318 343 319 buffer_ptr 320 nb_available 344 buffer_ptr += nb_read; 345 nb_available -= nb_read; 321 346 } 322 347 … … 325 350 "Entry point address: " 326 351 ); 327 boot_putx(elf_header_ptr->e_entry); 352 353 boot_putx(elf_ehdr_ptr->e_entry); 328 354 boot_puts("\n"); 329 355 330 return ((void *) elf_ header_ptr->e_entry);356 return ((void *) elf_ehdr_ptr->e_entry); 331 357 } 358 359 // vim: tabstop=4 : softtabstop=4 : shiftwidth=4 : expandtab -
trunk/softs/tsar_boot/src/boot_ioc.c
r412 r425 5 5 static struct sdcard_dev _sdcard_device; 6 6 static struct spi_dev * _spi_device = ( struct spi_dev * )IOC_BASE; 7 8 #ifndef SYSCLK_FREQ9 #warning "Using default value for SYSCLK_FREQ = 50000000"10 #define SYSCLK_FREQ 50000000U11 #endif // end ifndef SYSCLK_FREQ12 7 13 8 #endif // end ifndef SOCLIB_IOC … … 266 261 267 262 // iterate on cache lines 268 for (i = 0; i < size; i += line_size) {263 for (i = 0; i <= size; i += line_size) { 269 264 asm volatile( 270 265 " cache %0, %1" -
trunk/softs/tsar_boot/src/reset.S
r349 r425 34 34 .extern boot_ioc_read 35 35 .extern boot_elf_loader 36 .extern boot_memcpy36 .extern memcpy 37 37 .extern boot_puts 38 38 .extern boot_putx … … 58 58 .word boot_ioc_read /* 0xbfc0018 */ 59 59 .word boot_elf_loader /* 0xbfc001C */ 60 .word boot_memcpy/* 0xbfc0020 */60 .word memcpy /* 0xbfc0020 */ 61 61 .word boot_puts /* 0xbfc0024 */ 62 62 .word boot_putx /* 0xbfc0028 */
Note: See TracChangeset
for help on using the changeset viewer.