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}
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

@ -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 */
}

@ -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 */

@ -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);
}

@ -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 <philippe@cowpig.ca>
@ -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

Loading…
Cancel
Save