blob: 8c6548d280c8dc9660a22a4e138948cc6f464e18 [file] [log] [blame]
Eric Andersenc126f8f2001-07-30 19:32:03 +00001#!/usr/bin/perl -w
"Robert P. J. Day"63fc1a92006-07-02 19:47:05 +00002# vi: set sw=4 ts=4:
Eric Andersenc126f8f2001-07-30 19:32:03 +00003# 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.
Mike Frysinger2b6497b2009-05-05 20:14:12 -040016use Getopt::Long qw(:config no_auto_abbrev no_ignore_case);
Eric Andersenc126f8f2001-07-30 19:32:03 +000017use 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="";
Mike Frysingerd611ccc2007-07-13 04:37:12 +000025my $symprefix="";
Mike Frysinger2b6497b2009-05-05 20:14:12 -040026my $all=0;
27my $quick=0;
28my $errsyms=0;
"Steven J. Hill"adb058b2002-10-08 21:33:51 +000029my $stdout=0;
Eric Andersenc126f8f2001-07-30 19:32:03 +000030my $verbose=0;
Rob Landleyd0498122006-03-21 16:35:50 +000031my $help=0;
Rob Landley9a990aa2006-06-02 21:30:40 +000032my $nm = $ENV{'NM'} || "nm";
Eric Andersenc126f8f2001-07-30 19:32:03 +000033
Rob Landleyd0498122006-03-21 16:35:50 +000034# more globals
35my (@liblist) = ();
36my $exp = {};
37my $dep = {};
38my $mod = {};
39
40my $usage = <<TXT;
Denis Vlasenko9213a9e2006-09-17 16:28:10 +000041$0 -b basedir { -k <vmlinux> | -F <System.map> } [options]...
Rob Landleyd0498122006-03-21 16:35:50 +000042 Where:
Mike Frysingerd611ccc2007-07-13 04:37:12 +000043 -h --help : Show this help screen
44 -b --basedir : Modules base directory (e.g /lib/modules/<2.x.y>)
45 -k --kernel : Kernel binary for the target (e.g. vmlinux)
46 -F --kernelsyms : Kernel symbol file (e.g. System.map)
47 -n --stdout : Write to stdout instead of <basedir>/modules.dep
48 -v --verbose : Print out lots of debugging stuff
49 -P --symbol-prefix : Symbol prefix
Mike Frysinger2b6497b2009-05-05 20:14:12 -040050 -a --all : Probe all modules (default/only thing supported)
51 -e --errsyms : Report any symbols not supplied by modules/kernel
Rob Landleyd0498122006-03-21 16:35:50 +000052TXT
Eric Andersenc126f8f2001-07-30 19:32:03 +000053
54# get command-line options
Eric Andersenc126f8f2001-07-30 19:32:03 +000055GetOptions(
Mike Frysingerd611ccc2007-07-13 04:37:12 +000056 "help|h" => \$help,
57 "basedir|b=s" => \$basedir,
58 "kernel|k=s" => \$kernel,
59 "kernelsyms|F=s" => \$kernelsyms,
60 "stdout|n" => \$stdout,
61 "verbose|v" => \$verbose,
62 "symbol-prefix|P=s" => \$symprefix,
Mike Frysinger2b6497b2009-05-05 20:14:12 -040063 "all|a" => \$all,
64 # unsupported options
65 "quick|A" => \$quick,
66 # ignored options (for historical usage)
67 "quiet|q",
68 "root|r",
69 "unresolved-error|u"
Eric Andersenc126f8f2001-07-30 19:32:03 +000070);
71
Rob Landleyd0498122006-03-21 16:35:50 +000072die $usage if $help;
73die $usage unless $basedir && ( $kernel || $kernelsyms );
74die "can't use both -k and -F\n\n$usage" if $kernel && $kernelsyms;
Mike Frysinger2b6497b2009-05-05 20:14:12 -040075die "sorry, -A/--quick is not supported" if $quick;
76die "--errsyms requires --kernelsyms" if $errsyms && !$kernelsyms;
Eric Andersenc126f8f2001-07-30 19:32:03 +000077
Rob Landleyd0498122006-03-21 16:35:50 +000078# Strip any trailing or multiple slashes from basedir
Mike Frysinger2b6497b2009-05-05 20:14:12 -040079$basedir =~ s-/+$--g;
Rob Landleyd0498122006-03-21 16:35:50 +000080
81# The base directory should contain /lib/modules somewhere
Eric Andersenc126f8f2001-07-30 19:32:03 +000082if($basedir !~ m-/lib/modules-) {
83 warn "WARNING: base directory does not match ..../lib/modules\n";
84}
85
Rob Landleyd0498122006-03-21 16:35:50 +000086# if no kernel version is contained in the basedir, try to find one
87if($basedir !~ m-/lib/modules/\d\.\d-) {
88 opendir(BD, $basedir) or die "can't open basedir $basedir : $!\n";
89 foreach ( readdir(BD) ) {
90 next if /^\.\.?$/;
91 next unless -d "$basedir/$_";
92 warn "dir = $_\n" if $verbose;
93 if( /^\d\.\d/ ) {
94 $kdir = $_;
95 warn("Guessed module directory as $basedir/$kdir\n");
96 last;
97 }
98 }
99 closedir(BD);
100 die "Cannot find a kernel version under $basedir\n" unless $kdir;
101 $basedir = "$basedir/$kdir";
102}
103
104# Find the list of .o or .ko files living under $basedir
105warn "**** Locating all modules\n" if $verbose;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000106find sub {
Rob Landleyd0498122006-03-21 16:35:50 +0000107 my $file;
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000108 if ( -f $_ && ! -d $_ ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +0000109 $file = $File::Find::name;
Rob Landleyd0498122006-03-21 16:35:50 +0000110 if ( $file =~ /\.k?o$/ ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +0000111 push(@liblist, $file);
Rob Landleyd0498122006-03-21 16:35:50 +0000112 warn "$file\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000113 }
114 }
115}, $basedir;
Rob Landleyd0498122006-03-21 16:35:50 +0000116warn "**** Finished locating modules\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000117
Rob Landleyd0498122006-03-21 16:35:50 +0000118foreach my $obj ( @liblist ){
Eric Andersenc126f8f2001-07-30 19:32:03 +0000119 # turn the input file name into a target tag name
Rob Landleyd0498122006-03-21 16:35:50 +0000120 my ($tgtname) = $obj =~ m-(/lib/modules/.*)$-;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000121
Rob Landleyd0498122006-03-21 16:35:50 +0000122 warn "\nMODULE = $tgtname\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000123
124 # get a list of symbols
Rob Landley9a990aa2006-06-02 21:30:40 +0000125 my @output=`$nm $obj`;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000126
Rob Landleyd0498122006-03-21 16:35:50 +0000127 build_ref_tables($tgtname, \@output, $exp, $dep);
Eric Andersenc126f8f2001-07-30 19:32:03 +0000128}
129
130
Rob Landleyd0498122006-03-21 16:35:50 +0000131# vmlinux is a special name that is only used to resolve symbols
132my $tgtname = 'vmlinux';
Rob Landley9a990aa2006-06-02 21:30:40 +0000133my @output = $kernelsyms ? `cat $kernelsyms` : `$nm $kernel`;
Rob Landleyd0498122006-03-21 16:35:50 +0000134warn "\nMODULE = $tgtname\n" if $verbose;
135build_ref_tables($tgtname, \@output, $exp, $dep);
136
Mike Frysingerfa6c4842006-05-26 01:48:17 +0000137# resolve the dependencies for each module
138# reduce dependencies: remove unresolvable and resolved from vmlinux/System.map
Eric Andersenc126f8f2001-07-30 19:32:03 +0000139# remove duplicates
Rob Landleyd0498122006-03-21 16:35:50 +0000140foreach my $module (keys %$dep) {
141 warn "reducing module: $module\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000142 $mod->{$module} = {};
143 foreach (@{$dep->{$module}}) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000144 if( $exp->{$_} ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +0000145 warn "resolved symbol $_ in file $exp->{$_}\n" if $verbose;
146 next if $exp->{$_} =~ /vmlinux/;
147 $mod->{$module}{$exp->{$_}} = 1;
148 } else {
149 warn "unresolved symbol $_ in file $module\n";
150 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000151 }
Eric Andersenc126f8f2001-07-30 19:32:03 +0000152}
153
Mike Frysinger2b6497b2009-05-05 20:14:12 -0400154# build a complete dependency list for each module and make sure it
155# is kept in order proper order
156my $mod2 = {};
157sub maybe_unshift
158{
159 my ($array, $ele) = @_;
160 # chop off the leading path /lib/modules/<kver>/ as modprobe
161 # will handle relative paths just fine
162 $ele =~ s:^/lib/modules/[^/]*/::;
163 foreach (@{$array}) {
164 if ($_ eq $ele) {
165 return;
166 }
167 }
168 unshift (@{$array}, $ele);
169}
Mike Frysinger4c8a7212009-07-09 00:28:48 -0400170sub add_mod_deps
171{
172 my ($depth, $mod, $mod2, $module, $this_module) = @_;
173
174 $depth .= " ";
175 warn "${depth}loading deps of module: $this_module\n" if $verbose;
176
177 foreach my $md (keys %{$mod->{$this_module}}) {
178 add_mod_deps ($depth, $mod, $mod2, $module, $md);
179 warn "${depth} outputting $md\n" if $verbose;
180 maybe_unshift (\@{$$mod2->{$module}}, $md);
181 }
182
183 if (!%{$mod->{$this_module}}) {
184 warn "${depth} no deps\n" if $verbose;
185 }
186}
Mike Frysinger2b6497b2009-05-05 20:14:12 -0400187foreach my $module (keys %$mod) {
Mike Frysinger4c8a7212009-07-09 00:28:48 -0400188 warn "filling out module: $module\n" if $verbose;
189 @{$mod2->{$module}} = ();
190 add_mod_deps ("", $mod, \$mod2, $module, $module);
Mike Frysinger2b6497b2009-05-05 20:14:12 -0400191}
192
Rob Landleyd0498122006-03-21 16:35:50 +0000193# figure out where the output should go
194if ($stdout == 0) {
Mike Frysinger4c8a7212009-07-09 00:28:48 -0400195 warn "writing $basedir/modules.dep\n" if $verbose;
Rob Landleyd0498122006-03-21 16:35:50 +0000196 open(STDOUT, ">$basedir/modules.dep")
197 or die "cannot open $basedir/modules.dep: $!";
198}
199my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4';
200
201foreach my $module ( keys %$mod ) {
202 if($kseries eq '2.4') {
203 print "$module:\t";
204 my @sorted = sort bydep keys %{$mod->{$module}};
205 print join(" \\\n\t",@sorted);
206 print "\n\n";
207 } else {
Mike Frysinger2b6497b2009-05-05 20:14:12 -0400208 my $shortmod = $module;
209 $shortmod =~ s:^/lib/modules/[^/]*/::;
210 print "$shortmod:";
211 my @sorted = @{$mod2->{$module}};
212 printf " " if @sorted;
Rob Landleyd0498122006-03-21 16:35:50 +0000213 print join(" ",@sorted);
214 print "\n";
215 }
Eric Andersenc126f8f2001-07-30 19:32:03 +0000216}
217
"Steven J. Hill"adb058b2002-10-08 21:33:51 +0000218
Rob Landleyd0498122006-03-21 16:35:50 +0000219sub build_ref_tables
220{
221 my ($name, $sym_ar, $exp, $dep) = @_;
222
Mike Frysinger2b6497b2009-05-05 20:14:12 -0400223 my $ksymtab = grep m/ ${symprefix}__ksymtab/, @$sym_ar;
Rob Landleyd0498122006-03-21 16:35:50 +0000224
225 # gather the exported symbols
226 if($ksymtab){
227 # explicitly exported
228 foreach ( @$sym_ar ) {
Mike Frysinger2b6497b2009-05-05 20:14:12 -0400229 / ${symprefix}__ksymtab_(.*)$/ and do {
230 my $sym = ${symprefix} . $1;
231 warn "sym = $sym\n" if $verbose;
232 $exp->{$sym} = $name;
Rob Landleyd0498122006-03-21 16:35:50 +0000233 };
234 }
235 } else {
236 # exporting all symbols
237 foreach ( @$sym_ar ) {
Mike Frysingerdbd18f62007-11-18 06:13:58 +0000238 / [ABCDGRSTW] (.*)$/ and do {
Rob Landleyd0498122006-03-21 16:35:50 +0000239 warn "syma = $1\n" if $verbose;
240 $exp->{$1} = $name;
241 };
242 }
243 }
244
245 # this takes makes sure modules with no dependencies get listed
Mike Frysingerd611ccc2007-07-13 04:37:12 +0000246 push @{$dep->{$name}}, $symprefix . 'printk' unless $name eq 'vmlinux';
Rob Landleyd0498122006-03-21 16:35:50 +0000247
248 # gather the unresolved symbols
249 foreach ( @$sym_ar ) {
Mike Frysinger2b6497b2009-05-05 20:14:12 -0400250 !/ ${symprefix}__this_module/ && / U (.*)$/ and do {
Rob Landleyd0498122006-03-21 16:35:50 +0000251 warn "und = $1\n" if $verbose;
252 push @{$dep->{$name}}, $1;
253 };
254 }
255}
256
Eric Andersenc126f8f2001-07-30 19:32:03 +0000257sub bydep
258{
259 foreach my $f ( keys %{$mod->{$b}} ) {
260 if($f eq $a) {
261 return 1;
262 }
263 }
264 return -1;
265}
266
267
268
269__END__
270
271=head1 NAME
272
Rob Landleyd0498122006-03-21 16:35:50 +0000273depmod.pl - a cross platform script to generate kernel module
274dependency lists (modules.conf) which can then be used by modprobe
Denis Vlasenko9213a9e2006-09-17 16:28:10 +0000275on the target platform.
Rob Landleyd0498122006-03-21 16:35:50 +0000276
277It supports Linux 2.4 and 2.6 styles of modules.conf (auto-detected)
Eric Andersenc126f8f2001-07-30 19:32:03 +0000278
279=head1 SYNOPSIS
280
"Steven J. Hill"adb058b2002-10-08 21:33:51 +0000281depmod.pl [OPTION]... [basedir]...
Eric Andersenc126f8f2001-07-30 19:32:03 +0000282
283Example:
284
Rob Landleyd0498122006-03-21 16:35:50 +0000285 depmod.pl -F linux/System.map -b target/lib/modules/2.6.11
Eric Andersenc126f8f2001-07-30 19:32:03 +0000286
287=head1 DESCRIPTION
288
289The purpose of this script is to automagically generate a list of of kernel
Mike Frysingerfa6c4842006-05-26 01:48:17 +0000290module dependencies. This script produces dependency lists that should be
Eric Andersenc126f8f2001-07-30 19:32:03 +0000291identical to the depmod program from the modutils package. Unlike the depmod
292binary, however, depmod.pl is designed to be run on your host system, not
293on your target system.
294
295This script was written by David Schleef <ds@schleef.org> to be used in
296conjunction with the BusyBox modprobe applet.
297
298=head1 OPTIONS
299
300=over 4
301
302=item B<-h --help>
303
304This displays the help message.
305
306=item B<-b --basedir>
307
308The base directory uner which the target's modules will be found. This
Denis Vlasenko9213a9e2006-09-17 16:28:10 +0000309defaults to the /lib/modules directory.
Rob Landleyd0498122006-03-21 16:35:50 +0000310
311If you don't specify the kernel version, this script will search for
312one under the specified based directory and use the first thing that
313looks like a kernel version.
Eric Andersenc126f8f2001-07-30 19:32:03 +0000314
315=item B<-k --kernel>
316
Rob Landleyd0498122006-03-21 16:35:50 +0000317Kernel binary for the target (vmlinux). You must either supply a kernel binary
Eric Andersenc126f8f2001-07-30 19:32:03 +0000318or a kernel symbol file (using the -F option).
319
320=item B<-F --kernelsyms>
321
Rob Landleyd0498122006-03-21 16:35:50 +0000322Kernel symbol file for the target (System.map).
Eric Andersenc126f8f2001-07-30 19:32:03 +0000323
324=item B<-n --stdout>
325
Rob Landleyd0498122006-03-21 16:35:50 +0000326Write to stdout instead of modules.dep
Eric Andersenc126f8f2001-07-30 19:32:03 +0000327kernel binary for the target (using the -k option).
328
329=item B<--verbose>
330
Rob Landleyd0498122006-03-21 16:35:50 +0000331Verbose (debug) output
Eric Andersenc126f8f2001-07-30 19:32:03 +0000332
333=back
334
Rob Landleyd0498122006-03-21 16:35:50 +0000335=head1 COPYRIGHT AND LICENSE
Eric Andersenc126f8f2001-07-30 19:32:03 +0000336
Rob Landleyd0498122006-03-21 16:35:50 +0000337 Copyright (c) 2001 David Schleef <ds@schleef.org>
338 Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
339 Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
340 Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
341 Copyright (c) 2006 Freescale Semiconductor, Inc <stuarth@freescale.com>
342
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000343This program is free software; you can redistribute it and/or modify it
Eric Andersenc126f8f2001-07-30 19:32:03 +0000344under the same terms as Perl itself.
345
346=head1 AUTHOR
347
348David Schleef <ds@schleef.org>
349
350=cut