diff -urN linux-2.4.26-pre6/Documentation/Configure.help 2.4.26-pre6-ikconfig/Documentation/Configure.help --- linux-2.4.26-pre6/Documentation/Configure.help Thu Mar 25 09:05:11 2004 +++ 2.4.26-pre6-ikconfig/Documentation/Configure.help Thu Mar 25 09:45:04 2004 @@ -5885,6 +5885,32 @@ replacement for kerneld.) Say Y here and read about configuring it in . +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/'. + +"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 -urN linux-2.4.26-pre6/Makefile 2.4.26-pre6-ikconfig/Makefile --- linux-2.4.26-pre6/Makefile Thu Mar 25 09:05:11 2004 +++ 2.4.26-pre6-ikconfig/Makefile Thu Mar 25 09:45:54 2004 @@ -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 \ @@ -250,6 +251,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' @@ -546,6 +548,9 @@ # # This generates dependencies for the .h files. # + +scripts/mkconfigs: scripts/mkconfigs.c + $(HOSTCC) $(HOSTCFLAGS) -o scripts/mkconfigs scripts/mkconfigs.c scripts/mkdep: scripts/mkdep.c $(HOSTCC) $(HOSTCFLAGS) -o scripts/mkdep scripts/mkdep.c diff -urN linux-2.4.26-pre6/arch/i386/config.in 2.4.26-pre6-ikconfig/arch/i386/config.in --- linux-2.4.26-pre6/arch/i386/config.in Thu Feb 5 17:30:47 2004 +++ 2.4.26-pre6-ikconfig/arch/i386/config.in Thu Mar 25 09:45:04 2004 @@ -330,6 +330,9 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC bool 'Select task to kill on out of memory condition' CONFIG_OOM_KILLER +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 -urN linux-2.4.26-pre6/arch/i386/defconfig 2.4.26-pre6-ikconfig/arch/i386/defconfig --- linux-2.4.26-pre6/arch/i386/defconfig Sun Mar 21 17:23:16 2004 +++ 2.4.26-pre6-ikconfig/arch/i386/defconfig Thu Mar 25 09:45:33 2004 @@ -113,6 +113,8 @@ CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y +CONFIG_IKCONFIG=n +CONFIG_IKCONFIG_PROC=n # CONFIG_OOM_KILLER is not set CONFIG_PM=y # CONFIG_APM is not set diff -urN linux-2.4.26-pre6/kernel/Makefile 2.4.26-pre6-ikconfig/kernel/Makefile --- linux-2.4.26-pre6/kernel/Makefile Mon Sep 17 06:22:40 2001 +++ 2.4.26-pre6-ikconfig/kernel/Makefile Thu Mar 25 09:45:54 2004 @@ -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 , the -fno-omit-frame-pointer is @@ -30,3 +31,10 @@ endif include $(TOPDIR)/Rules.make + +ikconfig.h: $(TOPDIR)/kernel/mkconfigs $(TOPDIR)/.config $(TOPDIR)/Makefile + $(CONFIG_SHELL) $(TOPDIR)/kernel/mkconfigs $(TOPDIR)/.config $(TOPDIR)/Makefile > ikconfig.h + +configs.o: ikconfig.h configs.c \ + $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h + diff -urN linux-2.4.26-pre6/kernel/configs.c 2.4.26-pre6-ikconfig/kernel/configs.c --- linux-2.4.26-pre6/kernel/configs.c Thu Jan 1 01:00:00 1970 +++ 2.4.26-pre6-ikconfig/kernel/configs.c Thu Mar 25 09:45:03 2004 @@ -0,0 +1,188 @@ +/* + * kernel/configs.c + * Echo the kernel .config file used to build the kernel + * + * Copyright (C) 2002 Khalid Aziz + * Copyright (C) 2002 Randy Dunlap + * Copyright (C) 2002 Al Stone + * 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 +#include +#include +#include +#include +#include +#include + +/**************************************************/ +/* 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 -urN linux-2.4.26-pre6/kernel/mkconfigs 2.4.26-pre6-ikconfig/kernel/mkconfigs --- linux-2.4.26-pre6/kernel/mkconfigs Thu Jan 1 01:00:00 1970 +++ 2.4.26-pre6-ikconfig/kernel/mkconfigs Thu Mar 25 09:45:03 2004 @@ -0,0 +1,81 @@ +#!/bin/sh +# +# Copyright (C) 2002 Khalid Aziz +# Copyright (C) 2002 Randy Dunlap +# Copyright (C) 2002 Al Stone +# 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` " + 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 -urN linux-2.4.26-pre6/scripts/binoffset.c 2.4.26-pre6-ikconfig/scripts/binoffset.c --- linux-2.4.26-pre6/scripts/binoffset.c Thu Jan 1 01:00:00 1970 +++ 2.4.26-pre6-ikconfig/scripts/binoffset.c Thu Mar 25 09:45:04 2004 @@ -0,0 +1,163 @@ +/*************************************************************************** + * binoffset.c + * (C) 2002 Randy Dunlap + * +# 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#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 */