/* should be the first function */ void entry(unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize, unsigned long fw_arg0, unsigned long fw_arg1, unsigned long fw_arg2, unsigned long fw_arg3) { CLzmaDec state; ISzAlloc dummy; ISeqInStream stream; ELzmaStatus status; unsigned int i; /* temp value */ unsigned int osize; /* uncompressed size */ dummy.Alloc = dummy_alloc; dummy.Free = dummy_free; stream.Read = read_bytes; /* look for trx header, 32-bit data access */ for (data = ((unsigned char *)KSEG1ADDR(BCM4710_FLASH)); ((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536); /* compressed kernel is in the partition 1 */ data += ((struct trx_header *)data)->offsets[1]; offset = 0; /* read lzma stream header */ SeqInStream_Read(&stream, workspace, LZMA_PROPS_SIZE + 8); /* read the lower half of uncompressed size in the header */ osize = (workspace[LZMA_PROPS_SIZE + 0]) + (workspace[LZMA_PROPS_SIZE + 1] << 8) + (workspace[LZMA_PROPS_SIZE + 2] << 16) + (workspace[LZMA_PROPS_SIZE + 3] << 24); LzmaDec_Construct(&state); LzmaDec_AllocateProbs(&state, workspace, LZMA_PROPS_SIZE, &dummy); state.dic = (unsigned char *)LOADADDR; state.dicBufSize = osize; /* decompress kernel */ LzmaDec_Init(&state); do { i = LZMA_REQUIRED_INPUT_MAX; SeqInStream_Read(&stream, workspace, i); if (LzmaDec_DecodeToDic(&state, osize, workspace, &i, LZMA_FINISH_ANY, &status) != SZ_OK) { /* something went wrong */ return; } } while (status == LZMA_STATUS_NEEDS_MORE_INPUT); blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); /* jump to load address */ ((void (*)(unsigned long, unsigned long, unsigned long, unsigned long))LOADADDR)(fw_arg0, fw_arg1, fw_arg2, fw_arg3); }
/* should be the first function */ void entry(unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize) { /* clear the bss */ long *bssp; /* clear the bss */ for (bssp = bss_start; bssp != bss_end; bssp++) *bssp = 0; unsigned int i; /* temp value */ unsigned int osize; /* uncompressed size */ ILzmaInCallback callback; CLzmaDecoderState vs; callback.Read = read_byte; puts("Atheros WiSOC DD-WRT LZMA Kernel Loader ("); puts(__DATE__); puts(")\n"); puts("decompressing"); data = lzma_start; /* lzma args */ i = get_byte(); vs.Properties.lc = i % 9, i = i / 9; vs.Properties.lp = i % 5, vs.Properties.pb = i / 5; vs.Probs = (CProb *)buffer; /* skip rest of the LZMA coder property */ for (i = 0; i < 4; i++) get_byte(); /* read the lower half of uncompressed size in the header */ osize = ((unsigned int)get_byte()) + ((unsigned int)get_byte() << 8) + ((unsigned int)get_byte() << 16) + ((unsigned int)get_byte() << 24); /* skip rest of the header (upper half of uncompressed size) */ for (i = 0; i < 4; i++) get_byte(); /* decompress kernel */ if ((i = LzmaDecode(&vs, &callback, (unsigned char*)KERNEL_ENTRY, osize, &osize)) == LZMA_RESULT_OK) { puts("\ndone.\njump to kernel...\n"); blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); /* Jump to load address */ ((void (*)(unsigned long, unsigned long, unsigned long)) KERNEL_ENTRY) (linux_args[0], linux_args[1], linux_args[2]); } puts("Fatal error while decompressing!\n"); }
/* should be the first function */ void entry(unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize) { unsigned int i; /* temp value */ unsigned int lc; /* literal context bits */ unsigned int lp; /* literal pos state bits */ unsigned int pb; /* pos state bits */ unsigned int osize; /* uncompressed size */ ILzmaInCallback callback; callback.Read = read_byte; /* look for trx header, 32-bit data access */ for (data = ((unsigned char *) KSEG1ADDR(BCM4710_FLASH)); ((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536); /* compressed kernel is in the partition 0 or 1 */ if (((struct trx_header *)data)->offsets[1] > 65536) data += ((struct trx_header *)data)->offsets[0]; else data += ((struct trx_header *)data)->offsets[1]; offset = 0; /* lzma args */ i = get_byte(); lc = i % 9, i = i / 9; lp = i % 5, pb = i / 5; /* skip rest of the LZMA coder property */ for (i = 0; i < 4; i++) get_byte(); /* read the lower half of uncompressed size in the header */ osize = ((unsigned int)get_byte()) + ((unsigned int)get_byte() << 8) + ((unsigned int)get_byte() << 16) + ((unsigned int)get_byte() << 24); /* skip rest of the header (upper half of uncompressed size) */ for (i = 0; i < 4; i++) get_byte(); /* decompress kernel */ if (LzmaDecode(workspace, ~0, lc, lp, pb, &callback, (unsigned char*)LOADADDR, osize, &i) == LZMA_RESULT_OK) { blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); /* Jump to load address */ ((void (*)(void)) LOADADDR)(); } }
/* should be the first function */ void entry(unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize, unsigned long fw_arg0, unsigned long fw_arg1, unsigned long fw_arg2, unsigned long fw_arg3) { unsigned int i; /* temp value */ unsigned int osize; /* uncompressed size */ CLzmaDecoderState vs; ILzmaInCallback callback; callback.Read = read_byte; /* look for trx header, 32-bit data access */ for (data = ((unsigned char *) KSEG1ADDR(BCM4710_FLASH)); ((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536); /* compressed kernel is in the partition 1 */ data += ((struct trx_header *)data)->offsets[1]; offset = 0; /* lzma args */ i = get_byte(); vs.Properties.lc = i % 9, i = i / 9; vs.Properties.lp = i % 5, vs.Properties.pb = i / 5; vs.Probs = (CProb *)workspace; /* skip rest of the LZMA coder property */ for (i = 0; i < 4; i++) get_byte(); /* read the lower half of uncompressed size in the header */ osize = ((unsigned int)get_byte()) + ((unsigned int)get_byte() << 8) + ((unsigned int)get_byte() << 16) + ((unsigned int)get_byte() << 24); /* skip rest of the header (upper half of uncompressed size) */ for (i = 0; i < 4; i++) get_byte(); /* decompress kernel */ if (LzmaDecode(&vs, &callback, (unsigned char*)LOADADDR, osize, &i) == LZMA_RESULT_OK) { blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); /* Jump to load address */ ((void (*)(unsigned long, unsigned long, unsigned long, unsigned long)) LOADADDR)(fw_arg0, fw_arg1, fw_arg2, fw_arg3); } }
void caches_on(void) { uint32 config1; uint start, end, size, lsize; /* Save cache config */ config1 = MFC0(C0_CONFIG, 1); icache_probe(config1, &size, &lsize); icache_size = size; ic_lsize = lsize; dcache_probe(config1, &size, &lsize); dcache_size = size; dc_lsize = lsize; /* If caches are not in the default state then * presume that caches are already init'd */ if ((MFC0(C0_CONFIG, 0) & CONF_CM_CMASK) != CONF_CM_UNCACHED) { blast_dcache(); blast_icache(); return; } /* init icache */ start = KSEG0; end = (start + icache_size); MTC0(C0_TAGLO, 0, 0); MTC0(C0_TAGHI, 0, 0); while (start < end) { cache_op(start, Index_Store_Tag_I); start += ic_lsize; } /* init dcache */ start = KSEG0; end = (start + dcache_size); MTC0(C0_TAGLO, 0, 0); MTC0(C0_TAGHI, 0, 0); while (start < end) { cache_op(start, Index_Store_Tag_D); start += dc_lsize; } /* Must be in KSEG1 to change cachability */ change_cachability = (void (*)(uint32)) KSEG1ADDR(_change_cachability); change_cachability(CONF_CM_CACHABLE_NONCOHERENT); }
/* should be the first function */ void decompress_entry(unsigned long reg_a0, unsigned long reg_a1, unsigned long reg_a2, unsigned long reg_a3, unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize) { unsigned char props[LZMA_PROPERTIES_SIZE]; unsigned int i; /* temp value */ SizeT osize; /* uncompressed size */ int res; board_init(); printf("\n\nLZMA loader for " CONFIG_BOARD_NAME ", Copyright (C) 2007-2008 OpenWrt.org\n\n"); decompress_init(); /* lzma args */ for (i = 0; i < LZMA_PROPERTIES_SIZE; i++) props[i] = get_byte(); /* skip rest of the LZMA coder property */ /* read the lower half of uncompressed size in the header */ osize = ((SizeT)get_byte()) + ((SizeT)get_byte() << 8) + ((SizeT)get_byte() << 16) + ((SizeT)get_byte() << 24); /* skip rest of the header (upper half of uncompressed size) */ for (i = 0; i < 4; i++) get_byte(); res = LzmaDecodeProperties(&lzma_state.Properties, props, LZMA_PROPERTIES_SIZE); if (res != LZMA_RESULT_OK) { printf("Incorrect LZMA stream properties!\n"); halt(); } printf("decompressing kernel... "); lzma_state.Probs = (CProb *)workspace; res = decompress_data(&lzma_state, (unsigned char *)LOADADDR, osize); if (res != LZMA_RESULT_OK) { printf("failed, "); switch (res) { case LZMA_RESULT_DATA_ERROR: printf("data error!\n"); break; default: printf("unknown error %d!\n", res); } halt(); } else printf("done!\n"); blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); printf("launching kernel...\n\n"); #ifdef CONFIG_PASS_KARGS reg_a0 = 0; reg_a1 = 0; reg_a2 = (unsigned long)env_vars; reg_a3 = 0; #endif /* Jump to load address */ ((kernel_entry) LOADADDR)(reg_a0, reg_a1, reg_a2, reg_a3); }
/* should be the first function */ void entry(unsigned long icache_size, unsigned long icache_lsize, unsigned long dcache_size, unsigned long dcache_lsize) { unsigned int i; /* temp value */ unsigned int lc; /* literal context bits */ unsigned int lp; /* literal pos state bits */ unsigned int pb; /* pos state bits */ unsigned int osize; /* uncompressed size */ unsigned char SIGN[]="DD-WRT v24-sp2 (c) 2004 - 2011 Sebastian Gottschall / NewMedia-NET GmbH"; /* look for trx header, 32-bit data access */ data = ((unsigned char *) KSEG1ADDR(BCM4710_FLASH)); while(1) { if (((struct trx_header *)data)->magic == TRX_MAGIC) break; if (((struct trx_header *)data)->magic == TRX_MAGIC_F7D3301) break; if (((struct trx_header *)data)->magic == TRX_MAGIC_F7D3302) break; if (((struct trx_header *)data)->magic == TRX_MAGIC_F7D4302) break; if (((struct trx_header *)data)->magic == TRX_MAGIC_F5D8235V3) break; data += 65536; } /* compressed kernel is in the partition 0 or 1 */ if (((struct trx_header *)data)->offsets[1] > 65536) data += ((struct trx_header *)data)->offsets[0]; else data += ((struct trx_header *)data)->offsets[1]; offset = SIGN[0]-'D'; /* lzma args */ i = get_byte(); lc = i % 9, i = i / 9; lp = i % 5, pb = i / 5; /* skip rest of the LZMA coder property */ for (i = 0; i < 4; i++) get_byte(); /* read the lower half of uncompressed size in the header */ osize = ((unsigned int)get_byte()) + ((unsigned int)get_byte() << 8) + ((unsigned int)get_byte() << 16) + ((unsigned int)get_byte() << 24); /* skip rest of the header (upper half of uncompressed size) */ for (i = 0; i < 4; i++) get_byte(); /* decompress kernel */ if (LzmaDecode(workspace, ~0, lc, lp, pb, (unsigned char*)LOADADDR, osize, &i) == LZMA_RESULT_OK) { blast_dcache(dcache_size, dcache_lsize); blast_icache(icache_size, icache_lsize); /* Jump to load address */ ((void (*)(void)) LOADADDR)(); } }