diff -rup makedumpfile.old/Makefile makedumpfile/Makefile
--- makedumpfile.old/Makefile	2006-09-04 18:42:29.000000000 +0900
+++ makedumpfile/Makefile	2006-09-05 21:30:44.000000000 +0900
@@ -77,4 +77,4 @@ readdwarfinfo: $(SRC_DEBUG) $(OBJ_DEBUG)
 	$(CC) $(CFLAGS_DEBUG) $(OBJ_DEBUG) -lelf -o $@
 
 install:
-	cp ./makedumpfile /usr/sbin
+	cp ./makedumpfile /bin
diff -rup makedumpfile.old/makedumpfile.c makedumpfile/makedumpfile.c
--- makedumpfile.old/makedumpfile.c	2006-09-04 18:42:29.000000000 +0900
+++ makedumpfile/makedumpfile.c	2006-09-05 21:30:44.000000000 +0900
@@ -234,22 +234,101 @@ readmem(struct DumpInfo *info, unsigned 
 	return size;
 }
 
+int
+get_kernel_version(char *release)
+{
+	if (!strncmp(release, "2.6.15", strlen("2.6.15"))) {
+		return VERSION_2_6_15;
+	} else if (!strncmp(release, "2.6.16", strlen("2.6.16"))) {
+		return VERSION_2_6_16;
+	} else if (!strncmp(release, "2.6.17", strlen("2.6.17"))) {
+		return VERSION_2_6_17;
+	} else if (!strncmp(release, "2.6.18", strlen("2.6.18"))) {
+		return VERSION_2_6_18;
+	} else {
+		ERRMSG("Can't get kernel version from system_utsname.\n");
+		return FALSE;
+	}
+}
+
+int
+is_page_size(unsigned long page_size)
+{
+	unsigned long bitbuf = page_size;
+	unsigned int i, sum = 0;
+
+	/* Only 1 bit is set because of page size. */
+	for (i = 0; i < sizeof(bitbuf) * 8; i++) {
+		sum += bitbuf & 1;
+		bitbuf = bitbuf >> 1;
+	}
+	if (sum != 1) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+int
+check_release(struct DumpInfo *info)
+{
+	unsigned long sym_system_utsname;
+	struct utsname system_utsname;
+
+	sym_system_utsname = info->sym_system_utsname;
+	/*
+	 * Get the kernel version from the symbol "system_utsname".
+	 */
+	if (!sym_system_utsname) {
+		ERRMSG("Can't get the symbol of system_utsname.\n");
+		return FALSE;
+	}
+	if (!readmem(info, sym_system_utsname, &system_utsname, sizeof(struct utsname))) {
+		ERRMSG("Can't get the address of system_utsname.\n");
+		return FALSE;
+	}
+
+	if (info->flag_read_config) {
+		if (strcmp(system_utsname.release, info->release)) {
+			ERRMSG("%s doesn't suit the dump_mem.\n", info->name_configfile);
+			info->retcd = WRONG_RELEASE;
+			return FALSE;
+		}
+	}
+
+	info->kernel_version = get_kernel_version(system_utsname.release);
+	if (info->kernel_version == FALSE)
+		return FALSE;
+
+	return TRUE;
+}
+
 void
 print_usage()
 {
 	MSG("\n");
 	MSG("Usage:\n");
-	MSG("  makedumpfile [-c|-E] [-d dump_level] [-x vmlinux] [map_file] dump_mem dump_file\n");
+	MSG("  makedumpfile [-c|-E] [-d dump_level] [-g config_file]|[-i config_file]\n");
+	MSG("  [-x vmlinux] [map_file] dump_mem dump_file\n");
+	MSG("\n");
+	MSG("  Making dump_file with vmlinux and map_file:\n");
+	MSG("    makedumpfile [-c|-E] [-d dump_level] -x vmlinux map_file dump_mem dump_file\n");
+	MSG("\n");
+	MSG("  Making dump_file with config_file:\n");
+	MSG("    makedumpfile [-c|-E] [-d dump_level] -i config_file dump_mem dump_file\n");
+	MSG("\n");
+	MSG("  Generating config_file:\n");
+	MSG("    makedumpfile -g config_file -x vmlinux map_file\n");
 	MSG("\n");
 	MSG("Available options:\n");
 	MSG("  [-c]:\n");
 	MSG("      This option enables the compression function of each page.\n");
-	MSG("      This is only for crash.\n");
+	MSG("      You can not specify this opiton with [-E].\n");
+	MSG("      This is only for crash. [dump_mem] and [dump_file] must be specified.\n");
 	MSG("\n");
 	MSG("  [-E]:\n");
 	MSG("      Create the ELF dump file.\n");
 	MSG("      You can not specify this opiton with [-c].\n");
-	MSG("      This is only for gdb.\n");
+	MSG("      This is only for gdb. [dump_mem] and [dump_file] must be specified.\n");
 	MSG("\n");
 	MSG("  [-d dump_level]:\n");
 	MSG("      This is specification of the skipped pages. \n");
@@ -275,14 +354,40 @@ print_usage()
 //	MSG("        14  |         X       X        X\n");
 	MSG("        15  |  X      X       X        X\n");
 	MSG("\n");
+	MSG("      [-i config_file] or ([-x vmlinux] and [map_file]) must be specified,\n");
+	MSG("      when dump_level is two or more.\n");
+	MSG("      [dump_mem] and [dump_file] must be specified.\n");
+	MSG("\n");
+	MSG("  [-g config_file]:\n");
+	MSG("      Generate the configuration file. Debugging information\n");
+	MSG("      necessary for executing a partial dump is output to this file. A partial\n");
+	MSG("      dump can be executed even if the output this file is read by -i option,\n");
+	MSG("      and there is no kernel file with debugging information. When this option\n");
+	MSG("      is specified, the dump is not output. [-x vmlinux] and [map_file] must\n");
+	MSG("      be specified.\n");
+	MSG("\n");
+	MSG("  [-i config_file]:\n");
+	MSG("      Read the configuration file. This file is the one\n");
+	MSG("      output beforehand by specifying -g option, and debugging information\n");
+	MSG("      necessary for executing a partial dump is contained. A partial dump can\n");
+	MSG("      be executed even if this file is read, and there is no kernel file with\n");
+	MSG("      debugging information. When this option is specified, -g option,\n");
+	MSG("      [-x vmlinux], and [map_file] cannot be specified.\n");
+	MSG("      Note:\n");
+	MSG("      When this file is not specified, this command uses the page size of\n");
+	MSG("      the system under operation(Capture kernel) as the one of dump_mem\n");
+	MSG("      (First-kernel).\n");
+	MSG("\n");
 	MSG("  [-x vmlinux]:\n");
-	MSG("      This is a pathname to a vmlinux file compiled with -g option\n");
-	MSG("      for first-kernel.\n");
-	MSG("      This is necessary when dump_level is 2 or more.\n");
+	MSG("      This is a pathname to the first-kernel's vmlinux file compiled with\n");
+	MSG("      -g option.\n");
+	MSG("      This is necessary when dump_level is 2 or more and [-i config_file] is\n");
+	MSG("      not specified.\n");
 	MSG("\n");
 	MSG("  [map_file]:\n");
-	MSG("      This is a pathname to a system.map file of first-kernel.\n");
-	MSG("      This is necessary when dump_level is 2 or more.\n");
+	MSG("      This is a pathname to a System.map file of first-kernel.\n");
+	MSG("      This is necessary when dump_level is 2 or more and [-i config_file]\n");
+	MSG("      is not specified. [-x vmlinux] must be specified.\n");
 	MSG("\n");
 	MSG("  dump_mem:\n");
 	MSG("      This is a pathname to a first-kernel memory core image.\n");
@@ -312,6 +417,20 @@ open_system_map(struct DumpInfo *info)
 }
 
 int
+open_config_file(struct DumpInfo *info, char *mode)
+{
+	FILE *file_configfile;
+
+	if ((file_configfile = fopen(info->name_configfile, mode)) == NULL) {
+		ERRMSG("Can't open the config file(%s). %s\n",
+		info->name_configfile, strerror(errno));
+		return FALSE;
+	}
+	info->file_configfile = file_configfile;
+	return TRUE;
+}
+
+int
 open_dump_memory(struct DumpInfo *info)
 {
 	int fd;
@@ -322,7 +441,6 @@ open_dump_memory(struct DumpInfo *info)
 		return FALSE;
 	}
 	info->fd_memory = fd;
-
 	return TRUE;
 }
 
