source: MondoRescue/branches/3.0/mindi-busybox/examples/depmod.pl@ 2899

Last change on this file since 2899 was 2725, checked in by Bruno Cornec, 13 years ago
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
  • Property svn:executable set to *
File size: 9.6 KB
Line 
1#!/usr/bin/perl -w
2# vi: set sw=4 ts=4:
3# Copyright (c) 2001 David Schleef <ds@schleef.org>
4# Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
5# Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
6# Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
7# 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
14# This program is free software; you can redistribute it and/or modify it
15# under the same terms as Perl itself.
16use Getopt::Long qw(:config no_auto_abbrev no_ignore_case);
17use File::Find;
18use strict;
19
20# Set up some default values
21my $kdir="";
22my $basedir="";
23my $kernel="";
24my $kernelsyms="";
25my $symprefix="";
26my $all=0;
27my $quick=0;
28my $errsyms=0;
29my $stdout=0;
30my $verbose=0;
31my $help=0;
32my $nm = $ENV{'NM'} || "nm";
33
34# more globals
35my (@liblist) = ();
36my $exp = {};
37my $dep = {};
38my $mod = {};
39
40my $usage = <<TXT;
41$0 -b basedir { -k <vmlinux> | -F <System.map> } [options]...
42 Where:
43 -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
50 -a --all : Probe all modules (default/only thing supported)
51 -e --errsyms : Report any symbols not supplied by modules/kernel
52TXT
53
54# get command-line options
55GetOptions(
56 "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,
63 "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"
70);
71
72die $usage if $help;
73die $usage unless $basedir && ( $kernel || $kernelsyms );
74die "can't use both -k and -F\n\n$usage" if $kernel && $kernelsyms;
75die "sorry, -A/--quick is not supported" if $quick;
76die "--errsyms requires --kernelsyms" if $errsyms && !$kernelsyms;
77
78# Strip any trailing or multiple slashes from basedir
79$basedir =~ s-/+$--g;
80
81# The base directory should contain /lib/modules somewhere
82if($basedir !~ m-/lib/modules-) {
83 warn "WARNING: base directory does not match ..../lib/modules\n";
84}
85
86# 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;
106find sub {
107 my $file;
108 if ( -f $_ && ! -d $_ ) {
109 $file = $File::Find::name;
110 if ( $file =~ /\.k?o$/ ) {
111 push(@liblist, $file);
112 warn "$file\n" if $verbose;
113 }
114 }
115}, $basedir;
116warn "**** Finished locating modules\n" if $verbose;
117
118foreach my $obj ( @liblist ){
119 # turn the input file name into a target tag name
120 my ($tgtname) = $obj =~ m-(/lib/modules/.*)$-;
121
122 warn "\nMODULE = $tgtname\n" if $verbose;
123
124 # get a list of symbols
125 my @output=`$nm $obj`;
126
127 build_ref_tables($tgtname, \@output, $exp, $dep);
128}
129
130
131# vmlinux is a special name that is only used to resolve symbols
132my $tgtname = 'vmlinux';
133my @output = $kernelsyms ? `cat $kernelsyms` : `$nm $kernel`;
134warn "\nMODULE = $tgtname\n" if $verbose;
135build_ref_tables($tgtname, \@output, $exp, $dep);
136
137# resolve the dependencies for each module
138# reduce dependencies: remove unresolvable and resolved from vmlinux/System.map
139# remove duplicates
140foreach my $module (keys %$dep) {
141 warn "reducing module: $module\n" if $verbose;
142 $mod->{$module} = {};
143 foreach (@{$dep->{$module}}) {
144 if( $exp->{$_} ) {
145 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 }
151 }
152}
153
154# 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}
170sub 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 if (length($depth) > 50) {
177 die "too much recursion (circular dependencies in modules?)";
178 }
179
180 foreach my $md (keys %{$mod->{$this_module}}) {
181 add_mod_deps ($depth, $mod, $mod2, $module, $md);
182 warn "${depth} outputting $md\n" if $verbose;
183 maybe_unshift (\@{$$mod2->{$module}}, $md);
184 }
185
186 if (!%{$mod->{$this_module}}) {
187 warn "${depth} no deps\n" if $verbose;
188 }
189}
190foreach my $module (keys %$mod) {
191 warn "filling out module: $module\n" if $verbose;
192 @{$mod2->{$module}} = ();
193 add_mod_deps ("", $mod, \$mod2, $module, $module);
194}
195
196# figure out where the output should go
197if ($stdout == 0) {
198 warn "writing $basedir/modules.dep\n" if $verbose;
199 open(STDOUT, ">$basedir/modules.dep")
200 or die "cannot open $basedir/modules.dep: $!";
201}
202my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4';
203
204foreach my $module ( keys %$mod ) {
205 if($kseries eq '2.4') {
206 print "$module:\t";
207 my @sorted = sort bydep keys %{$mod->{$module}};
208 print join(" \\\n\t",@sorted);
209 print "\n\n";
210 } else {
211 my $shortmod = $module;
212 $shortmod =~ s:^/lib/modules/[^/]*/::;
213 print "$shortmod:";
214 my @sorted = @{$mod2->{$module}};
215 printf " " if @sorted;
216 print join(" ",@sorted);
217 print "\n";
218 }
219}
220
221
222sub build_ref_tables
223{
224 my ($name, $sym_ar, $exp, $dep) = @_;
225
226 my $ksymtab = grep m/ ${symprefix}__ksymtab/, @$sym_ar;
227
228 # gather the exported symbols
229 if($ksymtab){
230 # explicitly exported
231 foreach ( @$sym_ar ) {
232 / ${symprefix}__ksymtab_(.*)$/ and do {
233 my $sym = ${symprefix} . $1;
234 warn "sym = $sym\n" if $verbose;
235 $exp->{$sym} = $name;
236 };
237 }
238 } else {
239 # exporting all symbols
240 foreach ( @$sym_ar ) {
241 / [ABCDGRSTW] (.*)$/ and do {
242 warn "syma = $1\n" if $verbose;
243 $exp->{$1} = $name;
244 };
245 }
246 }
247
248 # this takes makes sure modules with no dependencies get listed
249 push @{$dep->{$name}}, $symprefix . 'printk' unless $name eq 'vmlinux';
250
251 # gather the unresolved symbols
252 foreach ( @$sym_ar ) {
253 !/ ${symprefix}__this_module/ && / U (.*)$/ and do {
254 warn "und = $1\n" if $verbose;
255 push @{$dep->{$name}}, $1;
256 };
257 }
258}
259
260sub bydep
261{
262 foreach my $f ( keys %{$mod->{$b}} ) {
263 if($f eq $a) {
264 return 1;
265 }
266 }
267 return -1;
268}
269
270
271
272__END__
273
274=head1 NAME
275
276depmod.pl - a cross platform script to generate kernel module
277dependency lists (modules.conf) which can then be used by modprobe
278on the target platform.
279
280It supports Linux 2.4 and 2.6 styles of modules.conf (auto-detected)
281
282=head1 SYNOPSIS
283
284depmod.pl [OPTION]... [basedir]...
285
286Example:
287
288 depmod.pl -F linux/System.map -b target/lib/modules/2.6.11
289
290=head1 DESCRIPTION
291
292The purpose of this script is to automagically generate a list of of kernel
293module dependencies. This script produces dependency lists that should be
294identical to the depmod program from the modutils package. Unlike the depmod
295binary, however, depmod.pl is designed to be run on your host system, not
296on your target system.
297
298This script was written by David Schleef <ds@schleef.org> to be used in
299conjunction with the BusyBox modprobe applet.
300
301=head1 OPTIONS
302
303=over 4
304
305=item B<-h --help>
306
307This displays the help message.
308
309=item B<-b --basedir>
310
311The base directory uner which the target's modules will be found. This
312defaults to the /lib/modules directory.
313
314If you don't specify the kernel version, this script will search for
315one under the specified based directory and use the first thing that
316looks like a kernel version.
317
318=item B<-k --kernel>
319
320Kernel binary for the target (vmlinux). You must either supply a kernel binary
321or a kernel symbol file (using the -F option).
322
323=item B<-F --kernelsyms>
324
325Kernel symbol file for the target (System.map).
326
327=item B<-n --stdout>
328
329Write to stdout instead of modules.dep
330kernel binary for the target (using the -k option).
331
332=item B<--verbose>
333
334Verbose (debug) output
335
336=back
337
338=head1 COPYRIGHT AND LICENSE
339
340 Copyright (c) 2001 David Schleef <ds@schleef.org>
341 Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
342 Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
343 Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
344 Copyright (c) 2006 Freescale Semiconductor, Inc <stuarth@freescale.com>
345
346This program is free software; you can redistribute it and/or modify it
347under the same terms as Perl itself.
348
349=head1 AUTHOR
350
351David Schleef <ds@schleef.org>
352
353=cut
Note: See TracBrowser for help on using the repository browser.