From: "Randy.Dunlap" The SuSE kernels place their ikconfig info at /proc/config.gz: in a different place, and compressed. We thought it was a good idea to do it that way in 2.6 as well. - gzip the /proc config file, put it in /proc/config.gz; - Based on a SuSE patch by Oliver Xymoron , which was derived from a patch by Nicholas Leon - change /proc/ikconfig/built_with to /proc/config_build_info; - cleanup ikconfig init/exit entry points (static, __init, __exit); - Makefile help from Sam Ravnborg; DESC ikconfig cleanup EDESC From: Stephen Hemminger Simplify and cleanup the code: - use single interface to seq_file where possible - don't need to do as much of the /proc interface, only read - use copy_to_user to avoid char at a time copy - remove unneccesary globals - use const char[] rather than const char * where possible. Didn't change the version since interface doesn't change. 25-akpm/init/Kconfig | 12 ++--- 25-akpm/kernel/Makefile | 25 ++++++++++- 25-akpm/kernel/configs.c | 98 ++++++++++++++++++++-------------------------- 25-akpm/scripts/Makefile | 2 25-akpm/scripts/bin2c.c | 27 ++++++++++++ 25-akpm/scripts/mkconfigs | 10 +--- 6 files changed, 104 insertions(+), 70 deletions(-) diff -puN init/Kconfig~ikconfig-gzipped-2 init/Kconfig --- 25/init/Kconfig~ikconfig-gzipped-2 Thu Sep 4 15:41:28 2003 +++ 25-akpm/init/Kconfig Thu Sep 4 15:42:12 2003 @@ -134,24 +134,24 @@ 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 + from Makefile to be saved in the 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 + /proc/config.gz and /proc/config_built_with, if enabled (below). + /proc/config.gz will list the configuration that was used + to build the kernel and /proc/config_built_with will list information on the compiler and host machine that was used to build the kernel. config IKCONFIG_PROC - bool "Enable access to .config through /proc/ikconfig" + bool "Enable access to .config through /proc/config.gz" depends on IKCONFIG && PROC_FS ---help--- This option enables access to kernel configuration file and build - information through /proc/ikconfig. + information through /proc/config.gz. menuconfig EMBEDDED diff -puN kernel/configs.c~ikconfig-gzipped-2 kernel/configs.c --- 25/kernel/configs.c~ikconfig-gzipped-2 Thu Sep 4 15:41:28 2003 +++ 25-akpm/kernel/configs.c Thu Sep 4 15:42:28 2003 @@ -23,6 +23,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include @@ -35,129 +36,116 @@ /**************************************************/ /* the actual current config file */ +/* This one is for extraction from the kernel binary file image. */ #include "ikconfig.h" #ifdef CONFIG_IKCONFIG_PROC +/* This is the data that can be read from /proc/config.gz. */ +#include "config_data.h" + /**************************************************/ /* globals and useful constants */ -static const char IKCONFIG_NAME[] = "ikconfig"; static const char IKCONFIG_VERSION[] = "0.6"; -static int ikconfig_size; -static struct proc_dir_entry *ikconfig_dir; - static ssize_t -ikconfig_read(struct file *file, char __user *buf, - size_t len, loff_t *offset) +ikconfig_read_current(struct file *file, char __user *buf, + size_t len, loff_t * offset) { loff_t pos = *offset; ssize_t count; - - if (pos >= ikconfig_size) + + if (pos >= kernel_config_data_size) return 0; - count = min(len, (size_t)(ikconfig_size - pos)); - if(copy_to_user(buf, ikconfig_config + pos, count)) + count = min(len, (size_t)(kernel_config_data_size - pos)); + if(copy_to_user(buf, kernel_config_data + pos, count)) return -EFAULT; *offset += count; return count; } -static struct file_operations config_fops = { +static struct file_operations ikconfig_file_ops = { .owner = THIS_MODULE, - .read = ikconfig_read, + .read = ikconfig_read_current, }; + /***************************************************/ -/* built_with_show: let people read the info */ +/* build_info_show: let people read the info */ /* we have on the tools used to build this kernel */ -static int builtwith_show(struct seq_file *seq, void *v) +static int build_info_show(struct seq_file *seq, void *v) { - seq_printf(seq, + seq_printf(seq, "Kernel: %s\nCompiler: %s\nVersion_in_Makefile: %s\n", - ikconfig_built_with, LINUX_COMPILER, UTS_RELEASE); + ikconfig_build_info, LINUX_COMPILER, UTS_RELEASE); return 0; } -static int built_with_open(struct inode *inode, struct file *file) +static int build_info_open(struct inode *inode, struct file *file) { - return single_open(file, builtwith_show, PDE(inode)->data); + return single_open(file, build_info_show, PDE(inode)->data); } - -static struct file_operations builtwith_fops = { + +static struct file_operations build_info_file_ops = { .owner = THIS_MODULE, - .open = built_with_open, + .open = build_info_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, -}; +}; /***************************************************/ /* ikconfig_init: start up everything we need to */ -int __init -ikconfig_init(void) +static int __init ikconfig_init(void) { struct proc_dir_entry *entry; - printk(KERN_INFO "ikconfig %s with /proc/ikconfig\n", + printk(KERN_INFO "ikconfig %s with /proc/config*\n", IKCONFIG_VERSION); - /* create the ikconfig directory */ - ikconfig_dir = proc_mkdir(IKCONFIG_NAME, NULL); - if (ikconfig_dir == NULL) - goto leave; - ikconfig_dir->owner = THIS_MODULE; - /* create the current config file */ - entry = create_proc_entry("config", S_IFREG | S_IRUGO, ikconfig_dir); + entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO, + &proc_root); if (!entry) - goto leave2; + goto leave; - entry->proc_fops = &config_fops; - entry->size = ikconfig_size = strlen(ikconfig_config); + entry->proc_fops = &ikconfig_file_ops; + entry->size = kernel_config_data_size; - /* create the "built with" file */ - entry = create_proc_entry("built_with", S_IFREG | S_IRUGO, - ikconfig_dir); + /* create the "build_info" file */ + entry = create_proc_entry("config_build_info", + S_IFREG | S_IRUGO, &proc_root); if (!entry) - goto leave3; - entry->proc_fops = &builtwith_fops; + goto leave_gz; + entry->proc_fops = &build_info_file_ops; return 0; -leave3: +leave_gz: /* remove the file from proc */ - remove_proc_entry("config", ikconfig_dir); - -leave2: - /* remove the ikconfig directory */ - remove_proc_entry(IKCONFIG_NAME, NULL); + remove_proc_entry("config.gz", &proc_root); leave: return -ENOMEM; } /***************************************************/ -/* cleanup_ikconfig: clean up our mess */ +/* ikconfig_cleanup: clean up our mess */ -static void -cleanup_ikconfig(void) +static void __exit ikconfig_cleanup(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); + remove_proc_entry("config.gz", &proc_root); + remove_proc_entry("config_build_info", &proc_root); } module_init(ikconfig_init); -module_exit(cleanup_ikconfig); +module_exit(ikconfig_cleanup); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Randy Dunlap"); diff -puN kernel/Makefile~ikconfig-gzipped-2 kernel/Makefile --- 25/kernel/Makefile~ikconfig-gzipped-2 Thu Sep 4 15:41:28 2003 +++ 25-akpm/kernel/Makefile Thu Sep 4 15:42:12 2003 @@ -19,6 +19,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_IKCONFIG) += configs.o +obj-$(CONFIG_IKCONFIG_PROC) += configs.o ifneq ($(CONFIG_IA64),y) # According to Alan Modra , the -fno-omit-frame-pointer is @@ -29,12 +30,32 @@ ifneq ($(CONFIG_IA64),y) CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer endif +# configs.o uses generated files - dependecies must be listed explicitly +$(obj)/configs.o: $(obj)/ikconfig.h + +ifdef CONFIG_IKCONFIG_PROC +$(obj)/configs.o: $(obj)/config_data.h +endif + +# ikconfig.h contains all the selected config entries - generated +# from top-level Makefile and .config. Info from ikconfig.h can +# be extracted from the kernel binary. + quiet_cmd_ikconfig = IKCFG $@ cmd_ikconfig = $(CONFIG_SHELL) $< .config $(srctree)/Makefile > $@ targets += ikconfig.h - $(obj)/ikconfig.h: scripts/mkconfigs .config Makefile FORCE $(call if_changed,ikconfig) -$(obj)/configs.o: $(obj)/ikconfig.h +# config_data.h contains the same information as ikconfig.h but gzipped. +# Info from config_data can be extracted from /proc/config* +targets += config_data.gz +$(obj)/config_data.gz: .config FORCE + $(call if_changed,gzip) + +quiet_cmd_ikconfiggz = IKCFG $@ + cmd_ikconfiggz = cat $< | scripts/bin2c kernel_config_data > $@ +targets += config_data.h +$(obj)/config_data.h: $(obj)/config_data.gz FORCE + $(call if_changed,ikconfiggz) diff -puN /dev/null scripts/bin2c.c --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/scripts/bin2c.c Thu Sep 4 15:42:28 2003 @@ -0,0 +1,27 @@ +#include + +int main(int argc, char *argv[]) +{ + int ch, total=0; + + if (argc > 1) + printf("const char %s[] %s=\n", + argv[1], argc > 2 ? argv[2] : ""); + + do { + printf("\t\""); + while ((ch = getchar()) != EOF) + { + total++; + printf("\\x%02x",ch); + if (total % 16 == 0) + break; + } + printf("\"\n"); + } while (ch != EOF); + + if (argc > 1) + printf("\t;\n\nconst int %s_size = %d;\n", argv[1], total); + + return 0; +} diff -puN scripts/Makefile~ikconfig-gzipped-2 scripts/Makefile --- 25/scripts/Makefile~ikconfig-gzipped-2 Thu Sep 4 15:41:28 2003 +++ 25-akpm/scripts/Makefile Thu Sep 4 15:42:12 2003 @@ -9,7 +9,7 @@ # conmakehash: Create arrays for initializing the kernel console tables host-progs := fixdep split-include conmakehash docproc kallsyms modpost \ - mk_elfconfig pnmtologo + mk_elfconfig pnmtologo bin2c always := $(host-progs) empty.o modpost-objs := modpost.o file2alias.o diff -puN scripts/mkconfigs~ikconfig-gzipped-2 scripts/mkconfigs --- 25/scripts/mkconfigs~ikconfig-gzipped-2 Thu Sep 4 15:41:28 2003 +++ 25-akpm/scripts/mkconfigs Thu Sep 4 15:42:28 2003 @@ -66,15 +66,13 @@ echo \ * */" -echo "static char *ikconfig_built_with =" +echo "#ifdef CONFIG_IKCONFIG_PROC" +echo "static char const ikconfig_build_info[] =" echo " \"`uname -s` `uname -r` `uname -v` `uname -m`\";" +echo "#endif" 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 "static char const ikconfig_config[] __attribute__((unused)) = " echo "\"CONFIG_BEGIN=n\\n\\" echo "`cat $config | sed 's/\"/\\\\\"/g' | grep "^#\? \?CONFIG_" | awk '{ print $0 "\\\\n\\\\" }' `" echo "CONFIG_END=n\\n\";" _