Fixed critical bugs in CiscoLoad.

master
Philippe Vachon 16 years ago
parent 04d5e09efb
commit e4c03b7f4e

@ -42,7 +42,7 @@ RAW=${OBJCOPY} --strip-unneeded --alt-machine-code ${MACHCODE}
INCLUDE=-Iinclude/ -Imach/${TARGET} -Iinclude/mach/${TARGET} 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 -Wall
ASFLAGS=-D__ASSEMBLY__-xassembler-with-cpp -traditional-cpp ASFLAGS=-D__ASSEMBLY__-xassembler-with-cpp -traditional-cpp

@ -26,6 +26,11 @@ void load_elf32_section(struct file *fp, uint32_t address,
uint32_t file_offset, uint32_t length) uint32_t file_offset, uint32_t length)
{ {
uint8_t *elf_loc = (uint8_t *)address; 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_seek(fp, file_offset, SEEK_SET);
cilo_read(elf_loc, length, 1, fp); 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; int i = 0;
uint8_t *p = (uint8_t *)address; uint8_t *p = (uint8_t *)address;
#ifdef DEBUG
printf("Uninit data: %08x, len %08x\n", address, length);
#endif
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
p[i] = 0; p[i] = 0;
} }
@ -98,6 +107,7 @@ int load_elf32_file(struct file *fp)
int i; int i;
struct elf32_phdr phdr; struct elf32_phdr phdr;
uint32_t offset = 0xffffffff;
cilo_seek(fp, hdr.phoff, SEEK_SET); cilo_seek(fp, hdr.phoff, SEEK_SET);
/* read in program header(s), determine total memory size of image */ /* 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++) { for (i = 0; i < hdr.phnum; i++) {
cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp); cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp);
if (phdr.type != ELF_PT_LOAD) continue;
mem_sz += phdr.memsz; 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); cilo_seek(fp, hdr.phoff, SEEK_SET);
for (i = 0; i < hdr.phnum; i++) { for (i = 0; i < hdr.phnum; i++) {
cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp); cilo_read(&phdr, sizeof(struct elf32_phdr), 1, fp);
@ -117,34 +134,35 @@ int load_elf32_file(struct file *fp)
/* skip unloadable segments */ /* skip unloadable segments */
if (phdr.type != ELF_PT_LOAD) continue; 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, load_elf32_section(fp, mem_sz + phdr.paddr,
phdr.offset, phdr.filesz); phdr.offset, phdr.filesz);
if (leftover > 0) { /* if (leftover > 0) {
load_elf32_uninitialized_memory(mem_sz + phdr.paddr + load_elf32_uninitialized_memory(mem_sz + phdr.paddr +
phdr.filesz, leftover); phdr.filesz, leftover);
} } */
cilo_seek(fp, hdr.phoff + sizeof(struct elf32_phdr) * (i + 1), cilo_seek(fp, hdr.phoff + sizeof(struct elf32_phdr) * (i + 1),
SEEK_SET); SEEK_SET);
} }
/* assume the entry point is the smallest address we're loading */ /* 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("Loaded %d bytes at %08x.\n", mem_sz, load_offset);
printf("Kicking into Linux.\n"); printf("Kicking into Linux.\n");
#ifdef DEBUG #ifdef DEBUG
printf("bootcpy: %08x, kdataoffset: %08x, kdatalength: %08x\n", printf("load_offset = 0x%08x\n", load_offset);
loader_addr, load_offset, mem_sz); printf("hdr.entry = 0x%08x\n", hdr.entry);
printf("kentrypt: %08x, kloadoffset: %08x\n", hdr.entry, hdr.entry); printf("mem_sz = 0x%08x\n", mem_sz);
printf("offset = 0x%08x\n", offset);
#endif #endif
/* Jump to the copy routine */ /* 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 */ return -1; /* something failed, badly */
} }

@ -11,6 +11,7 @@ void platform_init();
uint32_t check_flash(); uint32_t check_flash();
void flash_directory(); void flash_directory();
uint32_t locate_stage_two(); 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 */ #endif /* _INCLUDE_MACH_C3600_PLATFORM_H */

@ -55,7 +55,8 @@ uint32_t locate_stage_two()
/** /**
* Kick into the stage two loader. * 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)) + uint32_t s2addr = ((uint32_t)find_file("ciscoload.two", FLASH_BASE)) +
sizeof(struct fs_ent); 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, ((void (*)(uint32_t data_offset, uint32_t data_length, uint32_t entry_pt,
uint32_t load_offset)) (s2addr)) uint32_t load_offset)) (s2addr))
(kern_off, kern_size, kern_entry, kern_entry); (kern_off, kern_size, kern_entry, kern_loadpt);
} }

@ -1,6 +1,7 @@
/* Re-copy kernel image from given offset in a0 (length a1), and then /* 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 * jump to entry point contained in a2. Copies data to location pointed
* to in a3 * to in a3
* void kload(memory_start, memory_length, entry_point, copy_start)
* Very naive. * Very naive.
* ------------------------------------------------------------------ * ------------------------------------------------------------------
* (c) 2008 Philippe Vachon <philippe@cowpig.ca> * (c) 2008 Philippe Vachon <philippe@cowpig.ca>
@ -26,6 +27,17 @@ LEAF(_start)
.set noreorder .set noreorder
.set mips3 .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 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 sw s0, 0(a3) # copy byte to address pointed to in a3
@ -45,19 +57,9 @@ LEAF(_start)
li sp, KSEG0 li sp, KSEG0
add sp, sp, v0 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 */ /* set SR(BEV) = 0 */
mfc0 k0, CP0_STATUS mfc0 k0, CP0_STATUS
nop nop
/* fix... me... please */ /* fix... me... please */
li k1, 0xFFBFFFFF li k1, 0xFFBFFFFF
and k0, k1 and k0, k1
@ -69,7 +71,6 @@ LEAF(_start)
li a3, 0 li a3, 0
li v0, 0 li v0, 0
jr a2 # jump to kernel entry point jr a2 # jump to kernel entry point
nop nop

Loading…
Cancel
Save