3 # (c) 2008-2009 Technische Universität Dresden
4 # This file is part of TUD:OS and distributed under the terms of the
5 # GNU General Public License 2.
6 # Please see the COPYING-GPL-2 file for details.
8 # Adam Lackorzynski <adam@os.inf.tu-dresden.de>
13 BEGIN { unshift @INC, $ENV{L4DIR}.'/tool/lib'
14 if $ENV{L4DIR} && -d $ENV{L4DIR}.'/tool/lib/L4';}
20 my $cross_compile_prefix = $ENV{CROSS_COMPILE} || '';
21 my $arch = $ENV{OPT_ARCH} || "x86";
23 my $module_path = $ENV{SEARCHPATH} || ".";
24 my $prog_objcopy = $ENV{OBJCOPY} || "${cross_compile_prefix}objcopy";
25 my $prog_cc = $ENV{CC} || "${cross_compile_prefix}gcc";
26 my $prog_ld = $ENV{LD} || "${cross_compile_prefix}ld";
27 my $prog_cp = $ENV{PROG_CP} || "cp";
28 my $prog_gzip = $ENV{PROG_GZIP} || "gzip";
29 my $compress = $ENV{OPT_COMPRESS} || 0;
30 my $strip = $ENV{OPT_STRIP} || 1;
32 $flags_cc = "-m32" if $arch eq 'x86';
33 $flags_cc = "-m64" if $arch eq 'amd64';
35 my $make_inc_file = $ENV{MAKE_INC_FILE} || "mod.make.inc";
37 my $modulesfile = $ARGV[1];
38 my $entryname = $ARGV[2];
42 print STDERR "$0 modulefile entry\n";
45 # Write a string to a file, overwriting it.
47 # 2..n: Strings to write to the file
52 open(A, ">$file") || die "Cannot open $file!";
61 (split /\s+/, shift)[0]
64 # build object files from the modules
67 my ($cmdline, $modname, $no_strip) = @_;
68 my $_file = first_word($cmdline);
70 my $file = L4::ModList::search_file($_file, $module_path)
71 || die "Cannot find file $_file! Used search path: $module_path";
73 printf STDERR "Merging image %s to %s\n", $file, $modname;
74 # make sure that the file isn't already compressed
75 system("$prog_gzip -dc $file > $modname.ugz 2> /dev/null");
76 $file = "$modname.ugz" if !$?;
77 system("$prog_objcopy -S $file $modname.obj 2> /dev/null")
78 if $strip && !$no_strip;
79 system("$prog_cp $file $modname.obj")
80 if $? || !$strip || $no_strip;
81 my $uncompressed_size = -s "$modname.obj";
83 my $c_unc = Digest::MD5->new;
84 open(M, "$modname.obj") || die "Failed to open $modname.obj: $!";
88 system("$prog_gzip -9f $modname.obj && mv $modname.obj.gz $modname.obj")
91 my $c_compr = Digest::MD5->new;
92 open(M, "$modname.obj") || die "Failed to open $modname.obj: $!";
93 $c_compr->addfile(*M);
96 write_to_file("$modname.extra.s",
97 ".section .rodata.module_info \n",
99 "_bin_${modname}_name: \n",
100 ".ascii \"$_file\"; .byte 0 \n",
102 "_bin_${modname}_md5sum_compr: \n",
103 ".ascii \"".$c_compr->hexdigest."\"; .byte 0\n",
105 "_bin_${modname}_md5sum_uncompr: \n",
106 ".ascii \"".$c_unc->hexdigest."\"; .byte 0 \n",
108 ".section .module_info \n",
109 ".long _binary_${modname}_start \n",
110 ".long ", (-s "$modname.obj"), " \n",
111 ".long $uncompressed_size \n",
112 ".long _bin_${modname}_name \n",
113 ".long _bin_${modname}_md5sum_compr \n",
114 ".long _bin_${modname}_md5sum_uncompr \n",
115 ($arch eq 'x86' || $arch eq 'amd64' || $arch eq 'ppc32'
116 ? #".section .module_data, \"a\", \@progbits \n" # Not Xen
117 ".section .module_data, \"awx\", \@progbits \n" # Xen
118 : ".section .module_data, #alloc \n"),
120 ".global _binary_${modname}_start \n",
121 ".global _binary_${modname}_end \n",
122 "_binary_${modname}_start: \n",
123 ".incbin \"$modname.obj\" \n",
124 "_binary_${modname}_end: \n",
126 system("$prog_cc $flags_cc -c -o $modname.bin $modname.extra.s");
127 unlink("$modname.extra.s", "$modname.obj", "$modname.ugz");
130 sub build_mbi_modules_obj(@)
135 # generate mbi module structures
136 $asm_string .= ".align 4 \n".
137 ".section .data.modules_mbi \n".
138 ".global _modules_mbi_start; \n".
139 "_modules_mbi_start: \n";
141 for (my $i = 0; $i < @mods; $i++) {
142 $asm_string .= ".long 0 \n".
144 ".long _modules_mbi_cmdline_$i \n".
148 $asm_string .= ".global _modules_mbi_end; \n".
149 "_modules_mbi_end: \n";
151 $asm_string .= ".section .data.cmdlines \n";
154 for (my $i = 0; $i < @mods; $i++) {
155 $asm_string .= "_modules_mbi_cmdline_$i: \n".
156 ".ascii \"$mods[$i]->{cmdline}\"; .byte 0; \n";
159 write_to_file("mbi_modules.s", $asm_string);
160 system("$prog_cc $flags_cc -c -o mbi_modules.bin mbi_modules.s");
161 unlink("mbi_modules.s");
168 my @mods = @{$entry{mods}};
169 my $objs = "mbi_modules.bin";
171 unlink($make_inc_file);
173 # generate module-names
174 for (my $i = 0; $i < @mods; $i++) {
175 $mods[$i]->{modname} = sprintf "mod%02d", $i;
178 build_mbi_modules_obj(@mods);
180 for (my $i = 0; $i < @mods; $i++) {
181 build_obj($mods[$i]->{cmdline}, $mods[$i]->{modname},
182 $mods[$i]->{type} =~ /.+-nostrip$/);
183 $objs .= " $mods[$i]->{modname}.bin";
186 my $make_inc_str = "MODULE_OBJECT_FILES += $objs\n";
187 $make_inc_str .= "MOD_ADDR := $entry{modaddr}"
188 if defined $entry{modaddr};
190 write_to_file($make_inc_file, $make_inc_str);
197 print join(' ', map { L4::ModList::search_file_or_die(first_word($_->{cmdline}),
199 @{$entry{mods}}), "\n";
205 print join(' ', map { $_->{cmdline} } @{$entry{mods}}), "\n";
208 # ------------------------------------------------------------------------
211 print STDERR "Error: Invalid usage!\n";
216 my %entry = L4::ModList::get_module_entry($modulesfile, $entryname);
218 if ($ARGV[0] eq 'build')
220 build_objects(%entry);
222 elsif ($ARGV[0] eq 'list')
226 elsif ($ARGV[0] eq 'dump')