xref: /linux/scripts/kconfig/streamline_config.pl (revision c027b02d89fd42ecee911c39e9098b9609a5ca0b)
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.
24dcc60243SSteven Rostedt#  3. Copy the configuraton 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;
146*c027b02dSChangbin 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
173e0d28694SBill Pemberton    open(my $kinfile, '<', $source) || die "Can't open $kconfig";
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;
205*c027b02dSChangbin 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)
320dcc60243SSteven Rostedt	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
484d4bb58b5SSteven Rostedt# enabled in the orignal 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;
596*c027b02dSChangbin Dumy @preserved_kconfigs = split(/:/,$ENV{LMC_KEEP});
597*c027b02dSChangbin Du
598*c027b02dSChangbin Dusub in_preserved_kconfigs {
599*c027b02dSChangbin Du    my $kconfig = $config2kfile{$_[0]};
600*c027b02dSChangbin Du    if (!defined($kconfig)) {
601*c027b02dSChangbin Du        return 0;
602*c027b02dSChangbin Du    }
603*c027b02dSChangbin Du    foreach my $excl (@preserved_kconfigs) {
604*c027b02dSChangbin Du        if($kconfig =~ /^$excl/) {
605*c027b02dSChangbin Du            return 1;
606*c027b02dSChangbin Du        }
607*c027b02dSChangbin Du    }
608*c027b02dSChangbin Du    return 0;
609*c027b02dSChangbin Du}
610dcc60243SSteven Rostedt
611dcc60243SSteven Rostedt# Finally, read the .config file and turn off any module enabled that
612dcc60243SSteven Rostedt# we could not find a reason to keep enabled.
6134f4c51c9SSteven Rostedtforeach my $line (@config_file) {
6144f4c51c9SSteven Rostedt    $_ = $line;
615744ffcbeSSteven Rostedt
616744ffcbeSSteven Rostedt    if (/CONFIG_IKCONFIG/) {
617744ffcbeSSteven Rostedt	if (/# CONFIG_IKCONFIG is not set/) {
618744ffcbeSSteven Rostedt	    # enable IKCONFIG at least as a module
619744ffcbeSSteven Rostedt	    print "CONFIG_IKCONFIG=m\n";
620744ffcbeSSteven Rostedt	    # don't ask about PROC
621d08ca277SSteven Rostedt	    print "# CONFIG_IKCONFIG_PROC is not set\n";
622744ffcbeSSteven Rostedt	} else {
623744ffcbeSSteven Rostedt	    print;
624744ffcbeSSteven Rostedt	}
625744ffcbeSSteven Rostedt	next;
626744ffcbeSSteven Rostedt    }
627744ffcbeSSteven Rostedt
62896bab35dSBenjamin Poirier    if (/CONFIG_MODULE_SIG_KEY="(.+)"/) {
62996bab35dSBenjamin Poirier        my $orig_cert = $1;
63096bab35dSBenjamin Poirier        my $default_cert = "certs/signing_key.pem";
63196bab35dSBenjamin Poirier
63296bab35dSBenjamin Poirier        # Check that the logic in this script still matches the one in Kconfig
63396bab35dSBenjamin Poirier        if (!defined($depends{"MODULE_SIG_KEY"}) ||
63496bab35dSBenjamin Poirier            $depends{"MODULE_SIG_KEY"} !~ /"\Q$default_cert\E"/) {
63596bab35dSBenjamin Poirier            print STDERR "WARNING: MODULE_SIG_KEY assertion failure, ",
63696bab35dSBenjamin Poirier                "update needed to ", __FILE__, " line ", __LINE__, "\n";
63796bab35dSBenjamin Poirier            print;
63896bab35dSBenjamin Poirier        } elsif ($orig_cert ne $default_cert && ! -f $orig_cert) {
63996bab35dSBenjamin Poirier            print STDERR "Module signature verification enabled but ",
64096bab35dSBenjamin Poirier                "module signing key \"$orig_cert\" not found. Resetting ",
64196bab35dSBenjamin Poirier                "signing key to default value.\n";
64296bab35dSBenjamin Poirier            print "CONFIG_MODULE_SIG_KEY=\"$default_cert\"\n";
64396bab35dSBenjamin Poirier        } else {
64496bab35dSBenjamin Poirier            print;
64596bab35dSBenjamin Poirier        }
64696bab35dSBenjamin Poirier        next;
64796bab35dSBenjamin Poirier    }
64896bab35dSBenjamin Poirier
64996bab35dSBenjamin Poirier    if (/CONFIG_SYSTEM_TRUSTED_KEYS="(.+)"/) {
65096bab35dSBenjamin Poirier        my $orig_keys = $1;
65196bab35dSBenjamin Poirier
65296bab35dSBenjamin Poirier        if (! -f $orig_keys) {
65396bab35dSBenjamin Poirier            print STDERR "System keyring enabled but keys \"$orig_keys\" ",
65496bab35dSBenjamin Poirier                "not found. Resetting keys to default value.\n";
65596bab35dSBenjamin Poirier            print "CONFIG_SYSTEM_TRUSTED_KEYS=\"\"\n";
65696bab35dSBenjamin Poirier        } else {
65796bab35dSBenjamin Poirier            print;
65896bab35dSBenjamin Poirier        }
65996bab35dSBenjamin Poirier        next;
66096bab35dSBenjamin Poirier    }
66196bab35dSBenjamin Poirier
662ea2c1894SSteven Rostedt    if (/^(CONFIG.*)=(m|y)/) {
663*c027b02dSChangbin Du        if (in_preserved_kconfigs($1)) {
664*c027b02dSChangbin Du            dprint "Preserve config $1";
665*c027b02dSChangbin Du            print;
666*c027b02dSChangbin Du            next;
667*c027b02dSChangbin Du        }
668dcc60243SSteven Rostedt	if (defined($configs{$1})) {
66922d550aeSArnaud Lacombe	    if ($localyesconfig) {
67022d550aeSArnaud Lacombe	        $setconfigs{$1} = 'y';
6714eae518dSYuta Ando		print "$1=y\n";
6724eae518dSYuta Ando		next;
67322d550aeSArnaud Lacombe	    } else {
674ea2c1894SSteven Rostedt	        $setconfigs{$1} = $2;
67522d550aeSArnaud Lacombe	    }
676ea2c1894SSteven Rostedt	} elsif ($2 eq "m") {
677dcc60243SSteven Rostedt	    print "# $1 is not set\n";
678d08ca277SSteven Rostedt	    next;
679dcc60243SSteven Rostedt	}
680dcc60243SSteven Rostedt    }
681d08ca277SSteven Rostedt    print;
682dcc60243SSteven Rostedt}
683dcc60243SSteven Rostedt
684dcc60243SSteven Rostedt# Integrity check, make sure all modules that we want enabled do
685dcc60243SSteven Rostedt# indeed have their configs set.
686dcc60243SSteven Rostedtloop:
687dcc60243SSteven Rostedtforeach my $module (keys(%modules)) {
688dcc60243SSteven Rostedt    if (defined($objects{$module})) {
689dcc60243SSteven Rostedt	my @arr = @{$objects{$module}};
690dcc60243SSteven Rostedt	foreach my $conf (@arr) {
691dcc60243SSteven Rostedt	    if (defined($setconfigs{$conf})) {
692dcc60243SSteven Rostedt		next loop;
693dcc60243SSteven Rostedt	    }
694dcc60243SSteven Rostedt	}
695dcc60243SSteven Rostedt	print STDERR "module $module did not have configs";
696dcc60243SSteven Rostedt	foreach my $conf (@arr) {
697dcc60243SSteven Rostedt	    print STDERR " " , $conf;
698dcc60243SSteven Rostedt	}
699dcc60243SSteven Rostedt	print STDERR "\n";
700dcc60243SSteven Rostedt    }
701dcc60243SSteven Rostedt}
702