patch_name:	ikconfig_2422pre.patch
patch_version:	2003-08-03.22:23:00
author:		Randy.Dunlap <rddunlap@osdl.org>
description:	_
product:	Linux
product_versions: linux-2422-pre10
changelog:	_
URL:		_
requires:	_
conflicts:	_
maintainer:	_
diffstat:	TBD

diff -Naur ./kernel/Makefile~ikc ./kernel/Makefile
--- ./kernel/Makefile~ikc	2001-09-16 21:22:40.000000000 -0700
+++ ./kernel/Makefile	2003-08-03 22:10:35.000000000 -0700
@@ -19,6 +19,7 @@
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += ksyms.o
 obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_IKCONFIG) += configs.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
@@ -30,3 +31,10 @@
 endif
 
 include $(TOPDIR)/Rules.make
+
+ikconfig.h: $(TOPDIR)/scripts/mkconfigs $(TOPDIR)/.config $(TOPDIR)/Makefile
+	$(CONFIG_SHELL) $(TOPDIR)/scripts/mkconfigs $(TOPDIR)/.config $(TOPDIR)/Makefile > ikconfig.h
+
+configs.o: ikconfig.h configs.c \
+		$(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
+
diff -Naur ./kernel/configs.c~ikc ./kernel/configs.c
--- ./kernel/configs.c~ikc	2003-08-03 20:12:04.000000000 -0700
+++ ./kernel/configs.c	2003-08-03 22:14:56.000000000 -0700
@@ -0,0 +1,188 @@
+/*
+ * kernel/configs.c
+ * Echo the kernel .config file used to build the kernel
+ *
+ * Copyright (C) 2002 Khalid Aziz <khalid_aziz@hp.com>
+ * Copyright (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+ * Copyright (C) 2002 Al Stone <ahs3@fc.hp.com>
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/compile.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+/**************************************************/
+/* the actual current config file                 */
+
+#include "ikconfig.h"
+
+#ifdef CONFIG_IKCONFIG_PROC
+
+/**************************************************/
+/* globals and useful constants                   */
+
+static char *IKCONFIG_NAME = "ikconfig";
+static char *IKCONFIG_VERSION = "0.5";
+
+static int ikconfig_current_size = 0;
+static struct proc_dir_entry *ikconfig_dir, *current_config, *built_with;
+
+static int
+ikconfig_permission_current(struct inode *inode, int op)
+{
+	/* anyone can read the device, no one can write to it */
+	return (op == MAY_READ) ? 0 : -EACCES;
+}
+
+static ssize_t
+ikconfig_output_current(struct file *file, char *buf,
+			 size_t len, loff_t * offset)
+{
+	int i, limit;
+	int cnt;
+
+	limit = (ikconfig_current_size > len) ? len : ikconfig_current_size;
+	for (i = file->f_pos, cnt = 0;
+	     i < ikconfig_current_size && cnt < limit; i++, cnt++) {
+		put_user(ikconfig_config[i], buf + cnt);
+	}
+	file->f_pos = i;
+	return cnt;
+}
+
+static int
+ikconfig_open_current(struct inode *inode, struct file *file)
+{
+	if (file->f_mode & FMODE_READ) {
+		inode->i_size = ikconfig_current_size;
+		file->f_pos = 0;
+	}
+	return 0;
+}
+
+static int
+ikconfig_close_current(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static struct file_operations ikconfig_file_ops = {
+	.read = ikconfig_output_current,
+	.open = ikconfig_open_current,
+	.release = ikconfig_close_current,
+};
+
+static struct inode_operations ikconfig_inode_ops = {
+	.permission = ikconfig_permission_current,
+};
+
+/***************************************************/
+/* proc_read_built_with: let people read the info  */
+/* we have on the tools used to build this kernel  */
+
+static int
+proc_read_built_with(char *page, char **start,
+		     off_t off, int count, int *eof, void *data)
+{
+	*eof = 1;
+	return sprintf(page,
+			"Kernel:    %s\nCompiler:  %s\nVersion_in_Makefile: %s\n",
+			ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE);
+}
+
+/***************************************************/
+/* ikconfig_init: start up everything we need to */
+
+int __init
+ikconfig_init(void)
+{
+	int result = 0;
+
+	printk(KERN_INFO "ikconfig %s with /proc/ikconfig\n",
+	       IKCONFIG_VERSION);
+
+	/* create the ikconfig directory */
+	ikconfig_dir = proc_mkdir(IKCONFIG_NAME, NULL);
+	if (ikconfig_dir == NULL) {
+		result = -ENOMEM;
+		goto leave;
+	}
+	ikconfig_dir->owner = THIS_MODULE;
+
+	/* create the current config file */
+	current_config = create_proc_entry("config", S_IFREG | S_IRUGO,
+					   ikconfig_dir);
+	if (current_config == NULL) {
+		result = -ENOMEM;
+		goto leave2;
+	}
+	current_config->proc_iops = &ikconfig_inode_ops;
+	current_config->proc_fops = &ikconfig_file_ops;
+	current_config->owner = THIS_MODULE;
+	ikconfig_current_size = strlen(ikconfig_config);
+	current_config->size = ikconfig_current_size;
+
+	/* create the "built with" file */
+	built_with = create_proc_read_entry("built_with", 0444, ikconfig_dir,
+					    proc_read_built_with, NULL);
+	if (built_with == NULL) {
+		result = -ENOMEM;
+		goto leave3;
+	}
+	built_with->owner = THIS_MODULE;
+	goto leave;
+
+leave3:
+	/* remove the file from proc */
+	remove_proc_entry("config", ikconfig_dir);
+
+leave2:
+	/* remove the ikconfig directory */
+	remove_proc_entry(IKCONFIG_NAME, NULL);
+
+leave:
+	return result;
+}
+
+/***************************************************/
+/* cleanup_ikconfig: clean up our mess           */
+
+static void
+cleanup_ikconfig(void)
+{
+	/* remove the files */
+	remove_proc_entry("config", ikconfig_dir);
+	remove_proc_entry("built_with", ikconfig_dir);
+
+	/* remove the ikconfig directory */
+	remove_proc_entry(IKCONFIG_NAME, NULL);
+}
+
+module_init(ikconfig_init);
+module_exit(cleanup_ikconfig);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Randy Dunlap");
+MODULE_DESCRIPTION("Echo the kernel .config file used to build the kernel");
+
+#endif /* CONFIG_IKCONFIG_PROC */
diff -Naur ./kernel/mkconfigs~ikc ./kernel/mkconfigs
--- ./kernel/mkconfigs~ikc	2003-08-03 20:15:26.000000000 -0700
+++ ./kernel/mkconfigs	2003-08-03 20:15:44.000000000 -0700
@@ -0,0 +1,81 @@
+#!/bin/sh
+#
+# Copyright (C) 2002 Khalid Aziz <khalid_aziz@hp.com>
+# Copyright (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+# Copyright (C) 2002 Al Stone <ahs3@fc.hp.com>
+# Copyright (C) 2002 Hewlett-Packard Company
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# 
+# Rules to generate ikconfig.h from linux/.config:
+#	- Retain lines that begin with "CONFIG_"
+#	- Retain lines that begin with "# CONFIG_"
+#	- lines that use double-quotes must \\-escape-quote them
+
+
+kernel_version()
+{
+	KERNVER="`grep VERSION $1 | head -1 | cut -f3 -d' '`.`grep PATCHLEVEL $1 | head -1 | cut -f3 -d' '`.`grep SUBLEVEL $1 | head -1 | cut -f3 -d' '``grep EXTRAVERSION $1 | head -1 | cut -f3 -d' '`"
+}
+
+if [ $# -lt 2 ]
+then
+	echo "Usage: `basename $0` <configuration_file> <Makefile>"
+	exit 1
+fi
+
+config=$1
+makefile=$2
+
+echo "#ifndef _IKCONFIG_H"
+echo "#define _IKCONFIG_H"
+echo \
+"/*
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * 
+ * This file is generated automatically by scripts/mkconfigs. Do not edit.
+ *
+ */"
+
+echo "static char *ikconfig_built_with ="
+echo "    \"`uname -s` `uname -r` `uname -v` `uname -m`\";"
+echo
+kernel_version $makefile
+echo "#ifdef CONFIG_IKCONFIG_PROC"
+echo "static char *ikconfig_config = "
+echo "#else"
+echo "static char *ikconfig_config __initdata __attribute__((unused)) = "
+echo "#endif"
+echo "\"CONFIG_BEGIN=n\\n\\"
+echo "`cat $config | sed 's/\"/\\\\\"/g' | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `"
+echo "CONFIG_END=n\\n\";"
+echo "#endif /* _IKCONFIG_H */"
diff -Naur ./arch/i386/defconfig~ikc ./arch/i386/defconfig
--- ./arch/i386/defconfig~ikc	2002-11-28 15:53:09.000000000 -0800
+++ ./arch/i386/defconfig	2003-08-03 19:53:31.000000000 -0700
@@ -107,6 +107,8 @@
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
+CONFIG_IKCONFIG=n
+CONFIG_IKCONFIG_PROC=n
 CONFIG_PM=y
 # CONFIG_APM is not set
 
diff -Naur ./arch/i386/config.in~ikc ./arch/i386/config.in
--- ./arch/i386/config.in~ikc	2003-08-03 13:50:37.000000000 -0700
+++ ./arch/i386/config.in	2003-08-03 21:24:44.000000000 -0700
@@ -324,6 +324,9 @@
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
+bool 'Kernel .config support' CONFIG_IKCONFIG
+dep_bool '  Enable access to .config through /proc/ikconfig' CONFIG_IKCONFIG_PROC $CONFIG_IKCONFIG
+
 bool 'Power Management support' CONFIG_PM
 
 dep_tristate '  Advanced Power Management BIOS support' CONFIG_APM $CONFIG_PM
diff -Naur ./scripts/binoffset.c~ikc ./scripts/binoffset.c
--- ./scripts/binoffset.c~ikc	2003-08-03 20:12:00.000000000 -0700
+++ ./scripts/binoffset.c	2003-08-03 20:14:22.000000000 -0700
@@ -0,0 +1,163 @@
+/***************************************************************************
+ * binoffset.c
+ * (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+ *
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# binoffset.c:
+# - searches a (binary) file for a specified (binary) pattern
+# - returns the offset of the located pattern or ~0 if not found
+# - exits with exit status 0 normally or non-0 if pattern is not found
+#   or any other error occurs.
+
+****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#define VERSION		"0.1"
+#define BUF_SIZE	(16 * 1024)
+#define PAT_SIZE	100
+
+char		*progname;
+char		*inputname;
+int		inputfd;
+int		bix;			/* buf index */
+unsigned char	patterns [PAT_SIZE] = {0}; /* byte-sized pattern array */
+int		pat_len;		/* actual number of pattern bytes */
+unsigned char	*madr;			/* mmap address */
+size_t		filesize;
+int		num_matches = 0;
+off_t		firstloc = 0;
+
+void usage (void)
+{
+	fprintf (stderr, "%s ver. %s\n", progname, VERSION);
+	fprintf (stderr, "usage:  %s filename pattern_bytes\n",
+			progname);
+	fprintf (stderr, "        [prints location of pattern_bytes in file]\n");
+	exit (1);
+}
+
+int get_pattern (int pat_count, char *pats [])
+{
+	int ix, err, tmp;
+
+#ifdef DEBUG
+	fprintf (stderr,"get_pattern: count = %d\n", pat_count);
+	for (ix = 0; ix < pat_count; ix++)
+		fprintf (stderr, "  pat # %d:  [%s]\n", ix, pats[ix]);
+#endif
+
+	for (ix = 0; ix < pat_count; ix++) {
+		tmp = 0;
+		err = sscanf (pats[ix], "%5i", &tmp);
+		if (err != 1 || tmp > 0xff) {
+			fprintf (stderr, "pattern or value error in pattern # %d [%s]\n",
+					ix, pats[ix]);
+			usage ();
+		}
+		patterns [ix] = tmp;
+	}
+	pat_len = pat_count;
+}
+
+int search_pattern (void)
+{
+	for (bix = 0; bix < filesize; bix++) {
+		if (madr[bix] == patterns[0]) {
+			if (memcmp (&madr[bix], patterns, pat_len) == 0) {
+				if (num_matches == 0)
+					firstloc = bix;
+				num_matches++;
+			}
+		}
+	}
+}
+
+#ifdef NOTDEF
+size_t get_filesize (int fd)
+{
+	off_t end_off = lseek (fd, 0, SEEK_END);
+	lseek (fd, 0, SEEK_SET);
+	return (size_t) end_off;
+}
+#endif
+
+size_t get_filesize (int fd)
+{
+	int err;
+	struct stat stat;
+
+	err = fstat (fd, &stat);
+	fprintf (stderr, "filesize: %d\n", err < 0 ? err : stat.st_size);
+	if (err < 0)
+		return err;
+	return (size_t) stat.st_size;
+}
+
+int main (int argc, char *argv [])
+{
+	progname = argv[0];
+
+	if (argc < 3)
+		usage ();
+
+	get_pattern (argc - 2, argv + 2);
+
+	inputname = argv[1];
+
+	inputfd = open (inputname, O_RDONLY);
+	if (inputfd == -1) {
+		fprintf (stderr, "%s: cannot open '%s'\n",
+				progname, inputname);
+		exit (3);
+	}
+
+	filesize = get_filesize (inputfd);
+
+	madr = mmap (0, filesize, PROT_READ, MAP_PRIVATE, inputfd, 0);
+	if (madr == MAP_FAILED) {
+		fprintf (stderr, "mmap error = %d\n", errno);
+		close (inputfd);
+		exit (4);
+	}
+
+	search_pattern ();
+
+	if (munmap (madr, filesize))
+		fprintf (stderr, "munmap error = %d\n", errno);
+
+	if (close (inputfd))
+		fprintf (stderr, "%s: error %d closing '%s'\n",
+				progname, errno, inputname);
+
+	fprintf (stderr, "number of pattern matches = %d\n", num_matches);
+	if (num_matches == 0)
+		firstloc = ~0;
+	printf ("%d\n", firstloc);
+	fprintf (stderr, "%d\n", firstloc);
+
+	exit (num_matches ? 0 : 2);
+}
+
+/* end binoffset.c */
diff -Naur ./scripts/extract-ikconfig~ikc ./scripts/extract-ikconfig
--- ./scripts/extract-ikconfig~ikc	2003-08-03 20:13:11.000000000 -0700
+++ ./scripts/extract-ikconfig	2003-08-03 13:50:43.000000000 -0700
@@ -0,0 +1,17 @@
+#! /bin/bash -x
+# extracts .config info from a [b]zImage file
+# uses: binoffset (new), dd, zcat, strings, grep
+# $arg1 is [b]zImage filename
+
+HDR=`binoffset $1 0x1f 0x8b 0x08 0x0`
+PID=$$
+TMPFILE="$1.vmlin.$PID"
+
+# dd if=$1 bs=1 skip=$HDR | zcat - | strings /dev/stdin \
+# | grep "[A-Za-z_0-9]=[ynm]$" | sed "s/^/CONFIG_/" > $1.oldconfig.$PID
+# exit
+
+dd if=$1 bs=1 skip=$HDR | zcat - > $TMPFILE
+strings $TMPFILE | grep "^[\#[:blank:]]*CONFIG_[A-Za-z_0-9]*" > $1.oldconfig.$PID
+wc $1.oldconfig.$PID
+rm $TMPFILE
diff -Naur ./Documentation/Configure.help~ikc ./Documentation/Configure.help
--- ./Documentation/Configure.help~ikc	2003-08-03 13:50:36.000000000 -0700
+++ ./Documentation/Configure.help	2003-08-03 21:23:03.000000000 -0700
@@ -5351,6 +5351,32 @@
   replacement for kerneld.) Say Y here and read about configuring it
   in <file:Documentation/kmod.txt>.
 
+Kernel .config file saved in kernel image
+CONFIG_IKCONFIG
+  This option enables the complete Linux kernel ".config" file 
+  contents, information on compiler used to build the kernel, 
+  kernel running when this kernel was built and kernel version 
+  from Makefile to be saved in kernel. It provides documentation 
+  of which kernel options are used in a running kernel or in an 
+  on-disk kernel.  This information can be extracted from the kernel 
+  image file with the script scripts/extract-ikconfig and used as 
+  input to rebuild the current kernel or to build another kernel. 
+  It can also be extracted from a running kernel by reading 
+  /proc/ikconfig/config and /proc/ikconfig/built_with, if enabled. 
+  /proc/ikconfig/config will list the configuration that was used 
+  to build the kernel and /proc/ikconfig/built_with will list 
+  information on the compiler and host machine that was used to 
+  build the kernel.  Since the kernel image is zipped, using this
+  option adds approximately 8 KB to a kernel image file.
+  This option is not available as a module.  If you want a separate
+  file to save the kernel's .config contents, use 'installkernel' or 'cp'
+  or a similar tool, or just save it in '/lib/modules/<kernel-version>'.
+
+"Enable access to .config through /proc/ikconfig"
+CONFIG_IKCONFIG_PROC
+  This option enables access to kernel configuration file and build
+  information through /proc/ikconfig.
+
 ARP daemon support
 CONFIG_ARPD
   Normally, the kernel maintains an internal cache which maps IP
diff -Naur ./Makefile~ikc ./Makefile
--- ./Makefile~ikc	2003-08-03 13:50:36.000000000 -0700
+++ ./Makefile	2003-08-03 20:00:43.000000000 -0700
@@ -203,6 +203,7 @@
 	kernel/ksyms.lst include/linux/compile.h \
 	vmlinux System.map \
 	.tmp* \
+	kernel/ikconfig.h \
 	drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
 	drivers/char/conmakehash \
 	drivers/char/drm/*-mod.c \
@@ -248,6 +249,7 @@
 	include/asm \
 	.hdepend scripts/mkdep scripts/split-include scripts/docproc \
 	$(TOPDIR)/include/linux/modversions.h \
+	kernel/ikconfig.h \
 	kernel.spec
 
 # directories removed with 'make mrproper'
