3 # Originaly from: https://github.com/raspberrypi/tools/blob/master/mkimage/mkknlimg
4 # Original cset : 92a2df13b887f4799554bf92c4fc78d53668c868
9 my $trailer_magic = 'RPTL';
11 my $tmpfile1 = "/tmp/mkknlimg_$$.1";
12 my $tmpfile2 = "/tmp/mkknlimg_$$.2";
16 while ($ARGV[0] =~ /^-/)
18 my $arg = shift(@ARGV);
25 print ("* Unknown option '$arg'\n");
30 usage() if (@ARGV != 2);
32 my $kernel_file = $ARGV[0];
33 my $out_file = $ARGV[1];
35 my @wanted_config_lines =
43 'brcm,bcm2708-pinctrl',
48 my $res = try_extract($kernel_file, $tmpfile1);
50 $res = try_decompress('\037\213\010', 'xy', 'gunzip', 0,
51 $kernel_file, $tmpfile1, $tmpfile2) if (!$res);
52 $res = try_decompress('\3757zXZ\000', 'abcde', 'unxz --single-stream', -1,
53 $kernel_file, $tmpfile1, $tmpfile2) if (!$res);
54 $res = try_decompress('BZh', 'xy', 'bunzip2', 0,
55 $kernel_file, $tmpfile1, $tmpfile2) if (!$res);
56 $res = try_decompress('\135\0\0\0', 'xxx', 'unlzma', 0,
57 $kernel_file, $tmpfile1, $tmpfile2) if (!$res);
58 $res = try_decompress('\211\114\132', 'xy', 'lzop -d', 0,
59 $kernel_file, $tmpfile1, $tmpfile2) if (!$res);
66 print("Version: $res->{''}\n");
68 $append_trailer = $dtok;
71 if (config_bool($res, 'bcm2708_fb'))
73 $dtok ||= config_bool($res, 'CONFIG_BCM2708_DT');
74 $dtok ||= config_bool($res, 'brcm,bcm2708-pinctrl');
75 $dtok ||= config_bool($res, 'brcm,bcm2835-gpio');
80 print ("* This doesn't look like a Raspberry Pi kernel. In pass-through mode.\n");
86 print ("* Is this a valid kernel? In pass-through mode.\n");
91 printf("DT: %s\n", $dtok ? "y" : "n");
95 push @atoms, [ $trailer_magic, pack('V', 0) ];
96 push @atoms, [ 'KVer', $res->{''} ];
97 push @atoms, [ 'DTOK', pack('V', $dtok) ];
99 $trailer = pack_trailer(\@atoms);
100 $atoms[0]->[1] = pack('V', length($trailer));
102 $trailer = pack_trailer(\@atoms);
105 die "* Failed to open '$kernel_file'\n" if (!open(my $ifh, '<', $kernel_file));
106 die "* Failed to create '$out_file'\n" if (!open(my $ofh, '>', $out_file));
112 my $bytes = sysread($ifh, $copybuf, 64*1024);
114 syswrite($ofh, $copybuf, $bytes);
115 $total_len += $bytes;
120 # Pad to word-alignment
121 syswrite($ofh, "\x000\x000\x000", (-$total_len & 0x3));
122 syswrite($ofh, $trailer);
128 exit($trailer ? 0 : 1);
131 unlink($tmpfile1) if ($tmpfile1);
132 unlink($tmpfile2) if ($tmpfile2);
138 print ("Usage: mkknlimg [--dtok] <vmlinux|zImage|bzImage> <outfile>\n");
144 my ($knl, $tmp) = @_;
146 my $ver = `strings "$knl" | grep -a -E "^Linux version [1-9]"`;
148 return undef if (!$ver);
152 my $res = { ''=>$ver };
153 my $string_pattern = '^('.join('|', @wanted_strings).')$';
155 my @matches = `strings \"$knl\" | grep -E \"$string_pattern\"`;
156 foreach my $match (@matches)
162 my $config_pattern = '^('.join('|', @wanted_config_lines).')=(.*)$';
163 my $cf1 = 'IKCFG_ST\037\213\010';
164 my $cf2 = '0123456789';
166 my $pos = `tr "$cf1\n$cf2" "\n$cf2=" < "$knl" | grep -abo "^$cf2"`;
169 $pos =~ s/:.*[\r\n]*$//s;
171 my $err = (system("tail -c+$pos \"$knl\" | zcat > $tmp 2> /dev/null") >> 8);
172 if (($err == 0) || ($err == 2))
174 if (open(my $fh, '<', $tmp))
176 while (my $line = <$fh>)
179 $res->{$1} = $2 if ($line =~ /$config_pattern/);
193 my ($magic, $subst, $zcat, $idx, $knl, $tmp1, $tmp2) = @_;
195 my $pos = `tr "$magic\n$subst" "\n$subst=" < "$knl" | grep -abo "^$subst"`;
199 $pos = (split(/[\r\n]+/, $pos))[$idx];
200 $pos =~ s/:.*[\r\n]*$//s;
201 my $cmd = "tail -c+$pos \"$knl\" | $zcat > $tmp2 2> /dev/null";
202 my $err = (system($cmd) >> 8);
203 return undef if (($err != 0) && ($err != 2));
205 return try_extract($tmp2, $tmp1);
214 my $trailer = pack('VV', 0, 0);
215 for (my $i = $#$atoms; $i>=0; $i--)
217 my $atom = $atoms->[$i];
218 $trailer .= pack('a*x!4Va4', $atom->[1], length($atom->[1]), $atom->[0]);
225 my ($configs, $wanted) = @_;
226 return (($configs->{$wanted} eq 'y') || ($configs->{$wanted} eq '1'));