Commit 3e5c1f25 authored by Ryan Jackson's avatar Ryan Jackson

Remove unneeded firmware from initramfs

Once we determine which modules we need, parse the actual .ko files for
'firmware=.*' strings.  These provide the path(s) to that module's
firmware, relative to /lib/firmware.  Remove all firmware from the
output directory then copy in only the files we need.
parent 7e1cd70e
...@@ -25,26 +25,28 @@ my %aliases; ...@@ -25,26 +25,28 @@ my %aliases;
my %symbols; my %symbols;
my @order; my @order;
my @firmware;
sub parse_deps sub parse_deps
{ {
my ($module_dir) = @_; my ($module_dir) = @_;
my $depfile = "$module_dir/modules.dep"; my $depfile = "$module_dir/modules.dep";
open DEPS, $depfile || open DEPS, $depfile ||
die "Couldn't open modules.dep: $!\n"; die "Couldn't open modules.dep: $!\n";
while (<DEPS>) { while (<DEPS>) {
chomp; chomp;
my ($filename, $deplist) = /^(\S+):\s*(.*)$/; my ($filename, $deplist) = /^(\S+):\s*(.*)$/;
my $module = $filename; my $module = $filename;
$module =~ s/.*\/([^\/]+)\.ko$/$1/; $module =~ s/.*\/([^\/]+)\.ko$/$1/;
#my @d = map { s/.*\/([^\/]+)\.ko$/$1/; y/_/-/; $_ } #my @d = map { s/.*\/([^\/]+)\.ko$/$1/; y/_/-/; $_ }
my @d = map { s/.*\/([^\/]+)\.ko$/$1/; $_ } my @d = map { s/.*\/([^\/]+)\.ko$/$1/; $_ }
split(/\s+/, $deplist); split(/\s+/, $deplist);
# Normalize underscores to dashes # Normalize underscores to dashes
#$module =~ y/_/-/; #$module =~ y/_/-/;
$deps{$module} = \@d if (@d); $deps{$module} = \@d if (@d);
$files{$module} = $filename; $files{$module} = $filename;
} }
...@@ -57,7 +59,7 @@ sub parse_symbols ...@@ -57,7 +59,7 @@ sub parse_symbols
my $symfile = "$module_dir/modules.symbols"; my $symfile = "$module_dir/modules.symbols";
open SYMS, $symfile || open SYMS, $symfile ||
die "Couldn't open modules.symbols: $!\n"; die "Couldn't open modules.symbols: $!\n";
while (<SYMS>) { while (<SYMS>) {
chomp; chomp;
next if (/^#/ || /^\s*$/); next if (/^#/ || /^\s*$/);
...@@ -79,7 +81,7 @@ sub parse_aliases ...@@ -79,7 +81,7 @@ sub parse_aliases
my $aliasfile = "$module_dir/modules.alias"; my $aliasfile = "$module_dir/modules.alias";
open SYMS, $aliasfile || open SYMS, $aliasfile ||
die "Couldn't open modules.alias: $!\n"; die "Couldn't open modules.alias: $!\n";
while (<SYMS>) { while (<SYMS>) {
chomp; chomp;
next if (/^#/ || /^\s*$/); next if (/^#/ || /^\s*$/);
...@@ -100,7 +102,7 @@ sub parse_order ...@@ -100,7 +102,7 @@ sub parse_order
my $orderfile = "$module_dir/modules.order"; my $orderfile = "$module_dir/modules.order";
open ORDER, $orderfile || open ORDER, $orderfile ||
die "Couldn't open modules.order: $!\n"; die "Couldn't open modules.order: $!\n";
while (<ORDER>) { while (<ORDER>) {
chomp; chomp;
/.*\/([^\/]+)\.ko$/; /.*\/([^\/]+)\.ko$/;
...@@ -111,6 +113,21 @@ sub parse_order ...@@ -111,6 +113,21 @@ sub parse_order
close ORDER; close ORDER;
} }
sub parse_firmware
{
my ($module_file) = @_;
my @files;
open STRINGS, "strings \"$module_file\"|" or
die "Couldn't read $module_file: $!\n";
while (<STRINGS>) {
chomp;
next unless (/^firmware=(.*)$/);
push @files, $1;
}
return @files;
}
#my @modules = @ARGV; #my @modules = @ARGV;
my @modules = qw/unix sunrpc af_packet ext3 ext2 ufs/; my @modules = qw/unix sunrpc af_packet ext3 ext2 ufs/;
if (@ARGV != 3) { if (@ARGV != 3) {
...@@ -138,7 +155,9 @@ if ($? != 0) { ...@@ -138,7 +155,9 @@ if ($? != 0) {
$version = glob "$tmpdir/lib/modules/*"; $version = glob "$tmpdir/lib/modules/*";
$version = (split /\/+/, $version)[-1]; $version = (split /\/+/, $version)[-1];
$basedir = "$tmpdir/lib/modules"; $basedir = "$tmpdir/lib";
my $module_basedir = "$basedir/modules";
my $firmware_basedir = "$basedir/firmware";
open MODLIST, $modlist || die "Couldn't read $modlist: $!\n"; open MODLIST, $modlist || die "Couldn't read $modlist: $!\n";
while (<MODLIST>) { while (<MODLIST>) {
...@@ -150,30 +169,33 @@ close MODLIST; ...@@ -150,30 +169,33 @@ close MODLIST;
my @list = @modules; my @list = @modules;
parse_deps("$basedir/$version"); parse_deps("$module_basedir/$version");
parse_symbols("$basedir/$version"); parse_symbols("$module_basedir/$version");
parse_aliases("$basedir/$version"); parse_aliases("$module_basedir/$version");
while (@list) { while (@list) {
my $module = shift @list; my $module = shift @list;
#$module =~ y/_/-/; #$module =~ y/_/-/;
next if (exists $seen{$module}); next if (exists $seen{$module});
next if (not exists $files{$module}); next if (not exists $files{$module});
if (exists $deps{$module}) { if (exists $deps{$module}) {
push @list, @{$deps{$module}}; push @list, @{$deps{$module}};
} }
$seen{$module} = 1; $seen{$module} = 1;
} }
parse_order("$basedir/$version"); parse_order("$module_basedir/$version");
$outdir .= '/lib/modules/' . $version; my $module_outdir = $outdir . '/lib/modules/' . $version;
rmtree($outdir); my $firmware_outdir = $outdir . '/lib/firmware';
mkpath($outdir); rmtree($module_outdir);
rmtree($firmware_outdir);
mkpath($module_outdir);
mkpath($firmware_outdir);
open DEPS, ">$outdir/modules.dep" || die "Can't write to modules.dep: $!\n"; open DEPS, ">$module_outdir/modules.dep" || die "Can't write to modules.dep: $!\n";
#print "#modules.dep\n\n"; #print "#modules.dep\n\n";
for my $module (keys %seen) { for my $module (keys %seen) {
my @tmp = map { $files{$_} } @{$deps{$module}}; my @tmp = map { $files{$_} } @{$deps{$module}};
...@@ -181,7 +203,7 @@ for my $module (keys %seen) { ...@@ -181,7 +203,7 @@ for my $module (keys %seen) {
} }
close DEPS; close DEPS;
open SYMS, ">$outdir/modules.symbols" || die "Can't write to modules.symbols: $!\n"; open SYMS, ">$module_outdir/modules.symbols" || die "Can't write to modules.symbols: $!\n";
#print "#modules.symbols\n\n"; #print "#modules.symbols\n\n";
for my $module (keys %seen) { for my $module (keys %seen) {
for my $sym (@{$symbols{$module}}) { for my $sym (@{$symbols{$module}}) {
...@@ -190,7 +212,7 @@ for my $module (keys %seen) { ...@@ -190,7 +212,7 @@ for my $module (keys %seen) {
} }
close SYMS; close SYMS;
open ALIAS, ">$outdir/modules.alias" || die "Can't write to modules.alias: $!\n"; open ALIAS, ">$module_outdir/modules.alias" || die "Can't write to modules.alias: $!\n";
#print "#modules.aliases\n\n"; #print "#modules.aliases\n\n";
for my $module (keys %seen) { for my $module (keys %seen) {
for my $alias (@{$aliases{$module}}) { for my $alias (@{$aliases{$module}}) {
...@@ -199,7 +221,7 @@ for my $module (keys %seen) { ...@@ -199,7 +221,7 @@ for my $module (keys %seen) {
} }
close ALIAS; close ALIAS;
open ORDER, ">$outdir/modules.order" || die "Can't write to modules.order: $!\n"; open ORDER, ">$module_outdir/modules.order" || die "Can't write to modules.order: $!\n";
print ORDER "$_\n" for (@order); print ORDER "$_\n" for (@order);
close ORDER; close ORDER;
...@@ -207,7 +229,19 @@ for my $module (keys %seen) { ...@@ -207,7 +229,19 @@ for my $module (keys %seen) {
my $file = $files{$module}; my $file = $files{$module};
my $path = $file; my $path = $file;
$path =~ s/\/[^\/]+$//; $path =~ s/\/[^\/]+$//;
mkpath($outdir . '/' . $path); mkpath($module_outdir . '/' . $path);
copy("$basedir/$version/$file", "$outdir/$file"); copy("$module_basedir/$version/$file", "$module_outdir/$file");
push @firmware, parse_firmware("$module_basedir/$version/$file");
}
for my $fw (@firmware) {
my $path = $fw;
$path =~ s/\/[^\/]+$//;
mkpath($firmware_outdir . '/' . $path);
if (! -f "$firmware_basedir/$fw") {
print STDERR "WARNING: $firmware_basedir/$fw does not exist\n";
next;
}
copy("$firmware_basedir/$fw", "$firmware_outdir/$fw");
} }
rmtree($tmpdir); rmtree($tmpdir);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment