blob: 93c0b3dab3b2f2b51e0f420840c0f1a7803c8c1b [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.
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;
Rob Landley9a990aa2006-06-02 21:30:40 +000028my $nm = $ENV{'NM'} || "nm";
Eric Andersenc126f8f2001-07-30 19:32:03 +000029
Rob Landleyd0498122006-03-21 16:35:50 +000030# more globals
31my (@liblist) = ();
32my $exp = {};
33my $dep = {};
34my $mod = {};
35
36my $usage = <<TXT;
37$0 -b basedir { -k <vmlinux> | -F <System.map> } [options]...
38 Where:
39 -h --help : Show this help screen
40 -b --basedir : Modules base directory (e.g /lib/modules/<2.x.y>)
41 -k --kernel : Kernel binary for the target (e.g. vmlinux)
42 -F --kernelsyms : Kernel symbol file (e.g. System.map)
43 -n --stdout : Write to stdout instead of <basedir>/modules.dep
44 -v --verbose : Print out lots of debugging stuff
45TXT
Eric Andersenc126f8f2001-07-30 19:32:03 +000046
47# get command-line options
Eric Andersenc126f8f2001-07-30 19:32:03 +000048GetOptions(
Rob Landleyd0498122006-03-21 16:35:50 +000049 "help|h" => \$help,
50 "basedir|b=s" => \$basedir,
51 "kernel|k=s" => \$kernel,
Eric Andersenc126f8f2001-07-30 19:32:03 +000052 "kernelsyms|F=s" => \$kernelsyms,
Rob Landleyd0498122006-03-21 16:35:50 +000053 "stdout|n" => \$stdout,
54 "verbose|v" => \$verbose,
Eric Andersenc126f8f2001-07-30 19:32:03 +000055);
56
Rob Landleyd0498122006-03-21 16:35:50 +000057die $usage if $help;
58die $usage unless $basedir && ( $kernel || $kernelsyms );
59die "can't use both -k and -F\n\n$usage" if $kernel && $kernelsyms;
Eric Andersenc126f8f2001-07-30 19:32:03 +000060
Rob Landleyd0498122006-03-21 16:35:50 +000061# Strip any trailing or multiple slashes from basedir
62$basedir =~ s-(/)\1+-/-g;
63
64# The base directory should contain /lib/modules somewhere
Eric Andersenc126f8f2001-07-30 19:32:03 +000065if($basedir !~ m-/lib/modules-) {
66 warn "WARNING: base directory does not match ..../lib/modules\n";
67}
68
Rob Landleyd0498122006-03-21 16:35:50 +000069# if no kernel version is contained in the basedir, try to find one
70if($basedir !~ m-/lib/modules/\d\.\d-) {
71 opendir(BD, $basedir) or die "can't open basedir $basedir : $!\n";
72 foreach ( readdir(BD) ) {
73 next if /^\.\.?$/;
74 next unless -d "$basedir/$_";
75 warn "dir = $_\n" if $verbose;
76 if( /^\d\.\d/ ) {
77 $kdir = $_;
78 warn("Guessed module directory as $basedir/$kdir\n");
79 last;
80 }
81 }
82 closedir(BD);
83 die "Cannot find a kernel version under $basedir\n" unless $kdir;
84 $basedir = "$basedir/$kdir";
85}
86
87# Find the list of .o or .ko files living under $basedir
88warn "**** Locating all modules\n" if $verbose;
Eric Andersenc7bda1c2004-03-15 08:29:22 +000089find sub {
Rob Landleyd0498122006-03-21 16:35:50 +000090 my $file;
Eric Andersenc7bda1c2004-03-15 08:29:22 +000091 if ( -f $_ && ! -d $_ ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +000092 $file = $File::Find::name;
Rob Landleyd0498122006-03-21 16:35:50 +000093 if ( $file =~ /\.k?o$/ ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +000094 push(@liblist, $file);
Rob Landleyd0498122006-03-21 16:35:50 +000095 warn "$file\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +000096 }
97 }
98}, $basedir;
Rob Landleyd0498122006-03-21 16:35:50 +000099warn "**** Finished locating modules\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000100
Rob Landleyd0498122006-03-21 16:35:50 +0000101foreach my $obj ( @liblist ){
Eric Andersenc126f8f2001-07-30 19:32:03 +0000102 # turn the input file name into a target tag name
Rob Landleyd0498122006-03-21 16:35:50 +0000103 my ($tgtname) = $obj =~ m-(/lib/modules/.*)$-;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000104
Rob Landleyd0498122006-03-21 16:35:50 +0000105 warn "\nMODULE = $tgtname\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000106
107 # get a list of symbols
Rob Landley9a990aa2006-06-02 21:30:40 +0000108 my @output=`$nm $obj`;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000109
Rob Landleyd0498122006-03-21 16:35:50 +0000110 build_ref_tables($tgtname, \@output, $exp, $dep);
Eric Andersenc126f8f2001-07-30 19:32:03 +0000111}
112
113
Rob Landleyd0498122006-03-21 16:35:50 +0000114# vmlinux is a special name that is only used to resolve symbols
115my $tgtname = 'vmlinux';
Rob Landley9a990aa2006-06-02 21:30:40 +0000116my @output = $kernelsyms ? `cat $kernelsyms` : `$nm $kernel`;
Rob Landleyd0498122006-03-21 16:35:50 +0000117warn "\nMODULE = $tgtname\n" if $verbose;
118build_ref_tables($tgtname, \@output, $exp, $dep);
119
Mike Frysingerfa6c4842006-05-26 01:48:17 +0000120# resolve the dependencies for each module
121# reduce dependencies: remove unresolvable and resolved from vmlinux/System.map
Eric Andersenc126f8f2001-07-30 19:32:03 +0000122# remove duplicates
Rob Landleyd0498122006-03-21 16:35:50 +0000123foreach my $module (keys %$dep) {
124 warn "reducing module: $module\n" if $verbose;
Eric Andersenc126f8f2001-07-30 19:32:03 +0000125 $mod->{$module} = {};
126 foreach (@{$dep->{$module}}) {
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000127 if( $exp->{$_} ) {
Eric Andersenc126f8f2001-07-30 19:32:03 +0000128 warn "resolved symbol $_ in file $exp->{$_}\n" if $verbose;
129 next if $exp->{$_} =~ /vmlinux/;
130 $mod->{$module}{$exp->{$_}} = 1;
131 } else {
132 warn "unresolved symbol $_ in file $module\n";
133 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000134 }
Eric Andersenc126f8f2001-07-30 19:32:03 +0000135}
136
Rob Landleyd0498122006-03-21 16:35:50 +0000137# figure out where the output should go
138if ($stdout == 0) {
139 open(STDOUT, ">$basedir/modules.dep")
140 or die "cannot open $basedir/modules.dep: $!";
141}
142my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4';
143
144foreach my $module ( keys %$mod ) {
145 if($kseries eq '2.4') {
146 print "$module:\t";
147 my @sorted = sort bydep keys %{$mod->{$module}};
148 print join(" \\\n\t",@sorted);
149 print "\n\n";
150 } else {
151 print "$module: ";
152 my @sorted = sort bydep keys %{$mod->{$module}};
153 print join(" ",@sorted);
154 print "\n";
155 }
Eric Andersenc126f8f2001-07-30 19:32:03 +0000156}
157
"Steven J. Hill"adb058b2002-10-08 21:33:51 +0000158
Rob Landleyd0498122006-03-21 16:35:50 +0000159sub build_ref_tables
160{
161 my ($name, $sym_ar, $exp, $dep) = @_;
162
163 my $ksymtab = grep m/ __ksymtab/, @$sym_ar;
164
165 # gather the exported symbols
166 if($ksymtab){
167 # explicitly exported
168 foreach ( @$sym_ar ) {
169 / __ksymtab_(.*)$/ and do {
170 warn "sym = $1\n" if $verbose;
171 $exp->{$1} = $name;
172 };
173 }
174 } else {
175 # exporting all symbols
176 foreach ( @$sym_ar ) {
177 / [ABCDGRST] (.*)$/ and do {
178 warn "syma = $1\n" if $verbose;
179 $exp->{$1} = $name;
180 };
181 }
182 }
183
184 # this takes makes sure modules with no dependencies get listed
185 push @{$dep->{$name}}, 'printk' unless $name eq 'vmlinux';
186
187 # gather the unresolved symbols
188 foreach ( @$sym_ar ) {
189 !/ __this_module/ && / U (.*)$/ and do {
190 warn "und = $1\n" if $verbose;
191 push @{$dep->{$name}}, $1;
192 };
193 }
194}
195
Eric Andersenc126f8f2001-07-30 19:32:03 +0000196sub bydep
197{
198 foreach my $f ( keys %{$mod->{$b}} ) {
199 if($f eq $a) {
200 return 1;
201 }
202 }
203 return -1;
204}
205
206
207
208__END__
209
210=head1 NAME
211
Rob Landleyd0498122006-03-21 16:35:50 +0000212depmod.pl - a cross platform script to generate kernel module
213dependency lists (modules.conf) which can then be used by modprobe
214on the target platform.
215
216It supports Linux 2.4 and 2.6 styles of modules.conf (auto-detected)
Eric Andersenc126f8f2001-07-30 19:32:03 +0000217
218=head1 SYNOPSIS
219
"Steven J. Hill"adb058b2002-10-08 21:33:51 +0000220depmod.pl [OPTION]... [basedir]...
Eric Andersenc126f8f2001-07-30 19:32:03 +0000221
222Example:
223
Rob Landleyd0498122006-03-21 16:35:50 +0000224 depmod.pl -F linux/System.map -b target/lib/modules/2.6.11
Eric Andersenc126f8f2001-07-30 19:32:03 +0000225
226=head1 DESCRIPTION
227
228The purpose of this script is to automagically generate a list of of kernel
Mike Frysingerfa6c4842006-05-26 01:48:17 +0000229module dependencies. This script produces dependency lists that should be
Eric Andersenc126f8f2001-07-30 19:32:03 +0000230identical to the depmod program from the modutils package. Unlike the depmod
231binary, however, depmod.pl is designed to be run on your host system, not
232on your target system.
233
234This script was written by David Schleef <ds@schleef.org> to be used in
235conjunction with the BusyBox modprobe applet.
236
237=head1 OPTIONS
238
239=over 4
240
241=item B<-h --help>
242
243This displays the help message.
244
245=item B<-b --basedir>
246
247The base directory uner which the target's modules will be found. This
Rob Landleyd0498122006-03-21 16:35:50 +0000248defaults to the /lib/modules directory.
249
250If you don't specify the kernel version, this script will search for
251one under the specified based directory and use the first thing that
252looks like a kernel version.
Eric Andersenc126f8f2001-07-30 19:32:03 +0000253
254=item B<-k --kernel>
255
Rob Landleyd0498122006-03-21 16:35:50 +0000256Kernel binary for the target (vmlinux). You must either supply a kernel binary
Eric Andersenc126f8f2001-07-30 19:32:03 +0000257or a kernel symbol file (using the -F option).
258
259=item B<-F --kernelsyms>
260
Rob Landleyd0498122006-03-21 16:35:50 +0000261Kernel symbol file for the target (System.map).
Eric Andersenc126f8f2001-07-30 19:32:03 +0000262
263=item B<-n --stdout>
264
Rob Landleyd0498122006-03-21 16:35:50 +0000265Write to stdout instead of modules.dep
Eric Andersenc126f8f2001-07-30 19:32:03 +0000266kernel binary for the target (using the -k option).
267
268=item B<--verbose>
269
Rob Landleyd0498122006-03-21 16:35:50 +0000270Verbose (debug) output
Eric Andersenc126f8f2001-07-30 19:32:03 +0000271
272=back
273
Rob Landleyd0498122006-03-21 16:35:50 +0000274=head1 COPYRIGHT AND LICENSE
Eric Andersenc126f8f2001-07-30 19:32:03 +0000275
Rob Landleyd0498122006-03-21 16:35:50 +0000276 Copyright (c) 2001 David Schleef <ds@schleef.org>
277 Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
278 Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
279 Copyright (c) 2002 Steven J. Hill <shill@broadcom.com>
280 Copyright (c) 2006 Freescale Semiconductor, Inc <stuarth@freescale.com>
281
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000282This program is free software; you can redistribute it and/or modify it
Eric Andersenc126f8f2001-07-30 19:32:03 +0000283under the same terms as Perl itself.
284
285=head1 AUTHOR
286
287David Schleef <ds@schleef.org>
288
289=cut