@@ -364,6 +482,65 @@ open_dump_bitmap(struct DumpInfo *info)
 	return TRUE;
 }
 
+/*
+ * Open the following files when it generates the configuration file.
+ * - vmlinux
+ * - system.map
+ * - configuration file
+ */
+int
+open_files_for_generating_configfile(struct DumpInfo *info)
+{
+	if ((dwarf_info.vmlinux_fd
+	    = open_kernel_file(dwarf_info.vmlinux_name)) == -1)
+		return FALSE;
+
+	if (!open_system_map(info))
+		return FALSE;
+
+	if (!open_config_file(info, "w"))
+		return FALSE;
+
+	return TRUE;
+}
+
+/*
+ * Open the following files when it creates the dump file.
+ * - dump mem
+ * - dump file
+ * - bit map
+ * if it reads the configuration file
+ *   - configuration file
+ * else
+ *   - vmlinux
+ *   - system.map
+ */
+int
+open_files_for_creating_dumpfile(struct DumpInfo *info)
+{
+	if (info->flag_read_config) {
+		if (!open_config_file(info, "r"))
+			return FALSE;
+	} else if (info->dump_level >= 2) {
+		if ((dwarf_info.vmlinux_fd
+		    = open_kernel_file(dwarf_info.vmlinux_name)) == -1)
+			return FALSE;
+
+		if (!open_system_map(info))
+			return FALSE;
+	}
+	if (!open_dump_memory(info))
+		return FALSE;
+
+	if (!open_dump_file(info))
+		return FALSE;
+
+	if (!open_dump_bitmap(info))
+		return FALSE;
+
+	return TRUE;
+}
+
 int
 dump_Elf32_pt_load(struct DumpInfo *info, Elf32_Phdr *prog, int num_load)
 {
@@ -380,7 +557,6 @@ dump_Elf32_pt_load(struct DumpInfo *info
 	pls->virt_start  = prog->p_vaddr;
 	pls->virt_end    = pls->virt_start + prog->p_filesz;
 	pls->file_offset = prog->p_offset;
-
 	return TRUE;
 }
 
@@ -437,7 +613,6 @@ get_elf_info(struct DumpInfo *info)
 		       &header[sizeof(Elf32_Ehdr)+sizeof(Elf32_Phdr)];
 		info->num_load_memory    = elf32->e_phnum - 1;
 		info->offset_load_memory = (Elf32_Off)load32->p_offset;
-		info->page_size = (uint32_t)load32->p_align;
 	} else if (STRNEQ(elf64->e_ident, ELFMAG)
 	    && (elf64->e_ident[EI_CLASS] == ELFCLASS64)) {
 		info->flag_elf = ELF64;
@@ -445,7 +620,6 @@ get_elf_info(struct DumpInfo *info)
 		       &header[sizeof(Elf64_Ehdr)+sizeof(Elf64_Phdr)];
 		info->num_load_memory    = elf64->e_phnum - 1;
 		info->offset_load_memory = (Elf64_Off)load64->p_offset;
-		info->page_size = (uint64_t)load64->p_align;
 	} else {
 		ERRMSG("%s isn't the dump memory.\n", info->name_memory);
 		goto out;
@@ -456,11 +630,8 @@ get_elf_info(struct DumpInfo *info)
 	 *   If the page_size of 1st-kernel is different from the one of
 	 *   capture(2nd)-kernel, the problem will happen.
 	 */
-	if (!info->page_size)
-		info->page_size = (size_t)sysconf(_SC_PAGE_SIZE);
 	if (!info->page_size) {
-		ERRMSG("Can't get the size of page.\n");
-		goto out;
+		info->page_size = sysconf(_SC_PAGE_SIZE);
 	}
 	if (!info->num_load_memory) {
 		ERRMSG("Can't get the number of PT_LOAD.\n");
@@ -536,15 +707,14 @@ get_symbol_info(struct DumpInfo *info)
 {
 	unsigned long sym_mem_map = 0;
 	unsigned long sym_system_utsname = 0;
-	unsigned long addr_mem_map;
-	struct new_utsname system_utsname;
 	char buf[BUFSIZE_FGETS], *mapitems[MAXARGS], *endp;
 
-	if (info->name_sysmap == NULL)
+	if (info->name_sysmap == NULL) {
 		return TRUE;
+	}
 
 	/*
-	 * Get a symbol info from the System.map.
+	 * Get symbol info from the System.map.
 	 */
 	while (fgets(buf, BUFSIZE_FGETS, info->map)) {
 		if (parse_line(buf, mapitems) != 3)
@@ -569,56 +739,11 @@ get_symbol_info(struct DumpInfo *info)
 				return FALSE;
 			}
 		}
-		if ((sym_mem_map != 0)
-		    && (sym_system_utsname != 0))
+		if (sym_mem_map != 0 && sym_system_utsname != 0)
 			break;
 	}
-
-	/*
-	 * Get the address of the symbol "mem_map".
-	 * FIXME
-	 *   If this command get the feature of analysing a struct,
-	 *   the info of the memory management will be gotten from "pgdat_list".
-	 */
-	if (!sym_mem_map) {
-		ERRMSG("Can't get the symbol of mem_map.\n");
-		return FALSE;
-	}
-	if (!readmem(info, sym_mem_map, &addr_mem_map, sizeof addr_mem_map)) {
-		ERRMSG("Can't get the address of mem_map.\n");
-		return FALSE;
-	}
-
-	if (!addr_mem_map) {
-		ERRMSG("Can't get the address of mem_map.\n");
-		return FALSE;
-	}
-	info->addr_mem_map = addr_mem_map;
-
-	/*
-	 * Get the kernel version from the symbol "system_utsname".
-	 */
-	if (!sym_system_utsname) {
-		ERRMSG("Can't get the symbol of system_utsname.\n");
-		return FALSE;
-	}
-	if (!readmem(info, sym_system_utsname, &system_utsname, sizeof(struct new_utsname))) {
-		ERRMSG("Can't get the address of system_utsname.\n");
-		return FALSE;
-	}
-
-	if (!strncmp(system_utsname.release, "2.6.15", strlen("2.6.15"))) {
-		info->kernel_version = VERSION_2_6_15;
-	} else if (!strncmp(system_utsname.release, "2.6.16", strlen("2.6.16"))) {
-		info->kernel_version = VERSION_2_6_16;
-	} else if (!strncmp(system_utsname.release, "2.6.17", strlen("2.6.17"))) {
-		info->kernel_version = VERSION_2_6_17;
-	} else if (!strncmp(system_utsname.release, "2.6.18", strlen("2.6.18"))) {
-		info->kernel_version = VERSION_2_6_18;
-	} else {
-		ERRMSG("Can't get kernel version from system_utsname.\n");
-		return FALSE;
-	}
+	info->sym_mem_map = sym_mem_map;
+	info->sym_system_utsname = sym_system_utsname;
 
 	return TRUE;
 }
