diff --git a/Makefile b/Makefile index 6a2b84e..74cb99d 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ RAW=${OBJCOPY} --strip-unneeded --alt-machine-code ${MACHCODE} INCLUDE=-Iinclude/ -Imach/${TARGET} -Iinclude/mach/${TARGET} -CFLAGS=-fno-builtin -fomit-frame-pointer -fno-pic -mno-abicalls \ +CFLAGS+=-fno-builtin -fomit-frame-pointer -fno-pic -mno-abicalls \ -Wall ASFLAGS=-D__ASSEMBLY__-xassembler-with-cpp -traditional-cpp diff --git a/elf_loader.c b/elf_loader.c index 4862a1c..d0c33f5 100644 --- a/elf_loader.c +++ b/elf_loader.c @@ -26,6 +26,11 @@ void load_elf32_section(struct file *fp, uint32_t address, uint32_t file_offset, uint32_t length) { uint8_t *elf_loc = (uint8_t *)address; + +#ifdef DEBUG + printf("Init data: %08x length %08x\n", address, length); +#endif + cilo_seek(fp, file_offset, SEEK_SET); cilo_read(elf_loc, length, 1, fp); @@ -41,6 +46,10 @@ void load_elf32_uninitialized_memory(uint32_t address, uint32_t length) int i = 0; uint8_t *p = (uint8_t *)address; +#ifdef DEBUG + printf("Uninit data: %08x, len %08x\n", address, length); +#endif + for (i = 0; i < length; i++) { p[i] = 0; } @@ -98,6 +107,7 @@ int load_elf32_file(struct file *fp) int i; struct elf32_phdr phdr; + uint32_t offset = 0xffffffff; cilo_seek(fp, hdr.phoff, SEEK_SET); /* read in program header(s), determine total memory size of image */ @@ -105,11 +115,18 @@ int load_elf32_file(struct file *fp) for (i = 0; i < hdr.phnum; i++) { cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp); + if (phdr.type != ELF_PT_LOAD) continue; + mem_sz += phdr.memsz; + + if (phdr.paddr < offset) offset = phdr.paddr; } - /* read the PT_LOAD segments into memory at paddr + mem_sz - */ +#ifdef DEBUG + printf("mem_sz = %08x\n", mem_sz); +#endif + + /* read the PT_LOAD segments into memory at paddr + mem_sz */ cilo_seek(fp, hdr.phoff, SEEK_SET); for (i = 0; i < hdr.phnum; i++) { cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp); @@ -117,34 +134,35 @@ int load_elf32_file(struct file *fp) /* skip unloadable segments */ if (phdr.type != ELF_PT_LOAD) continue; - uint32_t leftover = phdr.memsz - phdr.filesz; + /* uint32_t leftover = phdr.memsz - phdr.filesz; */ load_elf32_section(fp, mem_sz + phdr.paddr, phdr.offset, phdr.filesz); - if (leftover > 0) { +/* if (leftover > 0) { load_elf32_uninitialized_memory(mem_sz + phdr.paddr + phdr.filesz, leftover); - } + } */ cilo_seek(fp, hdr.phoff + sizeof(struct elf32_phdr) * (i + 1), SEEK_SET); } /* assume the entry point is the smallest address we're loading */ - uint32_t load_offset = mem_sz + hdr.entry; + uint32_t load_offset = mem_sz + offset; printf("Loaded %d bytes at %08x.\n", mem_sz, load_offset); printf("Kicking into Linux.\n"); #ifdef DEBUG - printf("bootcpy: %08x, kdataoffset: %08x, kdatalength: %08x\n", - loader_addr, load_offset, mem_sz); - printf("kentrypt: %08x, kloadoffset: %08x\n", hdr.entry, hdr.entry); + printf("load_offset = 0x%08x\n", load_offset); + printf("hdr.entry = 0x%08x\n", hdr.entry); + printf("mem_sz = 0x%08x\n", mem_sz); + printf("offset = 0x%08x\n", offset); #endif /* Jump to the copy routine */ - stage_two(load_offset, hdr.entry, mem_sz); + stage_two(load_offset, hdr.entry, mem_sz, offset); return -1; /* something failed, badly */ } diff --git a/include/mach/c3600/platform.h b/include/mach/c3600/platform.h index ce47efe..af0b338 100644 --- a/include/mach/c3600/platform.h +++ b/include/mach/c3600/platform.h @@ -11,6 +11,7 @@ void platform_init(); uint32_t check_flash(); void flash_directory(); uint32_t locate_stage_two(); -void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size); +void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size, + uint32_t kern_loadpt); #endif /* _INCLUDE_MACH_C3600_PLATFORM_H */ diff --git a/mach/c3600/platform.c b/mach/c3600/platform.c index f15dad0..5ebb2e0 100644 --- a/mach/c3600/platform.c +++ b/mach/c3600/platform.c @@ -55,7 +55,8 @@ uint32_t locate_stage_two() /** * Kick into the stage two loader. */ -void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size) +void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size, + uint32_t kern_loadpt) { uint32_t s2addr = ((uint32_t)find_file("ciscoload.two", FLASH_BASE)) + sizeof(struct fs_ent); @@ -63,6 +64,6 @@ void stage_two(uint32_t kern_off, uint32_t kern_entry, uint32_t kern_size) ((void (*)(uint32_t data_offset, uint32_t data_length, uint32_t entry_pt, uint32_t load_offset)) (s2addr)) - (kern_off, kern_size, kern_entry, kern_entry); + (kern_off, kern_size, kern_entry, kern_loadpt); } diff --git a/second/kcopy.S b/second/kcopy.S index 4837732..0194ae9 100644 --- a/second/kcopy.S +++ b/second/kcopy.S @@ -1,6 +1,7 @@ /* Re-copy kernel image from given offset in a0 (length a1), and then * jump to entry point contained in a2. Copies data to location pointed * to in a3 + * void kload(memory_start, memory_length, entry_point, copy_start) * Very naive. * ------------------------------------------------------------------ * (c) 2008 Philippe Vachon @@ -26,6 +27,17 @@ LEAF(_start) .set noreorder .set mips3 + /* invalidate the caches */ + li k0, KSEG0 + addi k1, k0, CACHE_SIZE + +2: cache ICACHE_INVALIDATE, 0(k0) + cache DCACHE_WRITEBACK_INVALIDATE, 0(k0) + + ble k0, k1, 2b + addi k0, CACHE_LINE_LEN + + 1: lw s0, 0(a0) # load byte from address pointed to in a0 sw s0, 0(a3) # copy byte to address pointed to in a3 @@ -45,19 +57,9 @@ LEAF(_start) li sp, KSEG0 add sp, sp, v0 - /* invalidate the caches */ - li k0, KSEG0 - addi k1, k0, CACHE_SIZE - -2: cache ICACHE_INVALIDATE, 0(k0) - cache DCACHE_WRITEBACK_INVALIDATE, 0(k0) - - ble k0, k1, 2b - addi k0, CACHE_LINE_LEN - /* set SR(BEV) = 0 */ mfc0 k0, CP0_STATUS - nop + nop /* fix... me... please */ li k1, 0xFFBFFFFF and k0, k1 @@ -69,7 +71,6 @@ LEAF(_start) li a3, 0 li v0, 0 - jr a2 # jump to kernel entry point nop