Пример #1
0
int mrdump_detection(void)
{
    struct mrdump_control_block *mrdump_cblock = aee_mrdump_get_params();
    if (mrdump_cblock == NULL) {
        return 0;
    }

    memset(&mrdump_cblock->result, 0, sizeof(struct mrdump_cblock_result));
    cblock_result = &mrdump_cblock->result;

    if (!g_boot_arg->ddr_reserve_enable) {
	voprintf_debug("DDR reserve mode disabled\n");
	mrdump_status_none("DDR reserve mode disabled\n");
	return 0;
    }

    if (!g_boot_arg->ddr_reserve_success) {
	voprintf_debug("DDR reserve mode failed\n");
	mrdump_status_none("DDR reserve mode failed\n");
	return 0;
    }
    uint8_t reboot_mode = mrdump_cblock->crash_record.reboot_mode;
    if (mrdump_cblock->machdesc.nr_cpus == 0) {
	voprintf_debug("Runtime disabled\n");
	mrdump_status_none("Runtime disabled\n");
	return 0;
    }

    voprintf_debug("sram record with mode %d\n", reboot_mode);
    switch (reboot_mode) {
    case AEE_REBOOT_MODE_NORMAL:  {
	if (!ram_console_is_abnormal_boot()) {
	    mrdump_status_none("Normal boot\n");
	    return 0;
	}
	else {
	    /* SoC trigger HW REBOOT */
	    mrdump_cblock->crash_record.reboot_mode = AEE_REBOOT_MODE_WDT;
	    return 1;
	}
    }
    case AEE_REBOOT_MODE_KERNEL_OOPS:
    case AEE_REBOOT_MODE_KERNEL_PANIC:
    case AEE_REBOOT_MODE_NESTED_EXCEPTION:
    case AEE_REBOOT_MODE_WDT:
    case AEE_REBOOT_MODE_EXCEPTION_KDUMP:
      return 1;
    }
    return 0;
}
Пример #2
0
static void mrdump_query_bootinfo(void)
{
    if (mrdump_cb == NULL) {
        struct mrdump_control_block *bufp = (struct mrdump_control_block *)MRDUMP_CB_ADDR;
        if (memcmp(bufp->sig, "MRDUMP01", 8) == 0) {
            voprintf_debug("Boot record found at %p\n", bufp);
            mrdump_cb = bufp;
            bufp->sig[0] = 'X';
            aee_mrdump_flush_cblock();
        }
	else {
            voprintf_debug("No boot record found at %p[%02x%02x]\n", bufp, bufp->sig[0], bufp->sig[1]);
        }
    }
}
Пример #3
0
bool kzip_add_file(struct kzip_file *zfile, const struct kzip_memlist *memlist, const char *zfilename)
{
    int ret, flush;
    z_stream strm;
    struct aee_timer zip_time;

    if (zfile->entries_num >= KZIP_ENTRY_MAX) {
	voprintf_error("Too manry zip entry %d\n", zfile->entries_num);
	return false;
    }

    voprintf_debug("%s: zf %p(%p) %s\n", __func__, zfile, zfile->write_cb, zfilename);
    struct kzip_entry *zentry = &zfile->zentries[zfile->entries_num++];
    zentry->filename = strdup(zfilename);
    zentry->localheader_offset = zfile->current_size;
    zentry->level = DEF_MEM_LEVEL;

    KZIP_DEBUG("%s: write local header\n", __func__);
    uint8_t zip_localheader[128];
    int hsize = put_localheader(zip_localheader, zfilename, DEF_MEM_LEVEL);
    if (kzip_write_current(zfile, zip_localheader, hsize) != hsize) {
        return false;
    }

    KZIP_DEBUG("%s: init compressor\n", __func__);
    /* allocate deflate state */
    strm.workspace = malloc(zlib_deflate_workspacesize(-MAX_WBITS, DEF_MEM_LEVEL));
    ret = zlib_deflateInit2(&strm, zentry->level, Z_DEFLATED, -MAX_WBITS,
			    DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
    if (ret != Z_OK) {
	voprintf_error("zlib compress init failed\n");
	free(strm.workspace);
        return false;
    }

    uint8_t *out = malloc(CHUNK);
 
    aee_timer_init(&zip_time);
    aee_timer_start(&zip_time);
    /* compress until end of file */
    do {
        flush = (memlist->size == 0) ? Z_FINISH : Z_NO_FLUSH;
 	
	KZIP_DEBUG("-- Compress memory %x, size %d\n", memlist->address, memlist->size);
	strm.avail_in = memlist->size;
        strm.next_in = memlist->address;
        /* run deflate() on input until output buffer not full, finish
           compression if all of source has been read in */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = zlib_deflate(&strm, flush);    /* no bad return value */
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            int have = CHUNK - strm.avail_out;
	    if (have > 0) {
                aee_timer_stop(&zip_time);
		if (kzip_write_current(zfile, out, have) != have) {
                    goto error;
		}
                aee_timer_start(&zip_time);
	    }
        } while (strm.avail_out == 0);
        assert(strm.avail_in == 0);     /* all input will be used */

	memlist++;
        /* done when last data in file processed */
    } while (flush != Z_FINISH);
    assert(ret == Z_STREAM_END);        /* stream will be complete */

    /* clean up and return */
    (void)zlib_deflateEnd(&strm);
    free(strm.workspace);
    free(out);
    aee_timer_stop(&zip_time);
    voprintf_info("Zip time: %d sec\n", zip_time.acc_ms / 1000);

    zentry->comp_size = strm.total_out;
    zentry->uncomp_size = strm.total_in;
    zentry->crc32 = strm.crc32 ^ 0xffffffffUL;

    return true;

 error:
    free(strm.workspace);
    free(out);
    (void)zlib_deflateEnd(&strm);
    return false;
}
Пример #4
0
void *kdump_core_header_init(const struct mrdump_control_block *mrdump_cb, uint32_t kmem_address, uint32_t kmem_size)
{
	struct elf_phdr *nhdr, *phdr;
	struct elfhdr *elf;
	off_t offset = 0;
	const struct mrdump_machdesc *kparams = &mrdump_cb->machdesc;

	uint8_t *oldbufp = malloc(KDUMP_CORE_SIZE);
	uint8_t *bufp = oldbufp;

	/* setup ELF header */
	elf = (struct elfhdr *) bufp;
	bufp += sizeof(struct elfhdr);
	offset += sizeof(struct elfhdr);
	memcpy(elf->e_ident, ELFMAG, SELFMAG);
	elf->e_ident[EI_CLASS]	= ELFCLASS32;
	elf->e_ident[EI_DATA]	= ELFDATA2LSB;
	elf->e_ident[EI_VERSION]= EV_CURRENT;
	elf->e_ident[EI_OSABI] = ELFOSABI_NONE;
	memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
	elf->e_type	= ET_CORE;
	elf->e_machine	= EM_ARM;
	elf->e_version	= EV_CURRENT;
	elf->e_entry	= 0;
	elf->e_phoff	= sizeof(struct elfhdr);
	elf->e_shoff	= 0;
	elf->e_flags	= ELF_CORE_EFLAGS;
	elf->e_ehsize	= sizeof(struct elfhdr);
	elf->e_phentsize= sizeof(struct elf_phdr);
	elf->e_phnum	= 2;
	elf->e_shentsize= 0;
	elf->e_shnum	= 0;
	elf->e_shstrndx	= 0;

	nhdr = (struct elf_phdr *) bufp;
	bufp += sizeof(struct elf_phdr);
	offset += sizeof(struct elf_phdr);
	memset(nhdr, 0, sizeof(struct elf_phdr));
	nhdr->p_type = PT_NOTE;

	phdr = (struct elf_phdr *) bufp;
	bufp += sizeof(struct elf_phdr);
	offset += sizeof(struct elf_phdr);

        uint32_t low_memory_size = kparams->high_memory - kparams->page_offset;
        if (low_memory_size > kmem_size) {
            low_memory_size = kmem_size;
        }
	phdr->p_type	= PT_LOAD;
	phdr->p_flags	= PF_R|PF_W|PF_X;
	phdr->p_offset	= KDUMP_CORE_SIZE;
	phdr->p_vaddr	= (size_t) kparams->page_offset;
	phdr->p_paddr	= kmem_address;
	phdr->p_filesz	= kmem_size;
	phdr->p_memsz	= low_memory_size;
	phdr->p_align	= KDUMP_CORE_SIZE;

	nhdr->p_offset = offset;

	struct elf_prpsinfo prpsinfo;	/* NT_PRPSINFO */
	struct memelfnote notes;
	/* set up the process info */
	notes.name = CORE_STR;
	notes.type = NT_PRPSINFO;
	notes.datasz = sizeof(struct elf_prpsinfo);
	notes.data = &prpsinfo;

	memset(&prpsinfo, 0, sizeof(struct elf_prpsinfo));
	prpsinfo.pr_state = 0;
	prpsinfo.pr_sname = 'R';
	prpsinfo.pr_zomb = 0;
	prpsinfo.pr_gid = prpsinfo.pr_uid = mrdump_cb->crash_record.fault_cpu + 1;
	strlcpy(prpsinfo.pr_fname, "vmlinux", sizeof(prpsinfo.pr_fname));
	strlcpy(prpsinfo.pr_psargs, "vmlinux", ELF_PRARGSZ);

	nhdr->p_filesz += notesize(&notes);
	bufp = storenote(&notes, bufp);

	bufp = kdump_core_write_machdesc(mrdump_cb, nhdr, bufp);

        /* Store pre-cpu backtrace */
        bufp = kdump_core_write_cpu_note(mrdump_cb, mrdump_cb->crash_record.fault_cpu, nhdr, bufp);
	for (unsigned int cpu = 0; cpu < kparams->nr_cpus; cpu++) {
            if (cpu != mrdump_cb->crash_record.fault_cpu) {
                bufp = kdump_core_write_cpu_note(mrdump_cb, cpu, nhdr, bufp);
            }
        }
	voprintf_debug("%s cpu %d header size %d\n", __FUNCTION__, kparams->nr_cpus, bufp - oldbufp);
    
	return oldbufp;
}