@@ -673,16 +798,248 @@ get_pagedesc_offset(struct DumpInfo *inf
 }
 
 int
-initial(struct DumpInfo *info)
+generate_config(struct DumpInfo *info)
 {
-	if (!get_elf_info(info))
+	struct utsname utsname_buf;
+	long tmp_long;
+
+	/*
+	 * write 1st kernel's OSRELEASE
+	 */
+	if (uname(&utsname_buf)) {
+		ERRMSG("Can't get uname. %s\n", strerror(errno));
 		return FALSE;
+	}
+	fprintf(info->file_configfile, "%s%s\n", STR_OSRELEASE,
+	    utsname_buf.release);
 
+	/*
+	 * write 1st kernel's PAGESIZE
+	 */
+	if (!info->page_size) {
+		tmp_long = sysconf(_SC_PAGE_SIZE);
+		if (tmp_long == -1) {
+			ERRMSG("Can't get the size of page.\n");
+			return FALSE;
+		}
+		info->page_size = (size_t)tmp_long;
+	}
+	fprintf(info->file_configfile, "%s%d\n", STR_PAGESIZE,
+	    (int)info->page_size);
+
+	/*
+	 * write 1st kernel's address of SYMBOL(mem_map)
+	 */
 	if (!get_symbol_info(info))
 		return FALSE;
+	if (!info->sym_mem_map || !info->sym_system_utsname) {
+		ERRMSG("Can't get the symbol of mem_map.\n");
+		return FALSE;
+	}
+	fprintf(info->file_configfile, "%s%lx\n", STR_SYMBOL("mem_map"),
+	    info->sym_mem_map);
+
+	/*
+	 * write 1st kernel's address of SYMBOL(system_utsname)
+	 */
+	fprintf(info->file_configfile, "%s%lx\n", STR_SYMBOL("system_utsname"),
+	    info->sym_system_utsname);
 
+	/*
+	 * get 1st kernel's version
+	 */
+	info->kernel_version = get_kernel_version(utsname_buf.release);
+	if (info->kernel_version == FALSE)
+		return FALSE;
+
+	/*
+	 * write 1st kernel's size of struct page
+	 */
 	if (!get_pagedesc_offset(info))
 		return FALSE;
+	fprintf(info->file_configfile, "%s%d\n", STR_SIZE("page"),
+	    info->size_pagedesc);
+
+	/*
+	 * write 1st kernel's offset of page.flags
+	 */
+	fprintf(info->file_configfile, "%s%d\n", STR_OFFSET("page.flags"),
+	    info->offset_page_flags);
+
+	/*
+	 * write 1st kernel's offset of page._count
+	 */
+	fprintf(info->file_configfile, "%s%d\n", STR_OFFSET("page._count"),
+	    info->offset_page__count);
+
+	/*
+	 * write 1st kernel's offset of page.mapping
+	 */
+	fprintf(info->file_configfile, "%s%d\n", STR_OFFSET("page.mapping"),
+	    info->offset_page_mapping);
+
+	return TRUE;
+}
+
+int
+read_config(struct DumpInfo *info)
+{
+	unsigned long tmp_ulong;
+	char buf[BUFSIZE_FGETS], *endp;
+	unsigned int ok_flag = 0, i;
+
+	while (fgets(buf, BUFSIZE_FGETS, info->file_configfile)) {
+		i = strlen(buf);
+		if (buf[i - 1] == '\n')
+			buf[i - 1] = '\0';
+		if (strncmp(buf, STR_OSRELEASE, strlen(STR_OSRELEASE)) == 0) {
+			strcpy(info->release, buf + strlen(STR_OSRELEASE));
+			ok_flag = 1;
+		}
+		if (strncmp(buf, STR_PAGESIZE, strlen(STR_PAGESIZE)) == 0) {
+			tmp_ulong = strtoul(buf + strlen(STR_PAGESIZE), &endp, 10);
+	       		if ((!tmp_ulong || tmp_ulong == ULONG_MAX)
+			    || strlen(endp) != 0) {
+				ERRMSG("Invalid data in %s: %s",
+					info->name_configfile, buf);
+				return FALSE;
+			}
+			if (!is_page_size(tmp_ulong)) {
+				ERRMSG("Invalid data in %s: %s",
+				info->name_configfile, buf);
+				return FALSE;
+			}
+			info->page_size = tmp_ulong;
+		}
+		if (strncmp(buf, STR_SYMBOL("mem_map"), strlen(STR_SYMBOL("mem_map"))) == 0) {
+			tmp_ulong = strtoul(buf + strlen(STR_SYMBOL("mem_map")),
+				&endp, 16);
+	       		if ((!tmp_ulong || tmp_ulong == ULONG_MAX)
+			    || strlen(endp) != 0) {
+				ERRMSG("Invalid data in %s: %s",
+					info->name_configfile, buf);
+				return FALSE;
+			}
+			info->sym_mem_map = tmp_ulong;
+		}
+		if (strncmp(buf, STR_SYMBOL("system_utsname"), strlen(STR_SYMBOL("system_utsname"))) == 0) {
+			tmp_ulong = strtoul(buf
+				+ strlen(STR_SYMBOL("system_utsname")), &endp, 16);
+        		if ((!tmp_ulong || tmp_ulong == ULONG_MAX)
+			    || strlen(endp) != 0) {
+				ERRMSG("Invalid data in %s: %s",
+					info->name_configfile, buf);
+				return FALSE;
+			}
+			info->sym_system_utsname = tmp_ulong;
+		}
+		if (strncmp(buf, STR_SIZE("page"), strlen(STR_SIZE("page"))) == 0) {
+			tmp_ulong = strtoul(buf + strlen(STR_SIZE("page")), &endp, 10);
+	       		if ((!tmp_ulong || tmp_ulong == ULONG_MAX)
+			    || strlen(endp) != 0) {
+				ERRMSG("Invalid data in %s: %s",
+					info->name_configfile, buf);
+				return FALSE;
+			}
+			info->size_pagedesc = tmp_ulong;
+		}
+		if (strncmp(buf, STR_OFFSET("page.flags"), strlen(STR_OFFSET("page.flags"))) == 0) {
+			tmp_ulong = strtoul(buf + strlen(STR_OFFSET("page.flags")),
+				&endp, 10);
+	       		if (tmp_ulong == ULONG_MAX
+			    || strlen(endp) != 0) {
+				ERRMSG("Invalid data in %s: %s",
+					info->name_configfile, buf);
+				return FALSE;
+			}
+			info->offset_page_flags = tmp_ulong;
+		}
+		if (strncmp(buf, STR_OFFSET("page._count"), strlen(STR_OFFSET("page._count"))) == 0) {
+			tmp_ulong = strtoul(buf + strlen(STR_OFFSET("page._count")),
+				&endp, 10);
+	       		if (tmp_ulong == ULONG_MAX
+			    || strlen(endp) != 0) {
+				ERRMSG("Invalid data in %s: %s",
+					info->name_configfile, buf);
+				return FALSE;
+			}
+			info->offset_page__count = tmp_ulong;
+		}
+		if (strncmp(buf, STR_OFFSET("page.mapping"), strlen(STR_OFFSET("page.mapping"))) == 0) {
+			tmp_ulong = strtoul(buf + strlen(STR_OFFSET("page.mapping")),
+				&endp, 10);
+	       		if (tmp_ulong == ULONG_MAX
+			    || strlen(endp) != 0) {
+				ERRMSG("Invalid data in %s: %s",
+					info->name_configfile, buf);
+				return FALSE;
+			}
+			info->offset_page_mapping = tmp_ulong;
+		}
+	}
+	if (!ok_flag || !info->page_size) {
+		ERRMSG("Invalid format in %s", info->name_configfile);
+		return FALSE;
+	}
+	return TRUE;
+}
+
+int
+get_mem_map(struct DumpInfo *info)
+{
+	unsigned long sym_mem_map = info->sym_mem_map;
+	unsigned long addr_mem_map;
+
+	/*
+	 * Get the address of the symbol "mem_map".
+	 * FIXME
+	 *   If this command get the feature of analysing a struct,
+	 *   the info of the memory management will be gotten from "pgdat_list".
+	 */
+	if (!sym_mem_map) {
+		ERRMSG("Can't get the symbol of mem_map.\n");
+		return FALSE;
+	}
+	if (!readmem(info, sym_mem_map, &addr_mem_map, sizeof addr_mem_map)) {
+		ERRMSG("Can't get the address of mem_map.\n");
+		return FALSE;
+	}
+	if (!addr_mem_map) {
+		ERRMSG("Can't get the address of mem_map.\n");
+		return FALSE;
+	}
+	info->addr_mem_map = addr_mem_map;
+
+	return TRUE;
+}
+
+int
+initial(struct DumpInfo *info)
+{
+	if (!get_elf_info(info))
+		return FALSE;
+
+	if (!info->flag_read_config) {
+		if (info->dump_level <= 1)
+			return TRUE;
+		if (!get_symbol_info(info))
+			return FALSE;
+		if (!check_release(info))
+			return FALSE;
+		if (!get_pagedesc_offset(info))
+			return FALSE;
+	} else {
+		if (!read_config(info))
+			return FALSE;
+		if (!info->sym_mem_map || !info->sym_system_utsname) {
+			ERRMSG("Invalid format in %s", info->name_configfile);
+			return FALSE;
+		}
+		if (!check_release(info))
+			return FALSE;
+	}
+	if (!get_mem_map(info))
+		return FALSE;
 
 	return TRUE;
 }
