blob: 3211c8a6493a42bf167690a7cc3406901389c718 [file] [log] [blame]
Eric Andersenc126f8f2001-07-30 19:32:03 +00001#!/usr/bin/perl -w
2# vi: set ts=4:
3# Copyright (c) 2001 David Schleef <ds@schleef.org>
Eric Andersencb81e642003-07-14 21:21:08 +00004# Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
Rob Landleyd0498122006-03-21 16:35:50 +00005# Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
"Steven J. Hill"adb058b2002-10-08 21:33:51 +00006# Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
Rob Landleyd0498122006-03-21 16:35:50 +00007# Copyright (c) 2006 Freescale Semiconductor, Inc <stuarth@freescale.com>
8#
9# History:
10# March 2006: Stuart Hughes <stuarth@freescale.com>.
11# Significant updates, including implementing the '-F' option
12# and adding support for 2.6 kernels.
13
Eric Andersenc7bda1c2004-03-15 08:29:22 +000014# This program is free software; you can redistribute it and/or modify it
Eric Andersenc126f8f2001-07-30 19:32:03 +000015# under the same terms as Perl itself.
Eric Andersenc126f8f2001-07-30 19:32:03 +000016use Getopt::Long;
17use File::Find;
Rob Landleyd0498122006-03-21 16:35:50 +000018use strict;
Eric Andersenc126f8f2001-07-30 19:32:03 +000019
20# Set up some default values
Rob Landleyd0498122006-03-21 16:35:50 +000021my $kdir="";
Eric Andersenc126f8f2001-07-30 19:32:03 +000022my $basedir="";
Rob Landleyd0498122006-03-21 16:35:50 +000023my $kernel="";
24my $kernelsyms="";
"Steven J. Hill"adb058b2002-10-08 21:33:51 +000025my $stdout=0;
Eric Andersenc126f8f2001-07-30 19:32:03 +000026my $verbose=0;
Rob Landleyd0498122006-03-21 16:35:50 +000027my $help=0;
Eric Andersenc126f8f2001-07-30 19:32:03 +000028
Rob Landleyd0498122006-03-21 16:35:50 +000029# more globals
30my (@liblist) = ();
31my $exp = {};
32my $dep = {};
33my $mod = {};
34
35my $usage = <<TXT;
36$0 -b basedir { -k <vmlinux> | -F <System.map> } [options]...
37 Where:
38 -h --help : Show this help screen
39 -b --basedir : Modules base directory (e.g /lib/modules/<2.x.y>)
40 -k --kernel : Kernel binary for the target (e.g. vmlinux)
41 -F --kernelsyms : Kernel symbol file (e.g. System.map)
42 -n --stdout : Write to stdout instead of <basedir>/modules.dep
43 -v --verbose : Print out lots of debugging stuff
44TXT
Eric Andersenc126f8f2001-07-30 19:32:03 +000045
46# get command-line options
Eric Andersenc126f8f2001-07-30 19:32:03 +000047GetOptions(
Rob Landleyd0498122006-03-21 16:35:50 +000048 "help|h" => \$help,
49 "basedir|b=s" => \$basedir,
50 "kernel|k=s" => \$kernel,
Eric Andersenc126f8f2001-07-30 19:32:03 +000051 "kernelsyms|F=s" => \$kernelsyms,
Rob Landleyd0498122006-03-21 16:35:50 +000052 "stdout|n" => \$stdout,
53 "verbose|v" => \$verbose,
Eric Andersenc126f8f2001-07-30 19:32:03 +000054);
55
Rob Landleyd0498122006-03-21 16:35:50 +000056die $usage if $help;
57die $usage unless $basedir && ( $kernel || $kernelsyms );
58die "can't use both -k and -F\n\n$usage" if $kernel && $kernelsyms;
Eric Andersenc126f8f2001-07-30 19:32:03 +000059
Rob Landleyd0498122006-03-21 16:35:50 +000060# Strip any trailing or multiple slashes from basedir
61$basedir =~ s-(/)\1+-/-g;
62
63# The base directory should contain /lib/modules somewhere
Eric Andersenc126f8f2001-07-30 19:32:03 +000064if($basedir !~ m-/lib/modules-) {
65 warn "WARNING: base directory does not match ..../lib/modules\n";
66}
67
Rob Landleyd0498122006-03-21 16:35:50 +000068# if no kernel version is contained in the basedir, try to find one
69if($basedir !~ m-/lib/modules/\d\.\d-) {
70 opendir(BD, $basedir) or die "can't open basedir $basedir : $!\n";
71 foreach ( readdir(BD) ) {
72 next if /^\.\.?$/;
73 next unless -d "$basedir/$_";
74 warn "dir = $_\n" if $verbose;
75 if( /^\d\.\d/ ) {
76 $kdir = $_;
77 warn("Guessed module directory as $basedir/$kdir\n");
78 last;
79 }
80 }
81 closedir(BD);
82 die "Cannot find a kernel version under $basedir\n" unless $kdir;
83 $basedir = "$basedir/$kdir";
84}
85
86# Find the list of .o or .ko files living under $basedir
87warn "**** Locating all modules\n" if $verbose;
Eric Andersenc7bda1c2004-03-15 08:29:22 +000088find sub {
Rob Landleyd0498122006-03-21 16:35:50 +000089 my $file;
Eric Andersenc7bda1c2004-03-15 08:29:22 +000090 if ( -f $_ && ! -d $_ ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +000091 $file = $File::Find::name;
Rob Landleyd0498122006-03-21 16:35:50 +000092 if ( $file =~ /\.k?o$/ ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +000093 push(@liblist, $file);
Rob Landleyd0498122006-03-21 16:35:50 +000094 warn "$file\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +000095 }
96 }
97}, $basedir;
Rob Landleyd0498122006-03-21 16:35:50 +000098warn "**** Finished locating modules\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +000099
Rob Landleyd0498122006-03-21 16:35:50 +0000100foreach my $obj ( @liblist ){
Eric Andersenc126f8f2001-07-30 19:32:03 +0000101 # turn the input file name into a target tag name
Rob Landleyd0498122006-03-21 16:35:50 +0000102 my ($tgtname) = $obj =~ m-(/lib/modules/.*)$-;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000103
Rob Landleyd0498122006-03-21 16:35:50 +0000104 warn "\nMODULE = $tgtname\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000105
106 # get a list of symbols
Rob Landleyd0498122006-03-21 16:35:50 +0000107 my @output=`nm $obj`;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000108
Rob Landleyd0498122006-03-21 16:35:50 +0000109 build_ref_tables($tgtname, \@output, $exp, $dep);
Eric Andersenc126f8f2001-07-30 19:32:03 +0000110}
111
112
Rob Landleyd0498122006-03-21 16:35:50 +0000113# vmlinux is a special name that is only used to resolve symbols
114my $tgtname = 'vmlinux';
115my @output = $kernelsyms ? `cat $kernelsyms` : `nm $kernel`;
116warn "\nMODULE = $tgtname\n" if $verbose;
117build_ref_tables($tgtname, \@output, $exp, $dep);
118
119# resolve the dependancies for each module
120# reduce dependancies: remove unresolvable and resolved from vmlinux/System.map
Eric Andersenc126f8f2001-07-30 19:32:03 +0000121# remove duplicates
Rob Landleyd0498122006-03-21 16:35:50 +0000122foreach my $module (keys %$dep) {
123 warn "reducing module: $module\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000124 $mod->{$module} = {};
125 foreach (@{$dep->{$module}}) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000126 if( $exp->{$_} ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +0000127 warn "resolved symbol $_ in file $exp->{$_}\n" if $verbose;
128 next if $exp->{$_} =~ /vmlinux/;
129 $mod->{$module}{$exp->{$_}} = 1;
130 } else {
131 warn "unresolved symbol $_ in file $module\n";
132 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000133 }
Eric Andersenc126f8f2001-07-30 19:32:03 +0000134}
135
Rob Landleyd0498122006-03-21 16:35:50 +0000136# figure out where the output should go
137if ($stdout == 0) {
138 open(STDOUT, ">$basedir/modules.dep")
139 or die "cannot open $basedir/modules.dep: $!";
140}
141my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4';
142
143foreach my $module ( keys %$mod ) {
144 if($kseries eq '2.4') {
145 print "$module:\t";
146 my @sorted = sort bydep keys %{$mod->{$module}};
147 print join(" \\\n\t",@sorted);
148 print "\n\n";
149 } else {
150 print "$module: ";
151 my @sorted = sort bydep keys %{$mod->{$module}};
152 print join(" ",@sorted);
153 print "\n";
154 }
Eric Andersenc126f8f2001-07-30 19:32:03 +0000155}
156
"Steven J. Hill"adb058b2002-10-08 21:33:51 +0000157
Rob Landleyd0498122006-03-21 16:35:50 +0000158sub build_ref_tables
159{
160 my ($name, $sym_ar, $exp, $dep) = @_;
161
162 my $ksymtab = grep m/ __ksymtab/, @$sym_ar;
163
164 # gather the exported symbols
165 if($ksymtab){
166 # explicitly exported
167 foreach ( @$sym_ar ) {
168 / __ksymtab_(.*)$/ and do {
169 warn "sym = $1\n" if $verbose;
170 $exp->{$1} = $name;
171 };
172 }
173 } else {
174 # exporting all symbols
175 foreach ( @$sym_ar ) {
176 / [ABCDGRST] (.*)$/ and do {
177 warn "syma = $1\n" if $verbose;
178 $exp->{$1} = $name;
179 };
180 }
181 }
182
183 # this takes makes sure modules with no dependencies get listed
184 push @{$dep->{$name}}, 'printk' unless $name eq 'vmlinux';
185
186 # gather the unresolved symbols
187 foreach ( @$sym_ar ) {
188 !/ __this_module/ && / U (.*)$/ and do {
189 warn "und = $1\n" if $verbose;
190 push @{$dep->{$name}}, $1;
191 };
192 }
193}
194
Eric Andersenc126f8f2001-07-30 19:32:03 +0000195sub bydep
196{
197 foreach my $f ( keys %{$mod->{$b}} ) {
198 if($f eq $a) {
199 return 1;
200 }
201 }
202 return -1;
203}
204
205
206
207__END__
208
209=head1 NAME
210
Rob Landleyd0498122006-03-21 16:35:50 +0000211depmod.pl - a cross platform script to generate kernel module
212dependency lists (modules.conf) which can then be used by modprobe
213on the target platform.
214
215It supports Linux 2.4 and 2.6 styles of modules.conf (auto-detected)
Eric Andersenc126f8f2001-07-30 19:32:03 +0000216
217=head1 SYNOPSIS
218
"Steven J. Hill"adb058b2002-10-08 21:33:51 +0000219depmod.pl [OPTION]... [basedir]...
Eric Andersenc126f8f2001-07-30 19:32:03 +0000220
221Example:
222
Rob Landleyd0498122006-03-21 16:35:50 +0000223 depmod.pl -F linux/System.map -b target/lib/modules/2.6.11
Eric Andersenc126f8f2001-07-30 19:32:03 +0000224
225=head1 DESCRIPTION
226
227The purpose of this script is to automagically generate a list of of kernel
228module dependancies. This script produces dependancy lists that should be
229identical to the depmod program from the modutils package. Unlike the depmod
230binary, however, depmod.pl is designed to be run on your host system, not
231on your target system.
232
233This script was written by David Schleef <ds@schleef.org> to be used in
234conjunction with the BusyBox modprobe applet.
235
236=head1 OPTIONS
237
238=over 4
239
240=item B<-h --help>
241
242This displays the help message.
243
244=item B<-b --basedir>
245
246The base directory uner which the target's modules will be found. This
Rob Landleyd0498122006-03-21 16:35:50 +0000247defaults to the /lib/modules directory.
248
249If you don't specify the kernel version, this script will search for
250one under the specified based directory and use the first thing that
251looks like a kernel version.
Eric Andersenc126f8f2001-07-30 19:32:03 +0000252
253=item B<-k --kernel>
254
Rob Landleyd0498122006-03-21 16:35:50 +0000255Kernel binary for the target (vmlinux). You must either supply a kernel binary
Eric Andersenc126f8f2001-07-30 19:32:03 +0000256or a kernel symbol file (using the -F option).
257
258=item B<-F --kernelsyms>
259
Rob Landleyd0498122006-03-21 16:35:50 +0000260Kernel symbol file for the target (System.map).
Eric Andersenc126f8f2001-07-30 19:32:03 +0000261
262=item B<-n --stdout>
263
Rob Landleyd0498122006-03-21 16:35:50 +0000264Write to stdout instead of modules.dep
Eric Andersenc126f8f2001-07-30 19:32:03 +0000265kernel binary for the target (using the -k option).
266
267=item B<--verbose>
268
Rob Landleyd0498122006-03-21 16:35:50 +0000269Verbose (debug) output
Eric Andersenc126f8f2001-07-30 19:32:03 +0000270
271=back
272
Rob Landleyd0498122006-03-21 16:35:50 +0000273=head1 COPYRIGHT AND LICENSE
Eric Andersenc126f8f2001-07-30 19:32:03 +0000274
Rob Landleyd0498122006-03-21 16:35:50 +0000275 Copyright (c) 2001 David Schleef <ds@schleef.org>
276 Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
277 Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
278 Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
279 Copyright (c) 2006 Freescale Semiconductor, Inc <stuarth@freescale.com>
280
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000281This program is free software; you can redistribute it and/or modify it
Eric Andersenc126f8f2001-07-30 19:32:03 +0000282under the same terms as Perl itself.
283
284=head1 AUTHOR
285
286David Schleef <ds@schleef.org>
287
288=cut
289
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000290# $Id: depmod.pl,v 1.4 2004/03/15 08:28:33 andersen Exp $
Eric Andersenc126f8f2001-07-30 19:32:03 +0000291