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>
10 # March 2006: Stuart Hughes <stuarth@freescale.com>.
11 # Significant updates, including implementing the '-F' option
12 # and adding support for 2.6 kernels.
14 # This program is free software; you can redistribute it and/or modify it
15 # under the same terms as Perl itself.
16 use Getopt::Long qw(:config no_auto_abbrev no_ignore_case);
20 # Set up some default values
32 my $nm = $ENV{'NM'} || "nm";
41 $0 -b basedir { -k <vmlinux> | -F <System.map> } [options]...
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
54 # get command-line options
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,
66 # ignored options (for historical usage)
73 die $usage unless $basedir && ( $kernel || $kernelsyms );
74 die "can't use both -k and -F\n\n$usage" if $kernel && $kernelsyms;
75 die "sorry, -A/--quick is not supported" if $quick;
76 die "--errsyms requires --kernelsyms" if $errsyms && !$kernelsyms;
78 # Strip any trailing or multiple slashes from basedir
81 # The base directory should contain /lib/modules somewhere
82 if($basedir !~ m-/lib/modules-) {
83 warn "WARNING: base directory does not match ..../lib/modules\n";
86 # if no kernel version is contained in the basedir, try to find one
87 if($basedir !~ m-/lib/modules/\d\.\d-) {
88 opendir(BD, $basedir) or die "can't open basedir $basedir : $!\n";
89 foreach ( readdir(BD) ) {
91 next unless -d "$basedir/$_";
92 warn "dir = $_\n" if $verbose;
95 warn("Guessed module directory as $basedir/$kdir\n");
100 die "Cannot find a kernel version under $basedir\n" unless $kdir;
101 $basedir = "$basedir/$kdir";
104 # Find the list of .o or .ko files living under $basedir
105 warn "**** Locating all modules\n" if $verbose;
108 if ( -f $_ && ! -d $_ ) {
109 $file = $File::Find::name;
110 if ( $file =~ /\.k?o$/ ) {
111 push(@liblist, $file);
112 warn "$file\n" if $verbose;
116 warn "**** Finished locating modules\n" if $verbose;
118 foreach my $obj ( @liblist ){
119 # turn the input file name into a target tag name
120 my ($tgtname) = $obj =~ m-(/lib/modules/.*)$-;
122 warn "\nMODULE = $tgtname\n" if $verbose;
124 # get a list of symbols
125 my @output=`$nm $obj`;
127 build_ref_tables($tgtname, \@output, $exp, $dep);
131 # vmlinux is a special name that is only used to resolve symbols
132 my $tgtname = 'vmlinux';
133 my @output = $kernelsyms ? `cat $kernelsyms` : `$nm $kernel`;
134 warn "\nMODULE = $tgtname\n" if $verbose;
135 build_ref_tables($tgtname, \@output, $exp, $dep);
137 # resolve the dependencies for each module
138 # reduce dependencies: remove unresolvable and resolved from vmlinux/System.map
140 foreach my $module (keys %$dep) {
141 warn "reducing module: $module\n" if $verbose;
142 $mod->{$module} = {};
143 foreach (@{$dep->{$module}}) {
145 warn "resolved symbol $_ in file $exp->{$_}\n" if $verbose;
146 next if $exp->{$_} =~ /vmlinux/;
147 $mod->{$module}{$exp->{$_}} = 1;
149 warn "unresolved symbol $_ in file $module\n";
154 # build a complete dependency list for each module and make sure it
155 # is kept in order proper order
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}) {
168 unshift (@{$array}, $ele);
170 foreach my $module (keys %$mod) {
171 warn "filling out module: $module\n" if $verbose;
172 @{$mod2->{$module}} = ();
173 foreach my $md (keys %{$mod->{$module}}) {
174 foreach my $md2 (keys %{$mod->{$md}}) {
175 warn "outputting $md2\n" if $verbose;
176 maybe_unshift (\@{$mod2->{$module}}, $md2);
178 warn "outputting $md\n" if $verbose;
179 maybe_unshift (\@{$mod2->{$module}}, $md);
183 # figure out where the output should go
185 open(STDOUT, ">$basedir/modules.dep")
186 or die "cannot open $basedir/modules.dep: $!";
188 my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4';
190 foreach my $module ( keys %$mod ) {
191 if($kseries eq '2.4') {
193 my @sorted = sort bydep keys %{$mod->{$module}};
194 print join(" \\\n\t",@sorted);
197 my $shortmod = $module;
198 $shortmod =~ s:^/lib/modules/[^/]*/::;
200 my @sorted = @{$mod2->{$module}};
201 printf " " if @sorted;
202 print join(" ",@sorted);
210 my ($name, $sym_ar, $exp, $dep) = @_;
212 my $ksymtab = grep m/ ${symprefix}__ksymtab/, @$sym_ar;
214 # gather the exported symbols
216 # explicitly exported
217 foreach ( @$sym_ar ) {
218 / ${symprefix}__ksymtab_(.*)$/ and do {
219 my $sym = ${symprefix} . $1;
220 warn "sym = $sym\n" if $verbose;
221 $exp->{$sym} = $name;
225 # exporting all symbols
226 foreach ( @$sym_ar ) {
227 / [ABCDGRSTW] (.*)$/ and do {
228 warn "syma = $1\n" if $verbose;
234 # this takes makes sure modules with no dependencies get listed
235 push @{$dep->{$name}}, $symprefix . 'printk' unless $name eq 'vmlinux';
237 # gather the unresolved symbols
238 foreach ( @$sym_ar ) {
239 !/ ${symprefix}__this_module/ && / U (.*)$/ and do {
240 warn "und = $1\n" if $verbose;
241 push @{$dep->{$name}}, $1;
248 foreach my $f ( keys %{$mod->{$b}} ) {
262 depmod.pl - a cross platform script to generate kernel module
263 dependency lists (modules.conf) which can then be used by modprobe
264 on the target platform.
266 It supports Linux 2.4 and 2.6 styles of modules.conf (auto-detected)
270 depmod.pl [OPTION]... [basedir]...
274 depmod.pl -F linux/System.map -b target/lib/modules/2.6.11
278 The purpose of this script is to automagically generate a list of of kernel
279 module dependencies. This script produces dependency lists that should be
280 identical to the depmod program from the modutils package. Unlike the depmod
281 binary, however, depmod.pl is designed to be run on your host system, not
282 on your target system.
284 This script was written by David Schleef <ds@schleef.org> to be used in
285 conjunction with the BusyBox modprobe applet.
293 This displays the help message.
295 =item B<-b --basedir>
297 The base directory uner which the target's modules will be found. This
298 defaults to the /lib/modules directory.
300 If you don't specify the kernel version, this script will search for
301 one under the specified based directory and use the first thing that
302 looks like a kernel version.
306 Kernel binary for the target (vmlinux). You must either supply a kernel binary
307 or a kernel symbol file (using the -F option).
309 =item B<-F --kernelsyms>
311 Kernel symbol file for the target (System.map).
315 Write to stdout instead of modules.dep
316 kernel binary for the target (using the -k option).
320 Verbose (debug) output
324 =head1 COPYRIGHT AND LICENSE
326 Copyright (c) 2001 David Schleef <ds@schleef.org>
327 Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
328 Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
329 Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
330 Copyright (c) 2006 Freescale Semiconductor, Inc <stuarth@freescale.com>
332 This program is free software; you can redistribute it and/or modify it
333 under the same terms as Perl itself.
337 David Schleef <ds@schleef.org>