@@ -980,7 +1337,8 @@ create_dump_bitmap(struct DumpInfo *info
 		    strerror(errno));
 		goto out;
 	}
-	if ((page_cache = g_malloc(info->size_pagedesc*PGMM_CACHED)) == NULL) {
+	if (info->dump_level > DL_EXCLUDE_ZERO &&
+	    (page_cache = g_malloc(info->size_pagedesc*PGMM_CACHED)) == NULL) {
 		ERRMSG("Can't allocate memory for the pagedesc cache. %s\n",
 		    strerror(errno));
 		goto out;
@@ -1118,7 +1476,8 @@ create_dump_bitmap(struct DumpInfo *info
 	if (info->flag_elf_dumpfile && !create_contig_bitmap(info))
 		goto out;
 
-	g_free(page_cache);
+	if (page_cache != NULL)
+		g_free(page_cache);
 	g_free(buf);
 	g_free(bm1.buf);
 	g_free(bm2.buf);
@@ -1797,6 +2156,14 @@ close_system_map(struct DumpInfo *info)
 }
 
 void
+close_config_file(struct DumpInfo *info)
+{
+	if(fclose(info->file_configfile) < 0)
+		ERRMSG("Can't close the config file(%s). %s\n",
+		info->name_configfile, strerror(errno));
+}
+
+void
 close_dump_memory(struct DumpInfo *info)
 {
 	if (close(info->fd_memory) < 0)
@@ -1829,6 +2196,54 @@ close_kernel_file(int fd)
 			dwarf_info.vmlinux_name, strerror(errno));
 }
 
+/*
+ * Close the following files when it generates the configuration file.
+ * - vmlinux
+ * - system.map
+ * - configuration file
+ */
+int
+close_files_for_generating_configfile(struct DumpInfo *info)
+{
+	close_kernel_file(dwarf_info.vmlinux_fd);
+
+	close_system_map(info);
+
+	close_config_file(info);
+
+	return TRUE;
+}
+
+/*
+ * Close the following files when it creates the dump file.
+ * - dump mem
+ * - dump file
+ * - bit map
+ * if it reads the configuration file
+ *   - configuration file
+ * else
+ *   - vmlinux
+ *   - system.map
+ */
+int
+close_files_for_creating_dumpfile(struct DumpInfo *info)
+{
+	if (info->flag_read_config) {
+		close_config_file(info);
+	} else if (info->dump_level >= 2) {
+		close_kernel_file(dwarf_info.vmlinux_fd);
+
+		close_system_map(info);
+	}
+	close_dump_memory(info);
+
+	close_dump_file(info);
+
+	close_dump_bitmap(info);
+
+	return TRUE;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -1847,7 +2262,7 @@ main(int argc, char *argv[])
 		goto out;
 	}
 
-	while ((opt = getopt(argc, argv, "b:cd:Ex:")) != -1) {
+	while ((opt = getopt(argc, argv, "b:cd:Eg:i:x:")) != -1) {
 		switch (opt) {
 		case 'b':
 			info->block_order = atoi(optarg);
@@ -1861,7 +2276,16 @@ main(int argc, char *argv[])
 		case 'E':
 			info->flag_elf_dumpfile = 1;
 			break;
+		case 'g':
+			info->flag_generate_config = 1;
+			info->name_configfile = optarg;
+			break;
+		case 'i':
+			info->flag_read_config = 1;
+			info->name_configfile = optarg;
+			break;
 		case 'x':
+			info->flag_vmlinux = 1;
 			dwarf_info.vmlinux_name = optarg;
 			break;
 		case '?':
@@ -1870,75 +2294,114 @@ main(int argc, char *argv[])
 			goto out;
 		}
 	}
-	if ((info->dump_level < MIN_DUMP_LEVEL)
-	    || (MAX_DUMP_LEVEL < info->dump_level)) {
-		ERRMSG("Dump_level is invalid.\n");
-		print_usage();
-		goto out;
-	}
-	if ((optind + 3 < argc) 
-	    || ((info->dump_level <= 1) && (argc  < optind + 2))
-	    || ((info->dump_level >= 2) && (argc != optind + 3))
-	    || ((info->flag_compress == 1) && (info->flag_elf_dumpfile == 1))) {
-		ERRMSG("Commandline parameter is invalid.\n");
-		print_usage();
-		goto out;
-	}
-	if ((info->dump_level <= 1) && (argc == optind + 2)) {
+
+	if (info->flag_generate_config) {
+		/*
+		 * generate the configuration file
+		 */
+		if (argc != optind + 1) {
+			ERRMSG("Commandline parameter is invalid.\n");
+			print_usage();
+			goto out;
+		}
+		if (info->flag_compress || info->dump_level ||
+			info->flag_elf_dumpfile || info->flag_read_config ||
+			!info->flag_vmlinux) {
+			ERRMSG("Commandline parameter is invalid.\n");
+			print_usage();
+			goto out;
+		}
+		info->name_sysmap   = argv[optind];
+	} else if (info->flag_read_config) {
+		/*
+		 * check parameters to read the configuration file
+		 */
+		if ((info->dump_level < MIN_DUMP_LEVEL)
+		    || (MAX_DUMP_LEVEL < info->dump_level)) {
+			ERRMSG("Dump_level is invalid.\n");
+			print_usage();
+			goto out;
+		}
+		if ((argc != optind + 2)
+		    || ((info->flag_compress == 1)
+			&& (info->flag_elf_dumpfile == 1))
+			/* || info->flag_generate_config */
+			|| info->flag_vmlinux) {
+			ERRMSG("Commandline parameter is invalid.\n");
+			print_usage();
+			goto out;
+		}
 		info->name_sysmap   = NULL;
 		info->name_memory   = argv[optind];
 		info->name_dumpfile = argv[optind+1];
 	} else {
-		info->name_sysmap   = argv[optind];
-		info->name_memory   = argv[optind+1];
-		info->name_dumpfile = argv[optind+2];
+		if ((info->dump_level < MIN_DUMP_LEVEL)
+		    || (MAX_DUMP_LEVEL < info->dump_level)) {
+			ERRMSG("Dump_level is invalid.\n");
+			print_usage();
+			goto out;
+		}
+		if ((optind + 3 < argc)
+		    || ((info->dump_level <= 1) && (argc  < optind + 2))
+		    || ((info->dump_level >= 2) && (argc != optind + 3))
+		    || ((info->dump_level >= 2) && (!info->flag_vmlinux))
+		    || ((info->flag_compress == 1)
+			&& (info->flag_elf_dumpfile == 1))) {
+			ERRMSG("Commandline parameter is invalid.\n");
+			print_usage();
+			goto out;
+		}
+		if ((info->dump_level <= 1) && (argc == optind + 2)) {
+			info->name_sysmap   = NULL;
+			info->name_memory   = argv[optind];
+			info->name_dumpfile = argv[optind+1];
+		} else {
+			info->name_sysmap   = argv[optind];
+			info->name_memory   = argv[optind+1];
+			info->name_dumpfile = argv[optind+2];
+		}
 	}
 
-	if (!open_system_map(info))
-		goto out;
-
-	if (!open_dump_memory(info))
-		goto out;
-
-	if (!open_dump_file(info))
-		goto out;
-
-	if (!open_dump_bitmap(info))
-		goto out;
 
-	dwarf_info.vmlinux_fd = open_kernel_file(dwarf_info.vmlinux_name);
-	if (dwarf_info.vmlinux_fd == -1)
-		goto out;
-
-	if (!initial(info))
-		goto out;
+	if (info->flag_generate_config) {
+		if (!open_files_for_generating_configfile(info))
+			goto out;
 
-	if (!create_dump_bitmap(info))
-		goto out;
+		if (!generate_config(info))
+			goto out;
 
-	if (!write_dump_header(info))
-		goto out;
+		if (!close_files_for_generating_configfile(info))
+			goto out;
 
-	if (!write_pages(info))
-		goto out;
+		MSG("\n");
+	} else {
+		if (!open_files_for_creating_dumpfile(info))
+			goto out;
 
-	if (!write_dump_bitmap(info))
-		goto out;
+		if (!initial(info))
+			goto out;
 
-	close_system_map(info);
+		if (!create_dump_bitmap(info))
+			goto out;
 
-	close_dump_memory(info);
+		if (!write_dump_header(info))
+			goto out;
 
-	close_dump_file(info);
+		if (!write_pages(info))
+			goto out;
 
-	close_dump_bitmap(info);
+		if (!write_dump_bitmap(info))
+			goto out;
 
-	close_kernel_file(dwarf_info.vmlinux_fd);
+		if (!close_files_for_creating_dumpfile(info))
+			goto out;
 
-	MSG("\n");
-	MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
+		MSG("\n");
+		MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
+	}
 	MSG("makedumpfile Completed.\n");
-	g_free(info->pt_load_segments);
+	if (!info->flag_generate_config)
+		g_free(info->pt_load_segments);
 	g_free(info->dump_header);
 	g_free(info);
 	return COMPLETED;
@@ -1960,5 +2423,8 @@ out:
 		g_free(info->dump_header);
 	if (info != NULL)
 		g_free(info);
-	return FAILED;
+	if (info->retcd)
+		return info->retcd;
+	else
+		return FAILED;
 }
diff -rup makedumpfile.old/makedumpfile.h makedumpfile/makedumpfile.h
--- makedumpfile.old/makedumpfile.h	2006-09-04 18:42:29.000000000 +0900
+++ makedumpfile/makedumpfile.h	2006-09-05 21:30:44.000000000 +0900
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <errno.h>
 #include <time.h>
+#include <sys/utsname.h>
 #include <glib.h>
 #include <zlib.h>
 #include "diskdump_mod.h"
@@ -34,6 +35,9 @@
  */
 #define COMPLETED	(0)
 #define FAILED		(1)
+#define WRONG_RELEASE	(2)	/* utsname.release does not match. */
+#define ANALYSIS_FAILED	(3)	/* detected illegal page descriptor. */
+#define OUTPUT_FAILED	(4)	/* detected an output error. */
 
 /*
  * Page flags
@@ -140,6 +144,15 @@ isAnon(unsigned long mapping)
 #define VERSION_2_6_18		(18)
 
 /*
+ * field name of config file
+ */
+#define STR_OSRELEASE	"OSRELEASE="
+#define STR_PAGESIZE	"PAGESIZE="
+#define STR_SYMBOL(X)	"SYMBOL("X")="
+#define STR_SIZE(X)	"SIZE("X")="
+#define STR_OFFSET(X)	"OFFSET("X")="
+
+/*
  * The values of linux 2.6.15.1
  */
 #ifdef __i386__
@@ -183,6 +196,7 @@ struct cache_data {
 };
 
 struct DumpInfo {
+	int		retcd;		     /* return code */
 	int		size_pagedesc;       /* size of page descriptor */
 	int		offset_page_flags;   /* offset of page.flags */
 	int		offset_page__count;  /* offset of page._count */
@@ -197,6 +211,9 @@ struct DumpInfo {
 	int		flag_compress;       /* flag of compression */
 	int		flag_elf;
 	int		flag_elf_dumpfile;   /* flag of elf dump file */
+	int		flag_vmlinux;	     /* flag of vmlinux */
+	int		flag_generate_config;/* flag of generating config file */
+	int		flag_read_config;    /* flag of reading config file */
 	size_t		page_size;           /* size of page */
 	unsigned int	max_mapnr;           /* number of page descriptor */
 
@@ -241,4 +258,13 @@ struct DumpInfo {
 	 */
 	int			fd_bitmap;
 	char			*name_bitmap;
+
+	/*
+	 * config file info:
+	 */
+	FILE			*file_configfile;
+	char			*name_configfile;	     /* config file */
+	char			release[65]; /*Can I define 65 automatically?*/
+	unsigned long		sym_mem_map;
+	unsigned long		sym_system_utsname;
 };
