xref: /rk3399_rockchip-uboot/scripts/kconfig/streamline_config.pl (revision bf7ab1e70fd7621fea5dea07b6975c576119b86e)
10a9064fbSMasahiro Yamada#!/usr/bin/perl -w
20a9064fbSMasahiro Yamada#
30a9064fbSMasahiro Yamada# Copyright 2005-2009 - Steven Rostedt
40a9064fbSMasahiro Yamada# Licensed under the terms of the GNU GPL License version 2
50a9064fbSMasahiro Yamada#
60a9064fbSMasahiro Yamada#  It's simple enough to figure out how this works.
70a9064fbSMasahiro Yamada#  If not, then you can ask me at stripconfig@goodmis.org
80a9064fbSMasahiro Yamada#
90a9064fbSMasahiro Yamada# What it does?
100a9064fbSMasahiro Yamada#
110a9064fbSMasahiro Yamada#   If you have installed a Linux kernel from a distribution
120a9064fbSMasahiro Yamada#   that turns on way too many modules than you need, and
130a9064fbSMasahiro Yamada#   you only want the modules you use, then this program
140a9064fbSMasahiro Yamada#   is perfect for you.
150a9064fbSMasahiro Yamada#
160a9064fbSMasahiro Yamada#   It gives you the ability to turn off all the modules that are
170a9064fbSMasahiro Yamada#   not loaded on your system.
180a9064fbSMasahiro Yamada#
190a9064fbSMasahiro Yamada# Howto:
200a9064fbSMasahiro Yamada#
210a9064fbSMasahiro Yamada#  1. Boot up the kernel that you want to stream line the config on.
220a9064fbSMasahiro Yamada#  2. Change directory to the directory holding the source of the
230a9064fbSMasahiro Yamada#       kernel that you just booted.
240a9064fbSMasahiro Yamada#  3. Copy the configuraton file to this directory as .config
250a9064fbSMasahiro Yamada#  4. Have all your devices that you need modules for connected and
260a9064fbSMasahiro Yamada#      operational (make sure that their corresponding modules are loaded)
270a9064fbSMasahiro Yamada#  5. Run this script redirecting the output to some other file
280a9064fbSMasahiro Yamada#       like config_strip.
290a9064fbSMasahiro Yamada#  6. Back up your old config (if you want too).
300a9064fbSMasahiro Yamada#  7. copy the config_strip file to .config
310a9064fbSMasahiro Yamada#  8. Run "make oldconfig"
320a9064fbSMasahiro Yamada#
330a9064fbSMasahiro Yamada#  Now your kernel is ready to be built with only the modules that
340a9064fbSMasahiro Yamada#  are loaded.
350a9064fbSMasahiro Yamada#
360a9064fbSMasahiro Yamada# Here's what I did with my Debian distribution.
370a9064fbSMasahiro Yamada#
380a9064fbSMasahiro Yamada#    cd /usr/src/linux-2.6.10
390a9064fbSMasahiro Yamada#    cp /boot/config-2.6.10-1-686-smp .config
400a9064fbSMasahiro Yamada#    ~/bin/streamline_config > config_strip
410a9064fbSMasahiro Yamada#    mv .config config_sav
420a9064fbSMasahiro Yamada#    mv config_strip .config
430a9064fbSMasahiro Yamada#    make oldconfig
440a9064fbSMasahiro Yamada#
450a9064fbSMasahiro Yamadause strict;
460a9064fbSMasahiro Yamadause Getopt::Long;
470a9064fbSMasahiro Yamada
480a9064fbSMasahiro Yamada# set the environment variable LOCALMODCONFIG_DEBUG to get
490a9064fbSMasahiro Yamada# debug output.
500a9064fbSMasahiro Yamadamy $debugprint = 0;
510a9064fbSMasahiro Yamada$debugprint = 1 if (defined($ENV{LOCALMODCONFIG_DEBUG}));
520a9064fbSMasahiro Yamada
530a9064fbSMasahiro Yamadasub dprint {
540a9064fbSMasahiro Yamada    return if (!$debugprint);
550a9064fbSMasahiro Yamada    print STDERR @_;
560a9064fbSMasahiro Yamada}
570a9064fbSMasahiro Yamada
580a9064fbSMasahiro Yamadamy $config = ".config";
590a9064fbSMasahiro Yamada
600a9064fbSMasahiro Yamadamy $uname = `uname -r`;
610a9064fbSMasahiro Yamadachomp $uname;
620a9064fbSMasahiro Yamada
630a9064fbSMasahiro Yamadamy @searchconfigs = (
640a9064fbSMasahiro Yamada	{
650a9064fbSMasahiro Yamada	    "file" => ".config",
660a9064fbSMasahiro Yamada	    "exec" => "cat",
670a9064fbSMasahiro Yamada	},
680a9064fbSMasahiro Yamada	{
690a9064fbSMasahiro Yamada	    "file" => "/proc/config.gz",
700a9064fbSMasahiro Yamada	    "exec" => "zcat",
710a9064fbSMasahiro Yamada	},
720a9064fbSMasahiro Yamada	{
730a9064fbSMasahiro Yamada	    "file" => "/boot/config-$uname",
740a9064fbSMasahiro Yamada	    "exec" => "cat",
750a9064fbSMasahiro Yamada	},
760a9064fbSMasahiro Yamada	{
770a9064fbSMasahiro Yamada	    "file" => "/boot/vmlinuz-$uname",
780a9064fbSMasahiro Yamada	    "exec" => "scripts/extract-ikconfig",
790a9064fbSMasahiro Yamada	    "test" => "scripts/extract-ikconfig",
800a9064fbSMasahiro Yamada	},
810a9064fbSMasahiro Yamada	{
820a9064fbSMasahiro Yamada	    "file" => "vmlinux",
830a9064fbSMasahiro Yamada	    "exec" => "scripts/extract-ikconfig",
840a9064fbSMasahiro Yamada	    "test" => "scripts/extract-ikconfig",
850a9064fbSMasahiro Yamada	},
860a9064fbSMasahiro Yamada	{
870a9064fbSMasahiro Yamada	    "file" => "/lib/modules/$uname/kernel/kernel/configs.ko",
880a9064fbSMasahiro Yamada	    "exec" => "scripts/extract-ikconfig",
890a9064fbSMasahiro Yamada	    "test" => "scripts/extract-ikconfig",
900a9064fbSMasahiro Yamada	},
910a9064fbSMasahiro Yamada	{
920a9064fbSMasahiro Yamada	    "file" => "kernel/configs.ko",
930a9064fbSMasahiro Yamada	    "exec" => "scripts/extract-ikconfig",
940a9064fbSMasahiro Yamada	    "test" => "scripts/extract-ikconfig",
950a9064fbSMasahiro Yamada	},
960a9064fbSMasahiro Yamada	{
970a9064fbSMasahiro Yamada	    "file" => "kernel/configs.o",
980a9064fbSMasahiro Yamada	    "exec" => "scripts/extract-ikconfig",
990a9064fbSMasahiro Yamada	    "test" => "scripts/extract-ikconfig",
1000a9064fbSMasahiro Yamada	},
1010a9064fbSMasahiro Yamada);
1020a9064fbSMasahiro Yamada
1030a9064fbSMasahiro Yamadasub read_config {
1040a9064fbSMasahiro Yamada    foreach my $conf (@searchconfigs) {
1050a9064fbSMasahiro Yamada	my $file = $conf->{"file"};
1060a9064fbSMasahiro Yamada
1070a9064fbSMasahiro Yamada	next if ( ! -f "$file");
1080a9064fbSMasahiro Yamada
1090a9064fbSMasahiro Yamada	if (defined($conf->{"test"})) {
1100a9064fbSMasahiro Yamada	    `$conf->{"test"} $conf->{"file"} 2>/dev/null`;
1110a9064fbSMasahiro Yamada	    next if ($?);
1120a9064fbSMasahiro Yamada	}
1130a9064fbSMasahiro Yamada
1140a9064fbSMasahiro Yamada	my $exec = $conf->{"exec"};
1150a9064fbSMasahiro Yamada
1160a9064fbSMasahiro Yamada	print STDERR "using config: '$file'\n";
1170a9064fbSMasahiro Yamada
1180a9064fbSMasahiro Yamada	open(my $infile, '-|', "$exec $file") || die "Failed to run $exec $file";
1190a9064fbSMasahiro Yamada	my @x = <$infile>;
1200a9064fbSMasahiro Yamada	close $infile;
1210a9064fbSMasahiro Yamada	return @x;
1220a9064fbSMasahiro Yamada    }
1230a9064fbSMasahiro Yamada    die "No config file found";
1240a9064fbSMasahiro Yamada}
1250a9064fbSMasahiro Yamada
1260a9064fbSMasahiro Yamadamy @config_file = read_config;
1270a9064fbSMasahiro Yamada
1280a9064fbSMasahiro Yamada# Parse options
1290a9064fbSMasahiro Yamadamy $localmodconfig = 0;
1300a9064fbSMasahiro Yamadamy $localyesconfig = 0;
1310a9064fbSMasahiro Yamada
1320a9064fbSMasahiro YamadaGetOptions("localmodconfig" => \$localmodconfig,
1330a9064fbSMasahiro Yamada	   "localyesconfig" => \$localyesconfig);
1340a9064fbSMasahiro Yamada
1350a9064fbSMasahiro Yamada# Get the build source and top level Kconfig file (passed in)
1360a9064fbSMasahiro Yamadamy $ksource = ($ARGV[0] ? $ARGV[0] : '.');
1370a9064fbSMasahiro Yamadamy $kconfig = $ARGV[1];
1380a9064fbSMasahiro Yamadamy $lsmod_file = $ENV{'LSMOD'};
1390a9064fbSMasahiro Yamada
140*bf7ab1e7SMasahiro Yamadamy @makefiles = `find $ksource -name Makefile -or -name Kbuild 2>/dev/null`;
1410a9064fbSMasahiro Yamadachomp @makefiles;
1420a9064fbSMasahiro Yamada
1430a9064fbSMasahiro Yamadamy %depends;
1440a9064fbSMasahiro Yamadamy %selects;
1450a9064fbSMasahiro Yamadamy %prompts;
1460a9064fbSMasahiro Yamadamy %objects;
1470a9064fbSMasahiro Yamadamy $var;
1480a9064fbSMasahiro Yamadamy $iflevel = 0;
1490a9064fbSMasahiro Yamadamy @ifdeps;
1500a9064fbSMasahiro Yamada
1510a9064fbSMasahiro Yamada# prevent recursion
1520a9064fbSMasahiro Yamadamy %read_kconfigs;
1530a9064fbSMasahiro Yamada
1540a9064fbSMasahiro Yamadasub read_kconfig {
1550a9064fbSMasahiro Yamada    my ($kconfig) = @_;
1560a9064fbSMasahiro Yamada
1570a9064fbSMasahiro Yamada    my $state = "NONE";
1580a9064fbSMasahiro Yamada    my $config;
1590a9064fbSMasahiro Yamada
1600a9064fbSMasahiro Yamada    my $cont = 0;
1610a9064fbSMasahiro Yamada    my $line;
1620a9064fbSMasahiro Yamada
1630a9064fbSMasahiro Yamada    my $source = "$ksource/$kconfig";
1640a9064fbSMasahiro Yamada    my $last_source = "";
1650a9064fbSMasahiro Yamada
1660a9064fbSMasahiro Yamada    # Check for any environment variables used
1670a9064fbSMasahiro Yamada    while ($source =~ /\$(\w+)/ && $last_source ne $source) {
1680a9064fbSMasahiro Yamada	my $env = $1;
1690a9064fbSMasahiro Yamada	$last_source = $source;
1700a9064fbSMasahiro Yamada	$source =~ s/\$$env/$ENV{$env}/;
1710a9064fbSMasahiro Yamada    }
1720a9064fbSMasahiro Yamada
1730a9064fbSMasahiro Yamada    open(my $kinfile, '<', $source) || die "Can't open $kconfig";
1740a9064fbSMasahiro Yamada    while (<$kinfile>) {
1750a9064fbSMasahiro Yamada	chomp;
1760a9064fbSMasahiro Yamada
1770a9064fbSMasahiro Yamada	# Make sure that lines ending with \ continue
1780a9064fbSMasahiro Yamada	if ($cont) {
1790a9064fbSMasahiro Yamada	    $_ = $line . " " . $_;
1800a9064fbSMasahiro Yamada	}
1810a9064fbSMasahiro Yamada
1820a9064fbSMasahiro Yamada	if (s/\\$//) {
1830a9064fbSMasahiro Yamada	    $cont = 1;
1840a9064fbSMasahiro Yamada	    $line = $_;
1850a9064fbSMasahiro Yamada	    next;
1860a9064fbSMasahiro Yamada	}
1870a9064fbSMasahiro Yamada
1880a9064fbSMasahiro Yamada	$cont = 0;
1890a9064fbSMasahiro Yamada
1900a9064fbSMasahiro Yamada	# collect any Kconfig sources
191*bf7ab1e7SMasahiro Yamada	if (/^source\s+"?([^"]+)/) {
1920a9064fbSMasahiro Yamada	    my $kconfig = $1;
1930a9064fbSMasahiro Yamada	    # prevent reading twice.
1940a9064fbSMasahiro Yamada	    if (!defined($read_kconfigs{$kconfig})) {
1950a9064fbSMasahiro Yamada		$read_kconfigs{$kconfig} = 1;
1960a9064fbSMasahiro Yamada		read_kconfig($kconfig);
1970a9064fbSMasahiro Yamada	    }
1980a9064fbSMasahiro Yamada	    next;
1990a9064fbSMasahiro Yamada	}
2000a9064fbSMasahiro Yamada
2010a9064fbSMasahiro Yamada	# configs found
2020a9064fbSMasahiro Yamada	if (/^\s*(menu)?config\s+(\S+)\s*$/) {
2030a9064fbSMasahiro Yamada	    $state = "NEW";
2040a9064fbSMasahiro Yamada	    $config = $2;
2050a9064fbSMasahiro Yamada
2060a9064fbSMasahiro Yamada	    # Add depends for 'if' nesting
2070a9064fbSMasahiro Yamada	    for (my $i = 0; $i < $iflevel; $i++) {
2080a9064fbSMasahiro Yamada		if ($i) {
2090a9064fbSMasahiro Yamada		    $depends{$config} .= " " . $ifdeps[$i];
2100a9064fbSMasahiro Yamada		} else {
2110a9064fbSMasahiro Yamada		    $depends{$config} = $ifdeps[$i];
2120a9064fbSMasahiro Yamada		}
2130a9064fbSMasahiro Yamada		$state = "DEP";
2140a9064fbSMasahiro Yamada	    }
2150a9064fbSMasahiro Yamada
2160a9064fbSMasahiro Yamada	# collect the depends for the config
2170a9064fbSMasahiro Yamada	} elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) {
2180a9064fbSMasahiro Yamada	    $state = "DEP";
2190a9064fbSMasahiro Yamada	    $depends{$config} = $1;
2200a9064fbSMasahiro Yamada	} elsif ($state eq "DEP" && /^\s*depends\s+on\s+(.*)$/) {
2210a9064fbSMasahiro Yamada	    $depends{$config} .= " " . $1;
2220a9064fbSMasahiro Yamada	} elsif ($state eq "DEP" && /^\s*def(_(bool|tristate)|ault)\s+(\S.*)$/) {
2230a9064fbSMasahiro Yamada	    my $dep = $3;
2240a9064fbSMasahiro Yamada	    if ($dep !~ /^\s*(y|m|n)\s*$/) {
2250a9064fbSMasahiro Yamada		$dep =~ s/.*\sif\s+//;
2260a9064fbSMasahiro Yamada		$depends{$config} .= " " . $dep;
2270a9064fbSMasahiro Yamada		dprint "Added default depends $dep to $config\n";
2280a9064fbSMasahiro Yamada	    }
2290a9064fbSMasahiro Yamada
2300a9064fbSMasahiro Yamada	# Get the configs that select this config
2310a9064fbSMasahiro Yamada	} elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) {
2320a9064fbSMasahiro Yamada	    my $conf = $1;
2330a9064fbSMasahiro Yamada	    if (defined($selects{$conf})) {
2340a9064fbSMasahiro Yamada		$selects{$conf} .= " " . $config;
2350a9064fbSMasahiro Yamada	    } else {
2360a9064fbSMasahiro Yamada		$selects{$conf} = $config;
2370a9064fbSMasahiro Yamada	    }
2380a9064fbSMasahiro Yamada
2390a9064fbSMasahiro Yamada	# configs without prompts must be selected
240*bf7ab1e7SMasahiro Yamada	} elsif ($state ne "NONE" && /^\s*(tristate\s+\S|prompt\b)/) {
2410a9064fbSMasahiro Yamada	    # note if the config has a prompt
2420a9064fbSMasahiro Yamada	    $prompts{$config} = 1;
2430a9064fbSMasahiro Yamada
2440a9064fbSMasahiro Yamada	# Check for if statements
2450a9064fbSMasahiro Yamada	} elsif (/^if\s+(.*\S)\s*$/) {
2460a9064fbSMasahiro Yamada	    my $deps = $1;
2470a9064fbSMasahiro Yamada	    # remove beginning and ending non text
2480a9064fbSMasahiro Yamada	    $deps =~ s/^[^a-zA-Z0-9_]*//;
2490a9064fbSMasahiro Yamada	    $deps =~ s/[^a-zA-Z0-9_]*$//;
2500a9064fbSMasahiro Yamada
2510a9064fbSMasahiro Yamada	    my @deps = split /[^a-zA-Z0-9_]+/, $deps;
2520a9064fbSMasahiro Yamada
2530a9064fbSMasahiro Yamada	    $ifdeps[$iflevel++] = join ':', @deps;
2540a9064fbSMasahiro Yamada
2550a9064fbSMasahiro Yamada	} elsif (/^endif/) {
2560a9064fbSMasahiro Yamada
2570a9064fbSMasahiro Yamada	    $iflevel-- if ($iflevel);
2580a9064fbSMasahiro Yamada
259*bf7ab1e7SMasahiro Yamada	# stop on "help" and keywords that end a menu entry
260*bf7ab1e7SMasahiro Yamada	} elsif (/^\s*(---)?help(---)?\s*$/ || /^(comment|choice|menu)\b/) {
2610a9064fbSMasahiro Yamada	    $state = "NONE";
2620a9064fbSMasahiro Yamada	}
2630a9064fbSMasahiro Yamada    }
2640a9064fbSMasahiro Yamada    close($kinfile);
2650a9064fbSMasahiro Yamada}
2660a9064fbSMasahiro Yamada
2670a9064fbSMasahiro Yamadaif ($kconfig) {
2680a9064fbSMasahiro Yamada    read_kconfig($kconfig);
2690a9064fbSMasahiro Yamada}
2700a9064fbSMasahiro Yamada
2710a9064fbSMasahiro Yamada# Makefiles can use variables to define their dependencies
2720a9064fbSMasahiro Yamadasub convert_vars {
2730a9064fbSMasahiro Yamada    my ($line, %vars) = @_;
2740a9064fbSMasahiro Yamada
2750a9064fbSMasahiro Yamada    my $process = "";
2760a9064fbSMasahiro Yamada
2770a9064fbSMasahiro Yamada    while ($line =~ s/^(.*?)(\$\((.*?)\))//) {
2780a9064fbSMasahiro Yamada	my $start = $1;
2790a9064fbSMasahiro Yamada	my $variable = $2;
2800a9064fbSMasahiro Yamada	my $var = $3;
2810a9064fbSMasahiro Yamada
2820a9064fbSMasahiro Yamada	if (defined($vars{$var})) {
2830a9064fbSMasahiro Yamada	    $process .= $start . $vars{$var};
2840a9064fbSMasahiro Yamada	} else {
2850a9064fbSMasahiro Yamada	    $process .= $start . $variable;
2860a9064fbSMasahiro Yamada	}
2870a9064fbSMasahiro Yamada    }
2880a9064fbSMasahiro Yamada
2890a9064fbSMasahiro Yamada    $process .= $line;
2900a9064fbSMasahiro Yamada
2910a9064fbSMasahiro Yamada    return $process;
2920a9064fbSMasahiro Yamada}
2930a9064fbSMasahiro Yamada
2940a9064fbSMasahiro Yamada# Read all Makefiles to map the configs to the objects
2950a9064fbSMasahiro Yamadaforeach my $makefile (@makefiles) {
2960a9064fbSMasahiro Yamada
2970a9064fbSMasahiro Yamada    my $line = "";
2980a9064fbSMasahiro Yamada    my %make_vars;
2990a9064fbSMasahiro Yamada
3000a9064fbSMasahiro Yamada    open(my $infile, '<', $makefile) || die "Can't open $makefile";
3010a9064fbSMasahiro Yamada    while (<$infile>) {
3020a9064fbSMasahiro Yamada	# if this line ends with a backslash, continue
3030a9064fbSMasahiro Yamada	chomp;
3040a9064fbSMasahiro Yamada	if (/^(.*)\\$/) {
3050a9064fbSMasahiro Yamada	    $line .= $1;
3060a9064fbSMasahiro Yamada	    next;
3070a9064fbSMasahiro Yamada	}
3080a9064fbSMasahiro Yamada
3090a9064fbSMasahiro Yamada	$line .= $_;
3100a9064fbSMasahiro Yamada	$_ = $line;
3110a9064fbSMasahiro Yamada	$line = "";
3120a9064fbSMasahiro Yamada
3130a9064fbSMasahiro Yamada	my $objs;
3140a9064fbSMasahiro Yamada
3150a9064fbSMasahiro Yamada	# Convert variables in a line (could define configs)
3160a9064fbSMasahiro Yamada	$_ = convert_vars($_, %make_vars);
3170a9064fbSMasahiro Yamada
3180a9064fbSMasahiro Yamada	# collect objects after obj-$(CONFIG_FOO_BAR)
3190a9064fbSMasahiro Yamada	if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) {
3200a9064fbSMasahiro Yamada	    $var = $1;
3210a9064fbSMasahiro Yamada	    $objs = $2;
3220a9064fbSMasahiro Yamada
3230a9064fbSMasahiro Yamada	# check if variables are set
3240a9064fbSMasahiro Yamada	} elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) {
3250a9064fbSMasahiro Yamada	    $make_vars{$1} = $2;
3260a9064fbSMasahiro Yamada	}
3270a9064fbSMasahiro Yamada	if (defined($objs)) {
3280a9064fbSMasahiro Yamada	    foreach my $obj (split /\s+/,$objs) {
3290a9064fbSMasahiro Yamada		$obj =~ s/-/_/g;
3300a9064fbSMasahiro Yamada		if ($obj =~ /(.*)\.o$/) {
3310a9064fbSMasahiro Yamada		    # Objects may be enabled by more than one config.
3320a9064fbSMasahiro Yamada		    # Store configs in an array.
3330a9064fbSMasahiro Yamada		    my @arr;
3340a9064fbSMasahiro Yamada
3350a9064fbSMasahiro Yamada		    if (defined($objects{$1})) {
3360a9064fbSMasahiro Yamada			@arr = @{$objects{$1}};
3370a9064fbSMasahiro Yamada		    }
3380a9064fbSMasahiro Yamada
3390a9064fbSMasahiro Yamada		    $arr[$#arr+1] = $var;
3400a9064fbSMasahiro Yamada
3410a9064fbSMasahiro Yamada		    # The objects have a hash mapping to a reference
3420a9064fbSMasahiro Yamada		    # of an array of configs.
3430a9064fbSMasahiro Yamada		    $objects{$1} = \@arr;
3440a9064fbSMasahiro Yamada		}
3450a9064fbSMasahiro Yamada	    }
3460a9064fbSMasahiro Yamada	}
3470a9064fbSMasahiro Yamada    }
3480a9064fbSMasahiro Yamada    close($infile);
3490a9064fbSMasahiro Yamada}
3500a9064fbSMasahiro Yamada
3510a9064fbSMasahiro Yamadamy %modules;
3520a9064fbSMasahiro Yamadamy $linfile;
3530a9064fbSMasahiro Yamada
3540a9064fbSMasahiro Yamadaif (defined($lsmod_file)) {
3550a9064fbSMasahiro Yamada    if ( ! -f $lsmod_file) {
3560a9064fbSMasahiro Yamada	if ( -f $ENV{'objtree'}."/".$lsmod_file) {
3570a9064fbSMasahiro Yamada	    $lsmod_file = $ENV{'objtree'}."/".$lsmod_file;
3580a9064fbSMasahiro Yamada	} else {
3590a9064fbSMasahiro Yamada		die "$lsmod_file not found";
3600a9064fbSMasahiro Yamada	}
3610a9064fbSMasahiro Yamada    }
3620a9064fbSMasahiro Yamada
3630a9064fbSMasahiro Yamada    my $otype = ( -x $lsmod_file) ? '-|' : '<';
3640a9064fbSMasahiro Yamada    open($linfile, $otype, $lsmod_file);
3650a9064fbSMasahiro Yamada
3660a9064fbSMasahiro Yamada} else {
3670a9064fbSMasahiro Yamada
3680a9064fbSMasahiro Yamada    # see what modules are loaded on this system
3690a9064fbSMasahiro Yamada    my $lsmod;
3700a9064fbSMasahiro Yamada
3710a9064fbSMasahiro Yamada    foreach my $dir ( ("/sbin", "/bin", "/usr/sbin", "/usr/bin") ) {
3720a9064fbSMasahiro Yamada	if ( -x "$dir/lsmod" ) {
3730a9064fbSMasahiro Yamada	    $lsmod = "$dir/lsmod";
3740a9064fbSMasahiro Yamada	    last;
3750a9064fbSMasahiro Yamada	}
3760a9064fbSMasahiro Yamada}
3770a9064fbSMasahiro Yamada    if (!defined($lsmod)) {
3780a9064fbSMasahiro Yamada	# try just the path
3790a9064fbSMasahiro Yamada	$lsmod = "lsmod";
3800a9064fbSMasahiro Yamada    }
3810a9064fbSMasahiro Yamada
3820a9064fbSMasahiro Yamada    open($linfile, '-|', $lsmod) || die "Can not call lsmod with $lsmod";
3830a9064fbSMasahiro Yamada}
3840a9064fbSMasahiro Yamada
3850a9064fbSMasahiro Yamadawhile (<$linfile>) {
3860a9064fbSMasahiro Yamada	next if (/^Module/);  # Skip the first line.
3870a9064fbSMasahiro Yamada	if (/^(\S+)/) {
3880a9064fbSMasahiro Yamada		$modules{$1} = 1;
3890a9064fbSMasahiro Yamada	}
3900a9064fbSMasahiro Yamada}
3910a9064fbSMasahiro Yamadaclose ($linfile);
3920a9064fbSMasahiro Yamada
3930a9064fbSMasahiro Yamada# add to the configs hash all configs that are needed to enable
3940a9064fbSMasahiro Yamada# a loaded module. This is a direct obj-${CONFIG_FOO} += bar.o
3950a9064fbSMasahiro Yamada# where we know we need bar.o so we add FOO to the list.
3960a9064fbSMasahiro Yamadamy %configs;
3970a9064fbSMasahiro Yamadaforeach my $module (keys(%modules)) {
3980a9064fbSMasahiro Yamada    if (defined($objects{$module})) {
3990a9064fbSMasahiro Yamada	my @arr = @{$objects{$module}};
4000a9064fbSMasahiro Yamada	foreach my $conf (@arr) {
4010a9064fbSMasahiro Yamada	    $configs{$conf} = $module;
4020a9064fbSMasahiro Yamada	    dprint "$conf added by direct ($module)\n";
4030a9064fbSMasahiro Yamada	    if ($debugprint) {
4040a9064fbSMasahiro Yamada		my $c=$conf;
4050a9064fbSMasahiro Yamada		$c =~ s/^CONFIG_//;
4060a9064fbSMasahiro Yamada		if (defined($depends{$c})) {
4070a9064fbSMasahiro Yamada		    dprint " deps = $depends{$c}\n";
4080a9064fbSMasahiro Yamada		} else {
4090a9064fbSMasahiro Yamada		    dprint " no deps\n";
4100a9064fbSMasahiro Yamada		}
4110a9064fbSMasahiro Yamada	    }
4120a9064fbSMasahiro Yamada	}
4130a9064fbSMasahiro Yamada    } else {
4140a9064fbSMasahiro Yamada	# Most likely, someone has a custom (binary?) module loaded.
4150a9064fbSMasahiro Yamada	print STDERR "$module config not found!!\n";
4160a9064fbSMasahiro Yamada    }
4170a9064fbSMasahiro Yamada}
4180a9064fbSMasahiro Yamada
4190a9064fbSMasahiro Yamada# Read the current config, and see what is enabled. We want to
4200a9064fbSMasahiro Yamada# ignore configs that we would not enable anyway.
4210a9064fbSMasahiro Yamada
4220a9064fbSMasahiro Yamadamy %orig_configs;
4230a9064fbSMasahiro Yamadamy $valid = "A-Za-z_0-9";
4240a9064fbSMasahiro Yamada
4250a9064fbSMasahiro Yamadaforeach my $line (@config_file) {
4260a9064fbSMasahiro Yamada    $_ = $line;
4270a9064fbSMasahiro Yamada
4280a9064fbSMasahiro Yamada    if (/(CONFIG_[$valid]*)=(m|y)/) {
4290a9064fbSMasahiro Yamada	$orig_configs{$1} = $2;
4300a9064fbSMasahiro Yamada    }
4310a9064fbSMasahiro Yamada}
4320a9064fbSMasahiro Yamada
4330a9064fbSMasahiro Yamadamy $repeat = 1;
4340a9064fbSMasahiro Yamada
4350a9064fbSMasahiro Yamadamy $depconfig;
4360a9064fbSMasahiro Yamada
4370a9064fbSMasahiro Yamada#
4380a9064fbSMasahiro Yamada# Note, we do not care about operands (like: &&, ||, !) we want to add any
4390a9064fbSMasahiro Yamada# config that is in the depend list of another config. This script does
4400a9064fbSMasahiro Yamada# not enable configs that are not already enabled. If we come across a
4410a9064fbSMasahiro Yamada# config A that depends on !B, we can still add B to the list of depends
4420a9064fbSMasahiro Yamada# to keep on. If A was on in the original config, B would not have been
4430a9064fbSMasahiro Yamada# and B would not be turned on by this script.
4440a9064fbSMasahiro Yamada#
4450a9064fbSMasahiro Yamadasub parse_config_depends
4460a9064fbSMasahiro Yamada{
4470a9064fbSMasahiro Yamada    my ($p) = @_;
4480a9064fbSMasahiro Yamada
4490a9064fbSMasahiro Yamada    while ($p =~ /[$valid]/) {
4500a9064fbSMasahiro Yamada
4510a9064fbSMasahiro Yamada	if ($p =~ /^[^$valid]*([$valid]+)/) {
4520a9064fbSMasahiro Yamada	    my $conf = "CONFIG_" . $1;
4530a9064fbSMasahiro Yamada
4540a9064fbSMasahiro Yamada	    $p =~ s/^[^$valid]*[$valid]+//;
4550a9064fbSMasahiro Yamada
4560a9064fbSMasahiro Yamada	    # We only need to process if the depend config is a module
457*bf7ab1e7SMasahiro Yamada	    if (!defined($orig_configs{$conf}) || $orig_configs{$conf} eq "y") {
4580a9064fbSMasahiro Yamada		next;
4590a9064fbSMasahiro Yamada	    }
4600a9064fbSMasahiro Yamada
4610a9064fbSMasahiro Yamada	    if (!defined($configs{$conf})) {
4620a9064fbSMasahiro Yamada		# We must make sure that this config has its
4630a9064fbSMasahiro Yamada		# dependencies met.
4640a9064fbSMasahiro Yamada		$repeat = 1; # do again
4650a9064fbSMasahiro Yamada		dprint "$conf selected by depend $depconfig\n";
4660a9064fbSMasahiro Yamada		$configs{$conf} = 1;
4670a9064fbSMasahiro Yamada	    }
4680a9064fbSMasahiro Yamada	} else {
4690a9064fbSMasahiro Yamada	    die "this should never happen";
4700a9064fbSMasahiro Yamada	}
4710a9064fbSMasahiro Yamada    }
4720a9064fbSMasahiro Yamada}
4730a9064fbSMasahiro Yamada
4740a9064fbSMasahiro Yamada# Select is treated a bit differently than depends. We call this
4750a9064fbSMasahiro Yamada# when a config has no prompt and requires another config to be
4760a9064fbSMasahiro Yamada# selected. We use to just select all configs that selected this
4770a9064fbSMasahiro Yamada# config, but found that that can balloon into enabling hundreds
4780a9064fbSMasahiro Yamada# of configs that we do not care about.
4790a9064fbSMasahiro Yamada#
4800a9064fbSMasahiro Yamada# The idea is we look at all the configs that select it. If one
4810a9064fbSMasahiro Yamada# is already in our list of configs to enable, then there's nothing
4820a9064fbSMasahiro Yamada# else to do. If there isn't, we pick the first config that was
4830a9064fbSMasahiro Yamada# enabled in the orignal config and use that.
4840a9064fbSMasahiro Yamadasub parse_config_selects
4850a9064fbSMasahiro Yamada{
4860a9064fbSMasahiro Yamada    my ($config, $p) = @_;
4870a9064fbSMasahiro Yamada
4880a9064fbSMasahiro Yamada    my $next_config;
4890a9064fbSMasahiro Yamada
4900a9064fbSMasahiro Yamada    while ($p =~ /[$valid]/) {
4910a9064fbSMasahiro Yamada
4920a9064fbSMasahiro Yamada	if ($p =~ /^[^$valid]*([$valid]+)/) {
4930a9064fbSMasahiro Yamada	    my $conf = "CONFIG_" . $1;
4940a9064fbSMasahiro Yamada
4950a9064fbSMasahiro Yamada	    $p =~ s/^[^$valid]*[$valid]+//;
4960a9064fbSMasahiro Yamada
4970a9064fbSMasahiro Yamada	    # Make sure that this config exists in the current .config file
4980a9064fbSMasahiro Yamada	    if (!defined($orig_configs{$conf})) {
4990a9064fbSMasahiro Yamada		dprint "$conf not set for $config select\n";
5000a9064fbSMasahiro Yamada		next;
5010a9064fbSMasahiro Yamada	    }
5020a9064fbSMasahiro Yamada
5030a9064fbSMasahiro Yamada	    # Check if something other than a module selects this config
5040a9064fbSMasahiro Yamada	    if (defined($orig_configs{$conf}) && $orig_configs{$conf} ne "m") {
5050a9064fbSMasahiro Yamada		dprint "$conf (non module) selects config, we are good\n";
5060a9064fbSMasahiro Yamada		# we are good with this
5070a9064fbSMasahiro Yamada		return;
5080a9064fbSMasahiro Yamada	    }
5090a9064fbSMasahiro Yamada	    if (defined($configs{$conf})) {
5100a9064fbSMasahiro Yamada		dprint "$conf selects $config so we are good\n";
5110a9064fbSMasahiro Yamada		# A set config selects this config, we are good
5120a9064fbSMasahiro Yamada		return;
5130a9064fbSMasahiro Yamada	    }
5140a9064fbSMasahiro Yamada	    # Set this config to be selected
5150a9064fbSMasahiro Yamada	    if (!defined($next_config)) {
5160a9064fbSMasahiro Yamada		$next_config = $conf;
5170a9064fbSMasahiro Yamada	    }
5180a9064fbSMasahiro Yamada	} else {
5190a9064fbSMasahiro Yamada	    die "this should never happen";
5200a9064fbSMasahiro Yamada	}
5210a9064fbSMasahiro Yamada    }
5220a9064fbSMasahiro Yamada
5230a9064fbSMasahiro Yamada    # If no possible config selected this, then something happened.
5240a9064fbSMasahiro Yamada    if (!defined($next_config)) {
5250a9064fbSMasahiro Yamada	print STDERR "WARNING: $config is required, but nothing in the\n";
5260a9064fbSMasahiro Yamada	print STDERR "  current config selects it.\n";
5270a9064fbSMasahiro Yamada	return;
5280a9064fbSMasahiro Yamada    }
5290a9064fbSMasahiro Yamada
5300a9064fbSMasahiro Yamada    # If we are here, then we found no config that is set and
5310a9064fbSMasahiro Yamada    # selects this config. Repeat.
5320a9064fbSMasahiro Yamada    $repeat = 1;
5330a9064fbSMasahiro Yamada    # Make this config need to be selected
5340a9064fbSMasahiro Yamada    $configs{$next_config} = 1;
5350a9064fbSMasahiro Yamada    dprint "$next_config selected by select $config\n";
5360a9064fbSMasahiro Yamada}
5370a9064fbSMasahiro Yamada
5380a9064fbSMasahiro Yamadamy %process_selects;
5390a9064fbSMasahiro Yamada
5400a9064fbSMasahiro Yamada# loop through all configs, select their dependencies.
5410a9064fbSMasahiro Yamadasub loop_depend {
5420a9064fbSMasahiro Yamada    $repeat = 1;
5430a9064fbSMasahiro Yamada
5440a9064fbSMasahiro Yamada    while ($repeat) {
5450a9064fbSMasahiro Yamada	$repeat = 0;
5460a9064fbSMasahiro Yamada
5470a9064fbSMasahiro Yamada      forloop:
5480a9064fbSMasahiro Yamada	foreach my $config (keys %configs) {
5490a9064fbSMasahiro Yamada
5500a9064fbSMasahiro Yamada	    # If this config is not a module, we do not need to process it
5510a9064fbSMasahiro Yamada	    if (defined($orig_configs{$config}) && $orig_configs{$config} ne "m") {
5520a9064fbSMasahiro Yamada		next forloop;
5530a9064fbSMasahiro Yamada	    }
5540a9064fbSMasahiro Yamada
5550a9064fbSMasahiro Yamada	    $config =~ s/^CONFIG_//;
5560a9064fbSMasahiro Yamada	    $depconfig = $config;
5570a9064fbSMasahiro Yamada
5580a9064fbSMasahiro Yamada	    if (defined($depends{$config})) {
5590a9064fbSMasahiro Yamada		# This config has dependencies. Make sure they are also included
5600a9064fbSMasahiro Yamada		parse_config_depends $depends{$config};
5610a9064fbSMasahiro Yamada	    }
5620a9064fbSMasahiro Yamada
5630a9064fbSMasahiro Yamada	    # If the config has no prompt, then we need to check if a config
5640a9064fbSMasahiro Yamada	    # that is enabled selected it. Or if we need to enable one.
5650a9064fbSMasahiro Yamada	    if (!defined($prompts{$config}) && defined($selects{$config})) {
5660a9064fbSMasahiro Yamada		$process_selects{$config} = 1;
5670a9064fbSMasahiro Yamada	    }
5680a9064fbSMasahiro Yamada	}
5690a9064fbSMasahiro Yamada    }
5700a9064fbSMasahiro Yamada}
5710a9064fbSMasahiro Yamada
5720a9064fbSMasahiro Yamadasub loop_select {
5730a9064fbSMasahiro Yamada
5740a9064fbSMasahiro Yamada    foreach my $config (keys %process_selects) {
5750a9064fbSMasahiro Yamada	$config =~ s/^CONFIG_//;
5760a9064fbSMasahiro Yamada
5770a9064fbSMasahiro Yamada	dprint "Process select $config\n";
5780a9064fbSMasahiro Yamada
5790a9064fbSMasahiro Yamada	# config has no prompt and must be selected.
5800a9064fbSMasahiro Yamada	parse_config_selects $config, $selects{$config};
5810a9064fbSMasahiro Yamada    }
5820a9064fbSMasahiro Yamada}
5830a9064fbSMasahiro Yamada
5840a9064fbSMasahiro Yamadawhile ($repeat) {
5850a9064fbSMasahiro Yamada    # Get the first set of configs and their dependencies.
5860a9064fbSMasahiro Yamada    loop_depend;
5870a9064fbSMasahiro Yamada
5880a9064fbSMasahiro Yamada    $repeat = 0;
5890a9064fbSMasahiro Yamada
5900a9064fbSMasahiro Yamada    # Now we need to see if we have to check selects;
5910a9064fbSMasahiro Yamada    loop_select;
5920a9064fbSMasahiro Yamada}
5930a9064fbSMasahiro Yamada
5940a9064fbSMasahiro Yamadamy %setconfigs;
5950a9064fbSMasahiro Yamada
5960a9064fbSMasahiro Yamada# Finally, read the .config file and turn off any module enabled that
5970a9064fbSMasahiro Yamada# we could not find a reason to keep enabled.
5980a9064fbSMasahiro Yamadaforeach my $line (@config_file) {
5990a9064fbSMasahiro Yamada    $_ = $line;
6000a9064fbSMasahiro Yamada
6010a9064fbSMasahiro Yamada    if (/CONFIG_IKCONFIG/) {
6020a9064fbSMasahiro Yamada	if (/# CONFIG_IKCONFIG is not set/) {
6030a9064fbSMasahiro Yamada	    # enable IKCONFIG at least as a module
6040a9064fbSMasahiro Yamada	    print "CONFIG_IKCONFIG=m\n";
6050a9064fbSMasahiro Yamada	    # don't ask about PROC
6060a9064fbSMasahiro Yamada	    print "# CONFIG_IKCONFIG_PROC is not set\n";
6070a9064fbSMasahiro Yamada	} else {
6080a9064fbSMasahiro Yamada	    print;
6090a9064fbSMasahiro Yamada	}
6100a9064fbSMasahiro Yamada	next;
6110a9064fbSMasahiro Yamada    }
6120a9064fbSMasahiro Yamada
613*bf7ab1e7SMasahiro Yamada    if (/CONFIG_MODULE_SIG_KEY="(.+)"/) {
614*bf7ab1e7SMasahiro Yamada        my $orig_cert = $1;
615*bf7ab1e7SMasahiro Yamada        my $default_cert = "certs/signing_key.pem";
616*bf7ab1e7SMasahiro Yamada
617*bf7ab1e7SMasahiro Yamada        # Check that the logic in this script still matches the one in Kconfig
618*bf7ab1e7SMasahiro Yamada        if (!defined($depends{"MODULE_SIG_KEY"}) ||
619*bf7ab1e7SMasahiro Yamada            $depends{"MODULE_SIG_KEY"} !~ /"\Q$default_cert\E"/) {
620*bf7ab1e7SMasahiro Yamada            print STDERR "WARNING: MODULE_SIG_KEY assertion failure, ",
621*bf7ab1e7SMasahiro Yamada                "update needed to ", __FILE__, " line ", __LINE__, "\n";
622*bf7ab1e7SMasahiro Yamada            print;
623*bf7ab1e7SMasahiro Yamada        } elsif ($orig_cert ne $default_cert && ! -f $orig_cert) {
624*bf7ab1e7SMasahiro Yamada            print STDERR "Module signature verification enabled but ",
625*bf7ab1e7SMasahiro Yamada                "module signing key \"$orig_cert\" not found. Resetting ",
626*bf7ab1e7SMasahiro Yamada                "signing key to default value.\n";
627*bf7ab1e7SMasahiro Yamada            print "CONFIG_MODULE_SIG_KEY=\"$default_cert\"\n";
628*bf7ab1e7SMasahiro Yamada        } else {
629*bf7ab1e7SMasahiro Yamada            print;
630*bf7ab1e7SMasahiro Yamada        }
631*bf7ab1e7SMasahiro Yamada        next;
632*bf7ab1e7SMasahiro Yamada    }
633*bf7ab1e7SMasahiro Yamada
634*bf7ab1e7SMasahiro Yamada    if (/CONFIG_SYSTEM_TRUSTED_KEYS="(.+)"/) {
635*bf7ab1e7SMasahiro Yamada        my $orig_keys = $1;
636*bf7ab1e7SMasahiro Yamada
637*bf7ab1e7SMasahiro Yamada        if (! -f $orig_keys) {
638*bf7ab1e7SMasahiro Yamada            print STDERR "System keyring enabled but keys \"$orig_keys\" ",
639*bf7ab1e7SMasahiro Yamada                "not found. Resetting keys to default value.\n";
640*bf7ab1e7SMasahiro Yamada            print "CONFIG_SYSTEM_TRUSTED_KEYS=\"\"\n";
641*bf7ab1e7SMasahiro Yamada        } else {
642*bf7ab1e7SMasahiro Yamada            print;
643*bf7ab1e7SMasahiro Yamada        }
644*bf7ab1e7SMasahiro Yamada        next;
645*bf7ab1e7SMasahiro Yamada    }
646*bf7ab1e7SMasahiro Yamada
6470a9064fbSMasahiro Yamada    if (/^(CONFIG.*)=(m|y)/) {
6480a9064fbSMasahiro Yamada	if (defined($configs{$1})) {
6490a9064fbSMasahiro Yamada	    if ($localyesconfig) {
6500a9064fbSMasahiro Yamada	        $setconfigs{$1} = 'y';
6510a9064fbSMasahiro Yamada		print "$1=y\n";
6520a9064fbSMasahiro Yamada		next;
6530a9064fbSMasahiro Yamada	    } else {
6540a9064fbSMasahiro Yamada	        $setconfigs{$1} = $2;
6550a9064fbSMasahiro Yamada	    }
6560a9064fbSMasahiro Yamada	} elsif ($2 eq "m") {
6570a9064fbSMasahiro Yamada	    print "# $1 is not set\n";
6580a9064fbSMasahiro Yamada	    next;
6590a9064fbSMasahiro Yamada	}
6600a9064fbSMasahiro Yamada    }
6610a9064fbSMasahiro Yamada    print;
6620a9064fbSMasahiro Yamada}
6630a9064fbSMasahiro Yamada
6640a9064fbSMasahiro Yamada# Integrity check, make sure all modules that we want enabled do
6650a9064fbSMasahiro Yamada# indeed have their configs set.
6660a9064fbSMasahiro Yamadaloop:
6670a9064fbSMasahiro Yamadaforeach my $module (keys(%modules)) {
6680a9064fbSMasahiro Yamada    if (defined($objects{$module})) {
6690a9064fbSMasahiro Yamada	my @arr = @{$objects{$module}};
6700a9064fbSMasahiro Yamada	foreach my $conf (@arr) {
6710a9064fbSMasahiro Yamada	    if (defined($setconfigs{$conf})) {
6720a9064fbSMasahiro Yamada		next loop;
6730a9064fbSMasahiro Yamada	    }
6740a9064fbSMasahiro Yamada	}
6750a9064fbSMasahiro Yamada	print STDERR "module $module did not have configs";
6760a9064fbSMasahiro Yamada	foreach my $conf (@arr) {
6770a9064fbSMasahiro Yamada	    print STDERR " " , $conf;
6780a9064fbSMasahiro Yamada	}
6790a9064fbSMasahiro Yamada	print STDERR "\n";
6800a9064fbSMasahiro Yamada    }
6810a9064fbSMasahiro Yamada}
682