1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl 20c874100SMasahiro Yamada# SPDX-License-Identifier: GPL-2.0 3dcc60243SSteven Rostedt# 4cce1dac8SUwe Kleine-König# Copyright 2005-2009 - Steven Rostedt 5dcc60243SSteven Rostedt# 6dcc60243SSteven Rostedt# It's simple enough to figure out how this works. 7dcc60243SSteven Rostedt# If not, then you can ask me at stripconfig@goodmis.org 8dcc60243SSteven Rostedt# 9dcc60243SSteven Rostedt# What it does? 10dcc60243SSteven Rostedt# 11dcc60243SSteven Rostedt# If you have installed a Linux kernel from a distribution 12dcc60243SSteven Rostedt# that turns on way too many modules than you need, and 13dcc60243SSteven Rostedt# you only want the modules you use, then this program 14dcc60243SSteven Rostedt# is perfect for you. 15dcc60243SSteven Rostedt# 16dcc60243SSteven Rostedt# It gives you the ability to turn off all the modules that are 17dcc60243SSteven Rostedt# not loaded on your system. 18dcc60243SSteven Rostedt# 19dcc60243SSteven Rostedt# Howto: 20dcc60243SSteven Rostedt# 21dcc60243SSteven Rostedt# 1. Boot up the kernel that you want to stream line the config on. 22dcc60243SSteven Rostedt# 2. Change directory to the directory holding the source of the 23dcc60243SSteven Rostedt# kernel that you just booted. 2421f8b32fSBhaskar Chowdhury# 3. Copy the configuration file to this directory as .config 25dcc60243SSteven Rostedt# 4. Have all your devices that you need modules for connected and 26dcc60243SSteven Rostedt# operational (make sure that their corresponding modules are loaded) 27dcc60243SSteven Rostedt# 5. Run this script redirecting the output to some other file 28dcc60243SSteven Rostedt# like config_strip. 29dcc60243SSteven Rostedt# 6. Back up your old config (if you want too). 30dcc60243SSteven Rostedt# 7. copy the config_strip file to .config 31dcc60243SSteven Rostedt# 8. Run "make oldconfig" 32dcc60243SSteven Rostedt# 33dcc60243SSteven Rostedt# Now your kernel is ready to be built with only the modules that 34dcc60243SSteven Rostedt# are loaded. 35dcc60243SSteven Rostedt# 36dcc60243SSteven Rostedt# Here's what I did with my Debian distribution. 37dcc60243SSteven Rostedt# 38dcc60243SSteven Rostedt# cd /usr/src/linux-2.6.10 39dcc60243SSteven Rostedt# cp /boot/config-2.6.10-1-686-smp .config 40dcc60243SSteven Rostedt# ~/bin/streamline_config > config_strip 41dcc60243SSteven Rostedt# mv .config config_sav 42dcc60243SSteven Rostedt# mv config_strip .config 43dcc60243SSteven Rostedt# make oldconfig 44dcc60243SSteven Rostedt# 45cb77f0d6SKamil Rytarowskiuse warnings; 46cf5a189dShiromuuse strict; 4722d550aeSArnaud Lacombeuse Getopt::Long; 48cf5a189dShiromu 494503379cSSteven Rostedt# set the environment variable LOCALMODCONFIG_DEBUG to get 504503379cSSteven Rostedt# debug output. 514503379cSSteven Rostedtmy $debugprint = 0; 524503379cSSteven Rostedt$debugprint = 1 if (defined($ENV{LOCALMODCONFIG_DEBUG})); 534503379cSSteven Rostedt 544503379cSSteven Rostedtsub dprint { 554503379cSSteven Rostedt return if (!$debugprint); 564503379cSSteven Rostedt print STDERR @_; 574503379cSSteven Rostedt} 584503379cSSteven Rostedt 59cdfc4795SSteven Rostedtmy $uname = `uname -r`; 60cdfc4795SSteven Rostedtchomp $uname; 61cdfc4795SSteven Rostedt 62cdfc4795SSteven Rostedtmy @searchconfigs = ( 63cdfc4795SSteven Rostedt { 64a9024838SSteven Rostedt "file" => ".config", 65a9024838SSteven Rostedt "exec" => "cat", 66a9024838SSteven Rostedt }, 67a9024838SSteven Rostedt { 68cdfc4795SSteven Rostedt "file" => "/proc/config.gz", 69cdfc4795SSteven Rostedt "exec" => "zcat", 70cdfc4795SSteven Rostedt }, 71cdfc4795SSteven Rostedt { 72810b2be6SSteven Rostedt "file" => "/boot/config-$uname", 73810b2be6SSteven Rostedt "exec" => "cat", 74810b2be6SSteven Rostedt }, 75810b2be6SSteven Rostedt { 76cdfc4795SSteven Rostedt "file" => "/boot/vmlinuz-$uname", 77cdfc4795SSteven Rostedt "exec" => "scripts/extract-ikconfig", 78cdfc4795SSteven Rostedt "test" => "scripts/extract-ikconfig", 79cdfc4795SSteven Rostedt }, 80cdfc4795SSteven Rostedt { 81cdfc4795SSteven Rostedt "file" => "vmlinux", 82cdfc4795SSteven Rostedt "exec" => "scripts/extract-ikconfig", 83cdfc4795SSteven Rostedt "test" => "scripts/extract-ikconfig", 84cdfc4795SSteven Rostedt }, 85cdfc4795SSteven Rostedt { 86cdfc4795SSteven Rostedt "file" => "/lib/modules/$uname/kernel/kernel/configs.ko", 87cdfc4795SSteven Rostedt "exec" => "scripts/extract-ikconfig", 88cdfc4795SSteven Rostedt "test" => "scripts/extract-ikconfig", 89cdfc4795SSteven Rostedt }, 90cdfc4795SSteven Rostedt { 91cdfc4795SSteven Rostedt "file" => "kernel/configs.ko", 92cdfc4795SSteven Rostedt "exec" => "scripts/extract-ikconfig", 93cdfc4795SSteven Rostedt "test" => "scripts/extract-ikconfig", 94cdfc4795SSteven Rostedt }, 95cdfc4795SSteven Rostedt { 96cdfc4795SSteven Rostedt "file" => "kernel/configs.o", 97cdfc4795SSteven Rostedt "exec" => "scripts/extract-ikconfig", 98cdfc4795SSteven Rostedt "test" => "scripts/extract-ikconfig", 99cdfc4795SSteven Rostedt }, 100cdfc4795SSteven Rostedt); 101cdfc4795SSteven Rostedt 1023f0c5413SBill Pembertonsub read_config { 103cdfc4795SSteven Rostedt foreach my $conf (@searchconfigs) { 104cdfc4795SSteven Rostedt my $file = $conf->{"file"}; 105cdfc4795SSteven Rostedt 106cdfc4795SSteven Rostedt next if ( ! -f "$file"); 107cdfc4795SSteven Rostedt 108cdfc4795SSteven Rostedt if (defined($conf->{"test"})) { 109cdfc4795SSteven Rostedt `$conf->{"test"} $conf->{"file"} 2>/dev/null`; 110cdfc4795SSteven Rostedt next if ($?); 111cdfc4795SSteven Rostedt } 112cdfc4795SSteven Rostedt 113cdfc4795SSteven Rostedt my $exec = $conf->{"exec"}; 114cdfc4795SSteven Rostedt 115cdfc4795SSteven Rostedt print STDERR "using config: '$file'\n"; 116cdfc4795SSteven Rostedt 1173f0c5413SBill Pemberton open(my $infile, '-|', "$exec $file") || die "Failed to run $exec $file"; 1183f0c5413SBill Pemberton my @x = <$infile>; 1193f0c5413SBill Pemberton close $infile; 1203f0c5413SBill Pemberton return @x; 121cdfc4795SSteven Rostedt } 122cdfc4795SSteven Rostedt die "No config file found"; 123cdfc4795SSteven Rostedt} 124cdfc4795SSteven Rostedt 1253f0c5413SBill Pembertonmy @config_file = read_config; 1264f4c51c9SSteven Rostedt 12722d550aeSArnaud Lacombe# Parse options 12822d550aeSArnaud Lacombemy $localmodconfig = 0; 12922d550aeSArnaud Lacombemy $localyesconfig = 0; 13022d550aeSArnaud Lacombe 13122d550aeSArnaud LacombeGetOptions("localmodconfig" => \$localmodconfig, 13222d550aeSArnaud Lacombe "localyesconfig" => \$localyesconfig); 13322d550aeSArnaud Lacombe 134463bf900SSteven Rostedt# Get the build source and top level Kconfig file (passed in) 135224a2571SBill Pembertonmy $ksource = ($ARGV[0] ? $ARGV[0] : '.'); 136463bf900SSteven Rostedtmy $kconfig = $ARGV[1]; 137f597a718SArnaud Lacombemy $lsmod_file = $ENV{'LSMOD'}; 138463bf900SSteven Rostedt 139c0ddc8c7SRichard Weinbergermy @makefiles = `find $ksource -name Makefile -or -name Kbuild 2>/dev/null`; 14017431928SToralf Försterchomp @makefiles; 14117431928SToralf Förster 142dcc60243SSteven Rostedtmy %depends; 143dcc60243SSteven Rostedtmy %selects; 144dcc60243SSteven Rostedtmy %prompts; 145dcc60243SSteven Rostedtmy %objects; 146c027b02dSChangbin Dumy %config2kfile; 147dcc60243SSteven Rostedtmy $var; 14813d7e938SSteven Rostedtmy $iflevel = 0; 14913d7e938SSteven Rostedtmy @ifdeps; 150dcc60243SSteven Rostedt 151dcc60243SSteven Rostedt# prevent recursion 152dcc60243SSteven Rostedtmy %read_kconfigs; 153dcc60243SSteven Rostedt 154dcc60243SSteven Rostedtsub read_kconfig { 155dcc60243SSteven Rostedt my ($kconfig) = @_; 156dcc60243SSteven Rostedt 157dcc60243SSteven Rostedt my $state = "NONE"; 158dcc60243SSteven Rostedt my $config; 159dcc60243SSteven Rostedt 16020d19047SSteven Rostedt my $cont = 0; 16120d19047SSteven Rostedt my $line; 16220d19047SSteven Rostedt 1634908980bSSteven Rostedt my $source = "$ksource/$kconfig"; 1644908980bSSteven Rostedt my $last_source = ""; 1654908980bSSteven Rostedt 1664908980bSSteven Rostedt # Check for any environment variables used 1678593080cSSam Ravnborg while ($source =~ /\$\((\w+)\)/ && $last_source ne $source) { 1684908980bSSteven Rostedt my $env = $1; 1694908980bSSteven Rostedt $last_source = $source; 1708593080cSSam Ravnborg $source =~ s/\$\($env\)/$ENV{$env}/; 1714908980bSSteven Rostedt } 1724908980bSSteven Rostedt 1730431acd8SŁukasz Stelmach open(my $kinfile, '<', $source) || die "Can't open $source"; 174e0d28694SBill Pemberton while (<$kinfile>) { 175dcc60243SSteven Rostedt chomp; 176dcc60243SSteven Rostedt 17720d19047SSteven Rostedt # Make sure that lines ending with \ continue 17820d19047SSteven Rostedt if ($cont) { 17920d19047SSteven Rostedt $_ = $line . " " . $_; 18020d19047SSteven Rostedt } 18120d19047SSteven Rostedt 18220d19047SSteven Rostedt if (s/\\$//) { 18320d19047SSteven Rostedt $cont = 1; 18420d19047SSteven Rostedt $line = $_; 18520d19047SSteven Rostedt next; 18620d19047SSteven Rostedt } 18720d19047SSteven Rostedt 18820d19047SSteven Rostedt $cont = 0; 18920d19047SSteven Rostedt 190dcc60243SSteven Rostedt # collect any Kconfig sources 191296471adSBenjamin Poirier if (/^source\s+"?([^"]+)/) { 192ced9cb1aSSteven Rostedt my $kconfig = $1; 193ced9cb1aSSteven Rostedt # prevent reading twice. 194ced9cb1aSSteven Rostedt if (!defined($read_kconfigs{$kconfig})) { 195ced9cb1aSSteven Rostedt $read_kconfigs{$kconfig} = 1; 196ced9cb1aSSteven Rostedt read_kconfig($kconfig); 197ced9cb1aSSteven Rostedt } 198ced9cb1aSSteven Rostedt next; 199dcc60243SSteven Rostedt } 200dcc60243SSteven Rostedt 201dcc60243SSteven Rostedt # configs found 2028ef17fa2SSteven Rostedt if (/^\s*(menu)?config\s+(\S+)\s*$/) { 203dcc60243SSteven Rostedt $state = "NEW"; 2048ef17fa2SSteven Rostedt $config = $2; 205c027b02dSChangbin Du $config2kfile{"CONFIG_$config"} = $kconfig; 206dcc60243SSteven Rostedt 2070b58a99eSSteven Rostedt # Add depends for 'if' nesting 20813d7e938SSteven Rostedt for (my $i = 0; $i < $iflevel; $i++) { 20913d7e938SSteven Rostedt if ($i) { 21013d7e938SSteven Rostedt $depends{$config} .= " " . $ifdeps[$i]; 21113d7e938SSteven Rostedt } else { 21213d7e938SSteven Rostedt $depends{$config} = $ifdeps[$i]; 21313d7e938SSteven Rostedt } 21413d7e938SSteven Rostedt $state = "DEP"; 21513d7e938SSteven Rostedt } 21613d7e938SSteven Rostedt 217dcc60243SSteven Rostedt # collect the depends for the config 218dcc60243SSteven Rostedt } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { 219dcc60243SSteven Rostedt $state = "DEP"; 220dcc60243SSteven Rostedt $depends{$config} = $1; 221dcc60243SSteven Rostedt } elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) { 222dcc60243SSteven Rostedt $depends{$config} .= " " . $1; 22395edca5cSSteven Rostedt (Red Hat) } elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) { 22495edca5cSSteven Rostedt (Red Hat) my $dep = $3; 22595edca5cSSteven Rostedt (Red Hat) if ($dep !~ /^\s*(y|m|n)\s*$/) { 22695edca5cSSteven Rostedt (Red Hat) $dep =~ s/.*\sif\s+//; 22795edca5cSSteven Rostedt (Red Hat) $depends{$config} .= " " . $dep; 22895edca5cSSteven Rostedt (Red Hat) dprint "Added default depends $dep to $config\n"; 22995edca5cSSteven Rostedt (Red Hat) } 230dcc60243SSteven Rostedt 231dcc60243SSteven Rostedt # Get the configs that select this config 232dcc60243SSteven Rostedt } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { 2330b58a99eSSteven Rostedt my $conf = $1; 2340b58a99eSSteven Rostedt if (defined($selects{$conf})) { 2350b58a99eSSteven Rostedt $selects{$conf} .= " " . $config; 236dcc60243SSteven Rostedt } else { 2370b58a99eSSteven Rostedt $selects{$conf} = $config; 238dcc60243SSteven Rostedt } 239dcc60243SSteven Rostedt 240dcc60243SSteven Rostedt # configs without prompts must be selected 2415bcba792SBenjamin Poirier } elsif ($state ne "NONE" && /^\s*(tristate\s+\S|prompt\b)/) { 242dcc60243SSteven Rostedt # note if the config has a prompt 243ccece60aShiromu yagura $prompts{$config} = 1; 244dcc60243SSteven Rostedt 24513d7e938SSteven Rostedt # Check for if statements 24613d7e938SSteven Rostedt } elsif (/^if\s+(.*\S)\s*$/) { 24713d7e938SSteven Rostedt my $deps = $1; 24813d7e938SSteven Rostedt # remove beginning and ending non text 24913d7e938SSteven Rostedt $deps =~ s/^[^a-zA-Z0-9_]*//; 25013d7e938SSteven Rostedt $deps =~ s/[^a-zA-Z0-9_]*$//; 25113d7e938SSteven Rostedt 25213d7e938SSteven Rostedt my @deps = split /[^a-zA-Z0-9_]+/, $deps; 25313d7e938SSteven Rostedt 25413d7e938SSteven Rostedt $ifdeps[$iflevel++] = join ':', @deps; 25513d7e938SSteven Rostedt 25613d7e938SSteven Rostedt } elsif (/^endif/) { 25713d7e938SSteven Rostedt 25813d7e938SSteven Rostedt $iflevel-- if ($iflevel); 25913d7e938SSteven Rostedt 26027b71568SBenjamin Poirier # stop on "help" and keywords that end a menu entry 261a77ed525SBenjamin Poirier } elsif (/^\s*(---)?help(---)?\s*$/ || /^(comment|choice|menu)\b/) { 262dcc60243SSteven Rostedt $state = "NONE"; 263dcc60243SSteven Rostedt } 264dcc60243SSteven Rostedt } 265e0d28694SBill Pemberton close($kinfile); 266dcc60243SSteven Rostedt} 267dcc60243SSteven Rostedt 268dcc60243SSteven Rostedtif ($kconfig) { 269dcc60243SSteven Rostedt read_kconfig($kconfig); 270dcc60243SSteven Rostedt} 271dcc60243SSteven Rostedt 2720b58a99eSSteven Rostedt# Makefiles can use variables to define their dependencies 273364212fdSSteven Rostedtsub convert_vars { 274364212fdSSteven Rostedt my ($line, %vars) = @_; 275364212fdSSteven Rostedt 276364212fdSSteven Rostedt my $process = ""; 277364212fdSSteven Rostedt 278364212fdSSteven Rostedt while ($line =~ s/^(.*?)(\$\((.*?)\))//) { 279364212fdSSteven Rostedt my $start = $1; 280364212fdSSteven Rostedt my $variable = $2; 281364212fdSSteven Rostedt my $var = $3; 282364212fdSSteven Rostedt 283364212fdSSteven Rostedt if (defined($vars{$var})) { 284364212fdSSteven Rostedt $process .= $start . $vars{$var}; 285364212fdSSteven Rostedt } else { 286364212fdSSteven Rostedt $process .= $start . $variable; 287364212fdSSteven Rostedt } 288364212fdSSteven Rostedt } 289364212fdSSteven Rostedt 290364212fdSSteven Rostedt $process .= $line; 291364212fdSSteven Rostedt 292364212fdSSteven Rostedt return $process; 293364212fdSSteven Rostedt} 294364212fdSSteven Rostedt 295dcc60243SSteven Rostedt# Read all Makefiles to map the configs to the objects 296dcc60243SSteven Rostedtforeach my $makefile (@makefiles) { 297dcc60243SSteven Rostedt 298d060d963SSteven Rostedt my $line = ""; 299364212fdSSteven Rostedt my %make_vars; 30020d19047SSteven Rostedt 301e0d28694SBill Pemberton open(my $infile, '<', $makefile) || die "Can't open $makefile"; 302e0d28694SBill Pemberton while (<$infile>) { 303d060d963SSteven Rostedt # if this line ends with a backslash, continue 304d060d963SSteven Rostedt chomp; 305d060d963SSteven Rostedt if (/^(.*)\\$/) { 306d060d963SSteven Rostedt $line .= $1; 307d060d963SSteven Rostedt next; 308dcc60243SSteven Rostedt } 309d060d963SSteven Rostedt 310d060d963SSteven Rostedt $line .= $_; 311d060d963SSteven Rostedt $_ = $line; 312d060d963SSteven Rostedt $line = ""; 313d060d963SSteven Rostedt 314d060d963SSteven Rostedt my $objs; 315dcc60243SSteven Rostedt 3160b58a99eSSteven Rostedt # Convert variables in a line (could define configs) 317364212fdSSteven Rostedt $_ = convert_vars($_, %make_vars); 318364212fdSSteven Rostedt 319dcc60243SSteven Rostedt # collect objects after obj-$(CONFIG_FOO_BAR) 320*98d7c754SJiri Slaby if (/obj-\$[({](CONFIG_[^})]*)[)}]\s*[+:]?=\s*(.*)/) { 321dcc60243SSteven Rostedt $var = $1; 322dcc60243SSteven Rostedt $objs = $2; 323364212fdSSteven Rostedt 324364212fdSSteven Rostedt # check if variables are set 325364212fdSSteven Rostedt } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) { 326364212fdSSteven Rostedt $make_vars{$1} = $2; 327dcc60243SSteven Rostedt } 328dcc60243SSteven Rostedt if (defined($objs)) { 329dcc60243SSteven Rostedt foreach my $obj (split /\s+/,$objs) { 330dcc60243SSteven Rostedt $obj =~ s/-/_/g; 331dcc60243SSteven Rostedt if ($obj =~ /(.*)\.o$/) { 3321d1d1feaSToralf Foerster # Objects may be enabled by more than one config. 333dcc60243SSteven Rostedt # Store configs in an array. 334dcc60243SSteven Rostedt my @arr; 335dcc60243SSteven Rostedt 336dcc60243SSteven Rostedt if (defined($objects{$1})) { 337dcc60243SSteven Rostedt @arr = @{$objects{$1}}; 338dcc60243SSteven Rostedt } 339dcc60243SSteven Rostedt 340dcc60243SSteven Rostedt $arr[$#arr+1] = $var; 341dcc60243SSteven Rostedt 342dcc60243SSteven Rostedt # The objects have a hash mapping to a reference 343dcc60243SSteven Rostedt # of an array of configs. 344dcc60243SSteven Rostedt $objects{$1} = \@arr; 345dcc60243SSteven Rostedt } 346dcc60243SSteven Rostedt } 347dcc60243SSteven Rostedt } 348dcc60243SSteven Rostedt } 349e0d28694SBill Pemberton close($infile); 350dcc60243SSteven Rostedt} 351dcc60243SSteven Rostedt 352dcc60243SSteven Rostedtmy %modules; 353e0d28694SBill Pembertonmy $linfile; 354dcc60243SSteven Rostedt 355615f0833SSteven Rostedtif (defined($lsmod_file)) { 356615f0833SSteven Rostedt if ( ! -f $lsmod_file) { 357f597a718SArnaud Lacombe if ( -f $ENV{'objtree'}."/".$lsmod_file) { 358f597a718SArnaud Lacombe $lsmod_file = $ENV{'objtree'}."/".$lsmod_file; 359f597a718SArnaud Lacombe } else { 360615f0833SSteven Rostedt die "$lsmod_file not found"; 361615f0833SSteven Rostedt } 362f597a718SArnaud Lacombe } 363e0d28694SBill Pemberton 364e0d28694SBill Pemberton my $otype = ( -x $lsmod_file) ? '-|' : '<'; 365e0d28694SBill Pemberton open($linfile, $otype, $lsmod_file); 366e0d28694SBill Pemberton 367615f0833SSteven Rostedt} else { 368615f0833SSteven Rostedt 369dcc60243SSteven Rostedt # see what modules are loaded on this system 37088f66ea9SSteven Rostedt my $lsmod; 37188f66ea9SSteven Rostedt 372cf5a189dShiromu foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) { 37388f66ea9SSteven Rostedt if ( -x "$dir/lsmod" ) { 37488f66ea9SSteven Rostedt $lsmod = "$dir/lsmod"; 37588f66ea9SSteven Rostedt last; 37688f66ea9SSteven Rostedt } 37788f66ea9SSteven Rostedt } 37888f66ea9SSteven Rostedt if (!defined($lsmod)) { 37988f66ea9SSteven Rostedt # try just the path 38088f66ea9SSteven Rostedt $lsmod = "lsmod"; 38188f66ea9SSteven Rostedt } 38288f66ea9SSteven Rostedt 383e0d28694SBill Pemberton open($linfile, '-|', $lsmod) || die "Can not call lsmod with $lsmod"; 384615f0833SSteven Rostedt} 385615f0833SSteven Rostedt 386e0d28694SBill Pembertonwhile (<$linfile>) { 387dcc60243SSteven Rostedt next if (/^Module/); # Skip the first line. 388dcc60243SSteven Rostedt if (/^(\S+)/) { 389dcc60243SSteven Rostedt $modules{$1} = 1; 390dcc60243SSteven Rostedt } 391dcc60243SSteven Rostedt} 392e0d28694SBill Pembertonclose ($linfile); 393dcc60243SSteven Rostedt 394dcc60243SSteven Rostedt# add to the configs hash all configs that are needed to enable 3950b58a99eSSteven Rostedt# a loaded module. This is a direct obj-${CONFIG_FOO} += bar.o 3960b58a99eSSteven Rostedt# where we know we need bar.o so we add FOO to the list. 397dcc60243SSteven Rostedtmy %configs; 398dcc60243SSteven Rostedtforeach my $module (keys(%modules)) { 399dcc60243SSteven Rostedt if (defined($objects{$module})) { 400e5199edbSToralf Foerster my @arr = @{$objects{$module}}; 401dcc60243SSteven Rostedt foreach my $conf (@arr) { 402dcc60243SSteven Rostedt $configs{$conf} = $module; 4034503379cSSteven Rostedt dprint "$conf added by direct ($module)\n"; 404bc20d12eSSteven Rostedt if ($debugprint) { 405bc20d12eSSteven Rostedt my $c=$conf; 406bc20d12eSSteven Rostedt $c =~ s/^CONFIG_//; 407bc20d12eSSteven Rostedt if (defined($depends{$c})) { 408bc20d12eSSteven Rostedt dprint " deps = $depends{$c}\n"; 409bc20d12eSSteven Rostedt } else { 410bc20d12eSSteven Rostedt dprint " no deps\n"; 411bc20d12eSSteven Rostedt } 412bc20d12eSSteven Rostedt } 413dcc60243SSteven Rostedt } 414dcc60243SSteven Rostedt } else { 415dcc60243SSteven Rostedt # Most likely, someone has a custom (binary?) module loaded. 416dcc60243SSteven Rostedt print STDERR "$module config not found!!\n"; 417dcc60243SSteven Rostedt } 418dcc60243SSteven Rostedt} 419dcc60243SSteven Rostedt 4204f4c51c9SSteven Rostedt# Read the current config, and see what is enabled. We want to 4214f4c51c9SSteven Rostedt# ignore configs that we would not enable anyway. 4224f4c51c9SSteven Rostedt 4234f4c51c9SSteven Rostedtmy %orig_configs; 424dcc60243SSteven Rostedtmy $valid = "A-Za-z_0-9"; 4254f4c51c9SSteven Rostedt 4264f4c51c9SSteven Rostedtforeach my $line (@config_file) { 4274f4c51c9SSteven Rostedt $_ = $line; 4284f4c51c9SSteven Rostedt 4294f4c51c9SSteven Rostedt if (/(CONFIG_[$valid]*)=(m|y)/) { 4304f4c51c9SSteven Rostedt $orig_configs{$1} = $2; 4314f4c51c9SSteven Rostedt } 4324f4c51c9SSteven Rostedt} 4334f4c51c9SSteven Rostedt 434dcc60243SSteven Rostedtmy $repeat = 1; 435dcc60243SSteven Rostedt 4364503379cSSteven Rostedtmy $depconfig; 4374503379cSSteven Rostedt 438dcc60243SSteven Rostedt# 439dcc60243SSteven Rostedt# Note, we do not care about operands (like: &&, ||, !) we want to add any 440dcc60243SSteven Rostedt# config that is in the depend list of another config. This script does 441dcc60243SSteven Rostedt# not enable configs that are not already enabled. If we come across a 442dcc60243SSteven Rostedt# config A that depends on !B, we can still add B to the list of depends 443dcc60243SSteven Rostedt# to keep on. If A was on in the original config, B would not have been 444dcc60243SSteven Rostedt# and B would not be turned on by this script. 445dcc60243SSteven Rostedt# 446d4bb58b5SSteven Rostedtsub parse_config_depends 447dcc60243SSteven Rostedt{ 448dcc60243SSteven Rostedt my ($p) = @_; 449dcc60243SSteven Rostedt 450dcc60243SSteven Rostedt while ($p =~ /[$valid]/) { 451dcc60243SSteven Rostedt 452dcc60243SSteven Rostedt if ($p =~ /^[^$valid]*([$valid]+)/) { 453dcc60243SSteven Rostedt my $conf = "CONFIG_" . $1; 454dcc60243SSteven Rostedt 455dcc60243SSteven Rostedt $p =~ s/^[^$valid]*[$valid]+//; 456dcc60243SSteven Rostedt 4574f4c51c9SSteven Rostedt # We only need to process if the depend config is a module 4585169192bSBenjamin Poirier if (!defined($orig_configs{$conf}) || $orig_configs{$conf} eq "y") { 4594f4c51c9SSteven Rostedt next; 4604f4c51c9SSteven Rostedt } 4614f4c51c9SSteven Rostedt 462dcc60243SSteven Rostedt if (!defined($configs{$conf})) { 463dcc60243SSteven Rostedt # We must make sure that this config has its 464dcc60243SSteven Rostedt # dependencies met. 465dcc60243SSteven Rostedt $repeat = 1; # do again 4664503379cSSteven Rostedt dprint "$conf selected by depend $depconfig\n"; 467dcc60243SSteven Rostedt $configs{$conf} = 1; 468dcc60243SSteven Rostedt } 469dcc60243SSteven Rostedt } else { 470dcc60243SSteven Rostedt die "this should never happen"; 471dcc60243SSteven Rostedt } 472dcc60243SSteven Rostedt } 473dcc60243SSteven Rostedt} 474dcc60243SSteven Rostedt 475d4bb58b5SSteven Rostedt# Select is treated a bit differently than depends. We call this 476d4bb58b5SSteven Rostedt# when a config has no prompt and requires another config to be 477d4bb58b5SSteven Rostedt# selected. We use to just select all configs that selected this 478d4bb58b5SSteven Rostedt# config, but found that that can balloon into enabling hundreds 479d4bb58b5SSteven Rostedt# of configs that we do not care about. 480d4bb58b5SSteven Rostedt# 481d4bb58b5SSteven Rostedt# The idea is we look at all the configs that select it. If one 482d4bb58b5SSteven Rostedt# is already in our list of configs to enable, then there's nothing 483d4bb58b5SSteven Rostedt# else to do. If there isn't, we pick the first config that was 48421f8b32fSBhaskar Chowdhury# enabled in the original config and use that. 485d4bb58b5SSteven Rostedtsub parse_config_selects 486d4bb58b5SSteven Rostedt{ 487d4bb58b5SSteven Rostedt my ($config, $p) = @_; 488d4bb58b5SSteven Rostedt 489d4bb58b5SSteven Rostedt my $next_config; 490d4bb58b5SSteven Rostedt 491d4bb58b5SSteven Rostedt while ($p =~ /[$valid]/) { 492d4bb58b5SSteven Rostedt 493d4bb58b5SSteven Rostedt if ($p =~ /^[^$valid]*([$valid]+)/) { 494d4bb58b5SSteven Rostedt my $conf = "CONFIG_" . $1; 495d4bb58b5SSteven Rostedt 496d4bb58b5SSteven Rostedt $p =~ s/^[^$valid]*[$valid]+//; 497d4bb58b5SSteven Rostedt 498d4bb58b5SSteven Rostedt # Make sure that this config exists in the current .config file 499d4bb58b5SSteven Rostedt if (!defined($orig_configs{$conf})) { 5004503379cSSteven Rostedt dprint "$conf not set for $config select\n"; 501d4bb58b5SSteven Rostedt next; 502d4bb58b5SSteven Rostedt } 503d4bb58b5SSteven Rostedt 504d4bb58b5SSteven Rostedt # Check if something other than a module selects this config 505d4bb58b5SSteven Rostedt if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") { 5064503379cSSteven Rostedt dprint "$conf (non module) selects config, we are good\n"; 507d4bb58b5SSteven Rostedt # we are good with this 508d4bb58b5SSteven Rostedt return; 509d4bb58b5SSteven Rostedt } 510d4bb58b5SSteven Rostedt if (defined($configs{$conf})) { 5114503379cSSteven Rostedt dprint "$conf selects $config so we are good\n"; 512d4bb58b5SSteven Rostedt # A set config selects this config, we are good 513d4bb58b5SSteven Rostedt return; 514d4bb58b5SSteven Rostedt } 515d4bb58b5SSteven Rostedt # Set this config to be selected 516d4bb58b5SSteven Rostedt if (!defined($next_config)) { 517d4bb58b5SSteven Rostedt $next_config = $conf; 518d4bb58b5SSteven Rostedt } 519d4bb58b5SSteven Rostedt } else { 520d4bb58b5SSteven Rostedt die "this should never happen"; 521d4bb58b5SSteven Rostedt } 522d4bb58b5SSteven Rostedt } 523d4bb58b5SSteven Rostedt 524d4bb58b5SSteven Rostedt # If no possible config selected this, then something happened. 525d4bb58b5SSteven Rostedt if (!defined($next_config)) { 526d4bb58b5SSteven Rostedt print STDERR "WARNING: $config is required, but nothing in the\n"; 527d4bb58b5SSteven Rostedt print STDERR " current config selects it.\n"; 528d4bb58b5SSteven Rostedt return; 529d4bb58b5SSteven Rostedt } 530d4bb58b5SSteven Rostedt 531d4bb58b5SSteven Rostedt # If we are here, then we found no config that is set and 532d4bb58b5SSteven Rostedt # selects this config. Repeat. 533d4bb58b5SSteven Rostedt $repeat = 1; 534d4bb58b5SSteven Rostedt # Make this config need to be selected 535d4bb58b5SSteven Rostedt $configs{$next_config} = 1; 5364503379cSSteven Rostedt dprint "$next_config selected by select $config\n"; 537d4bb58b5SSteven Rostedt} 538d4bb58b5SSteven Rostedt 539d4bb58b5SSteven Rostedtmy %process_selects; 540d4bb58b5SSteven Rostedt 541d4bb58b5SSteven Rostedt# loop through all configs, select their dependencies. 542d4bb58b5SSteven Rostedtsub loop_depend { 543d4bb58b5SSteven Rostedt $repeat = 1; 544d4bb58b5SSteven Rostedt 545dcc60243SSteven Rostedt while ($repeat) { 546dcc60243SSteven Rostedt $repeat = 0; 547dcc60243SSteven Rostedt 548d4bb58b5SSteven Rostedt forloop: 549dcc60243SSteven Rostedt foreach my $config (keys %configs) { 550d4bb58b5SSteven Rostedt 551d4bb58b5SSteven Rostedt # If this config is not a module, we do not need to process it 552d4bb58b5SSteven Rostedt if (defined($orig_configs{$config}) && $orig_configs{$config} ne "m") { 553d4bb58b5SSteven Rostedt next forloop; 554d4bb58b5SSteven Rostedt } 555d4bb58b5SSteven Rostedt 556dcc60243SSteven Rostedt $config =~ s/^CONFIG_//; 5574503379cSSteven Rostedt $depconfig = $config; 558dcc60243SSteven Rostedt 55974398d32SSteven Rostedt if (defined($depends{$config})) { 560dcc60243SSteven Rostedt # This config has dependencies. Make sure they are also included 561d4bb58b5SSteven Rostedt parse_config_depends $depends{$config}; 56274398d32SSteven Rostedt } 563dcc60243SSteven Rostedt 564d4bb58b5SSteven Rostedt # If the config has no prompt, then we need to check if a config 565d4bb58b5SSteven Rostedt # that is enabled selected it. Or if we need to enable one. 566d4bb58b5SSteven Rostedt if (!defined($prompts{$config}) && defined($selects{$config})) { 567d4bb58b5SSteven Rostedt $process_selects{$config} = 1; 568dcc60243SSteven Rostedt } 569d4bb58b5SSteven Rostedt } 570d4bb58b5SSteven Rostedt } 571d4bb58b5SSteven Rostedt} 572d4bb58b5SSteven Rostedt 573d4bb58b5SSteven Rostedtsub loop_select { 574d4bb58b5SSteven Rostedt 575d4bb58b5SSteven Rostedt foreach my $config (keys %process_selects) { 576d4bb58b5SSteven Rostedt $config =~ s/^CONFIG_//; 577dcc60243SSteven Rostedt 5784503379cSSteven Rostedt dprint "Process select $config\n"; 5794503379cSSteven Rostedt 580dcc60243SSteven Rostedt # config has no prompt and must be selected. 581d4bb58b5SSteven Rostedt parse_config_selects $config, $selects{$config}; 582dcc60243SSteven Rostedt } 583dcc60243SSteven Rostedt} 584dcc60243SSteven Rostedt 585d4bb58b5SSteven Rostedtwhile ($repeat) { 586d4bb58b5SSteven Rostedt # Get the first set of configs and their dependencies. 587d4bb58b5SSteven Rostedt loop_depend; 588d4bb58b5SSteven Rostedt 589d4bb58b5SSteven Rostedt $repeat = 0; 590d4bb58b5SSteven Rostedt 591d4bb58b5SSteven Rostedt # Now we need to see if we have to check selects; 592d4bb58b5SSteven Rostedt loop_select; 593d4bb58b5SSteven Rostedt} 594d4bb58b5SSteven Rostedt 595dcc60243SSteven Rostedtmy %setconfigs; 596a73fbfceSRandy Dunlapmy @preserved_kconfigs; 597a73fbfceSRandy Dunlapif (defined($ENV{'LMC_KEEP'})) { 598a73fbfceSRandy Dunlap @preserved_kconfigs = split(/:/,$ENV{LMC_KEEP}); 599a73fbfceSRandy Dunlap} 600c027b02dSChangbin Du 601c027b02dSChangbin Dusub in_preserved_kconfigs { 602c027b02dSChangbin Du my $kconfig = $config2kfile{$_[0]}; 603c027b02dSChangbin Du if (!defined($kconfig)) { 604c027b02dSChangbin Du return 0; 605c027b02dSChangbin Du } 606c027b02dSChangbin Du foreach my $excl (@preserved_kconfigs) { 607c027b02dSChangbin Du if($kconfig =~ /^$excl/) { 608c027b02dSChangbin Du return 1; 609c027b02dSChangbin Du } 610c027b02dSChangbin Du } 611c027b02dSChangbin Du return 0; 612c027b02dSChangbin Du} 613dcc60243SSteven Rostedt 614dcc60243SSteven Rostedt# Finally, read the .config file and turn off any module enabled that 615dcc60243SSteven Rostedt# we could not find a reason to keep enabled. 6164f4c51c9SSteven Rostedtforeach my $line (@config_file) { 6174f4c51c9SSteven Rostedt $_ = $line; 618744ffcbeSSteven Rostedt 619744ffcbeSSteven Rostedt if (/CONFIG_IKCONFIG/) { 620744ffcbeSSteven Rostedt if (/# CONFIG_IKCONFIG is not set/) { 621744ffcbeSSteven Rostedt # enable IKCONFIG at least as a module 622744ffcbeSSteven Rostedt print "CONFIG_IKCONFIG=m\n"; 623744ffcbeSSteven Rostedt # don't ask about PROC 624d08ca277SSteven Rostedt print "# CONFIG_IKCONFIG_PROC is not set\n"; 625744ffcbeSSteven Rostedt } else { 626744ffcbeSSteven Rostedt print; 627744ffcbeSSteven Rostedt } 628744ffcbeSSteven Rostedt next; 629744ffcbeSSteven Rostedt } 630744ffcbeSSteven Rostedt 63196bab35dSBenjamin Poirier if (/CONFIG_MODULE_SIG_KEY="(.+)"/) { 63296bab35dSBenjamin Poirier my $orig_cert = $1; 63396bab35dSBenjamin Poirier my $default_cert = "certs/signing_key.pem"; 63496bab35dSBenjamin Poirier 63596bab35dSBenjamin Poirier # Check that the logic in this script still matches the one in Kconfig 63696bab35dSBenjamin Poirier if (!defined($depends{"MODULE_SIG_KEY"}) || 63796bab35dSBenjamin Poirier $depends{"MODULE_SIG_KEY"} !~ /"\Q$default_cert\E"/) { 63896bab35dSBenjamin Poirier print STDERR "WARNING: MODULE_SIG_KEY assertion failure, ", 63996bab35dSBenjamin Poirier "update needed to ", __FILE__, " line ", __LINE__, "\n"; 64096bab35dSBenjamin Poirier print; 64196bab35dSBenjamin Poirier } elsif ($orig_cert ne $default_cert && ! -f $orig_cert) { 64296bab35dSBenjamin Poirier print STDERR "Module signature verification enabled but ", 64396bab35dSBenjamin Poirier "module signing key \"$orig_cert\" not found. Resetting ", 64496bab35dSBenjamin Poirier "signing key to default value.\n"; 64596bab35dSBenjamin Poirier print "CONFIG_MODULE_SIG_KEY=\"$default_cert\"\n"; 64696bab35dSBenjamin Poirier } else { 64796bab35dSBenjamin Poirier print; 64896bab35dSBenjamin Poirier } 64996bab35dSBenjamin Poirier next; 65096bab35dSBenjamin Poirier } 65196bab35dSBenjamin Poirier 65296bab35dSBenjamin Poirier if (/CONFIG_SYSTEM_TRUSTED_KEYS="(.+)"/) { 65396bab35dSBenjamin Poirier my $orig_keys = $1; 65496bab35dSBenjamin Poirier 65596bab35dSBenjamin Poirier if (! -f $orig_keys) { 65696bab35dSBenjamin Poirier print STDERR "System keyring enabled but keys \"$orig_keys\" ", 65796bab35dSBenjamin Poirier "not found. Resetting keys to default value.\n"; 65896bab35dSBenjamin Poirier print "CONFIG_SYSTEM_TRUSTED_KEYS=\"\"\n"; 65996bab35dSBenjamin Poirier } else { 66096bab35dSBenjamin Poirier print; 66196bab35dSBenjamin Poirier } 66296bab35dSBenjamin Poirier next; 66396bab35dSBenjamin Poirier } 66496bab35dSBenjamin Poirier 665ea2c1894SSteven Rostedt if (/^(CONFIG.*)=(m|y)/) { 666c027b02dSChangbin Du if (in_preserved_kconfigs($1)) { 667c027b02dSChangbin Du dprint "Preserve config $1"; 668c027b02dSChangbin Du print; 669c027b02dSChangbin Du next; 670c027b02dSChangbin Du } 671dcc60243SSteven Rostedt if (defined($configs{$1})) { 67222d550aeSArnaud Lacombe if ($localyesconfig) { 67322d550aeSArnaud Lacombe $setconfigs{$1} = 'y'; 6744eae518dSYuta Ando print "$1=y\n"; 6754eae518dSYuta Ando next; 67622d550aeSArnaud Lacombe } else { 677ea2c1894SSteven Rostedt $setconfigs{$1} = $2; 67822d550aeSArnaud Lacombe } 679ea2c1894SSteven Rostedt } elsif ($2 eq "m") { 680dcc60243SSteven Rostedt print "# $1 is not set\n"; 681d08ca277SSteven Rostedt next; 682dcc60243SSteven Rostedt } 683dcc60243SSteven Rostedt } 684d08ca277SSteven Rostedt print; 685dcc60243SSteven Rostedt} 686dcc60243SSteven Rostedt 687dcc60243SSteven Rostedt# Integrity check, make sure all modules that we want enabled do 688dcc60243SSteven Rostedt# indeed have their configs set. 689dcc60243SSteven Rostedtloop: 690dcc60243SSteven Rostedtforeach my $module (keys(%modules)) { 691dcc60243SSteven Rostedt if (defined($objects{$module})) { 692dcc60243SSteven Rostedt my @arr = @{$objects{$module}}; 693dcc60243SSteven Rostedt foreach my $conf (@arr) { 694dcc60243SSteven Rostedt if (defined($setconfigs{$conf})) { 695dcc60243SSteven Rostedt next loop; 696dcc60243SSteven Rostedt } 697dcc60243SSteven Rostedt } 698dcc60243SSteven Rostedt print STDERR "module $module did not have configs"; 699dcc60243SSteven Rostedt foreach my $conf (@arr) { 700dcc60243SSteven Rostedt print STDERR " " , $conf; 701dcc60243SSteven Rostedt } 702dcc60243SSteven Rostedt print STDERR "\n"; 703dcc60243SSteven Rostedt } 704dcc60243SSteven Rostedt} 705d1b1f1e6SSteven Rostedt (VMware) 706d1b1f1e6SSteven Rostedt (VMware)# vim: softtabstop=4 707