Blogposts tagged efi
f.zz.de
https://f.zz.de/tags/efi/
f.zz.de
ikiwiki
2022-03-24T14:44:54Z
Extract EFI Boot Image from iso file
https://f.zz.de/posts/202203241433.extract_efi_boot_image_from_iso_file/
Florian Lohoff
2022-03-24T14:44:54Z
2022-03-24T13:33:01Z
<p>Trying to repack Ubuntu images with addons i had the problem of extracting the EFI boot image from
the iso. There are tools like "geteltorito" which basically fail. So i quickly rolled my own with
the help of perl and sfdisk.</p>
<p>One issue is that the Ubuntu 20.04 image contains an DOS label, whereas the upcoming 22.04 contains
an GPT label. So we need to support both.</p>
<div class="sourcecode">
<!-- Generator: GNU source-highlight 3.1.8
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><tt><span class="normal">#</span><span class="symbol">!/</span><span class="normal">usr</span><span class="symbol">/</span><span class="normal">bin</span><span class="symbol">/</span><span class="normal">perl </span><span class="symbol">-</span><span class="normal">w</span>
<span class="normal">use strict</span><span class="symbol">;</span>
<span class="normal">use </span><span class="variable">Fcntl</span><span class="normal"> qw</span><span class="symbol">/</span><span class="variable">SEEK_CUR</span><span class="normal"> </span><span class="variable">O_CREAT</span><span class="normal"> </span><span class="variable">O_TRUNC</span><span class="normal"> </span><span class="variable">O_WRONLY</span><span class="normal"> </span><span class="variable">O_RDONLY</span><span class="symbol">/;</span>
<span class="normal">use </span><span class="variable">Data</span><span class="symbol">::</span><span class="variable">Dumper</span><span class="symbol">;</span>
<span class="normal">use </span><span class="variable">Capture</span><span class="symbol">::</span><span class="variable">Tiny</span><span class="normal"> qw</span><span class="symbol">/</span><span class="normal">capture</span><span class="symbol">/;</span>
<span class="normal">use </span><span class="variable">JSON</span><span class="symbol">;</span>
<span class="normal">my $image</span><span class="symbol">=</span><span class="normal">$</span><span class="variable">ARGV</span><span class="symbol">[</span><span class="number">0</span><span class="symbol">];</span>
<span class="normal">my $output</span><span class="symbol">=</span><span class="normal">$</span><span class="variable">ARGV</span><span class="symbol">[</span><span class="number">1</span><span class="symbol">];</span>
<span class="keyword">if</span><span class="normal"> </span><span class="symbol">(!</span><span class="function">defined</span><span class="symbol">(</span><span class="normal">$image</span><span class="symbol">)</span><span class="normal"> </span><span class="symbol">||</span><span class="normal"> </span><span class="symbol">!</span><span class="function">defined</span><span class="symbol">(</span><span class="normal">$output</span><span class="symbol">)</span><span class="normal"> </span><span class="symbol">||</span><span class="normal"> $image eq </span><span class="string">''</span><span class="normal"> </span><span class="symbol">||</span><span class="normal"> $output eq </span><span class="string">''</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal"> </span><span class="function">printf</span><span class="symbol">(</span><span class="string">"extractefi input.iso efi.img\n"</span><span class="symbol">);</span>
<span class="normal"> exit </span><span class="number">1</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="function">printf</span><span class="symbol">(</span><span class="string">"Using sfdisk to get partition layout\n"</span><span class="symbol">);</span>
<span class="function">my</span><span class="normal"> </span><span class="symbol">(</span><span class="normal">$stdout</span><span class="symbol">,</span><span class="normal"> $stderr</span><span class="symbol">,</span><span class="normal"> $exit</span><span class="symbol">)=</span><span class="normal">capture </span><span class="cbracket">{</span>
<span class="normal"> </span><span class="function">system</span><span class="symbol">(</span><span class="function">sprintf</span><span class="symbol">(</span><span class="string">"/usr/sbin/sfdisk -J %s"</span><span class="symbol">,</span><span class="normal"> $image</span><span class="symbol">));</span>
<span class="cbracket">}</span><span class="symbol">;</span>
<span class="keyword">if</span><span class="normal"> </span><span class="symbol">(</span><span class="normal">$exit </span><span class="symbol">!=</span><span class="normal"> </span><span class="number">0</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal"> </span><span class="function">printf</span><span class="symbol">(</span><span class="string">"Failed to execute sfdisk on image\n%s\n"</span><span class="symbol">,</span><span class="normal"> $stderr</span><span class="symbol">);</span>
<span class="normal"> exit </span><span class="number">1</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="normal">my $sf</span><span class="symbol">=</span><span class="function">from_json</span><span class="symbol">(</span><span class="normal">$stdout</span><span class="symbol">);</span>
<span class="normal">my $efipart</span><span class="symbol">;</span>
<span class="keyword">if</span><span class="normal"> </span><span class="symbol">(</span><span class="normal">$sf</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">partitiontable</span><span class="cbracket">}{</span><span class="normal">label</span><span class="cbracket">}</span><span class="normal"> eq </span><span class="string">'dos'</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal"> my @efis</span><span class="symbol">=</span><span class="normal">grep </span><span class="cbracket">{</span><span class="normal"> $</span><span class="variable">_</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">type</span><span class="cbracket">}</span><span class="normal"> eq </span><span class="string">'ef'</span><span class="normal"> </span><span class="cbracket">}</span><span class="normal"> @</span><span class="cbracket">{</span><span class="normal">$sf</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">partitiontable</span><span class="cbracket">}{</span><span class="normal">partitions</span><span class="cbracket">}}</span><span class="symbol">;</span>
<span class="normal"> $efipart</span><span class="symbol">=</span><span class="normal">shift @efis</span><span class="symbol">;</span>
<span class="cbracket">}</span><span class="normal"> </span><span class="function">elsif</span><span class="normal"> </span><span class="symbol">(</span><span class="normal">$sf</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">partitiontable</span><span class="cbracket">}{</span><span class="normal">label</span><span class="cbracket">}</span><span class="normal"> eq </span><span class="string">'gpt'</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal"> my @efis</span><span class="symbol">=</span><span class="normal">grep </span><span class="cbracket">{</span><span class="normal"> $</span><span class="variable">_</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">type</span><span class="cbracket">}</span><span class="normal"> eq </span><span class="string">'C12A7328-F81F-11D2-BA4B-00A0C93EC93B'</span><span class="normal"> </span><span class="cbracket">}</span><span class="normal"> @</span><span class="cbracket">{</span><span class="normal">$sf</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">partitiontable</span><span class="cbracket">}{</span><span class="normal">partitions</span><span class="cbracket">}}</span><span class="symbol">;</span>
<span class="normal"> $efipart</span><span class="symbol">=</span><span class="normal">shift @efis</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="keyword">if</span><span class="normal"> </span><span class="symbol">(!</span><span class="function">defined</span><span class="symbol">(</span><span class="normal">$efipart</span><span class="symbol">))</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal"> </span><span class="function">printf</span><span class="symbol">(</span><span class="string">"Could not find EFI System Partition with UUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B\n"</span><span class="symbol">);</span>
<span class="normal"> exit </span><span class="number">1</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="normal">my $start</span><span class="symbol">=</span><span class="normal">$sf</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">partitiontable</span><span class="cbracket">}{</span><span class="normal">sectorsize</span><span class="cbracket">}</span><span class="symbol">*</span><span class="normal">$efipart</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">start</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="normal">my $size</span><span class="symbol">=</span><span class="normal">$sf</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">partitiontable</span><span class="cbracket">}{</span><span class="normal">sectorsize</span><span class="cbracket">}</span><span class="symbol">*</span><span class="normal">$efipart</span><span class="symbol">-></span><span class="cbracket">{</span><span class="normal">size</span><span class="cbracket">}</span><span class="symbol">;</span>
<span class="function">printf</span><span class="symbol">(</span><span class="string">"Opening file %s to read efi image from offset %d length %d\n"</span><span class="symbol">,</span><span class="normal"> $image</span><span class="symbol">,</span><span class="normal"> $start</span><span class="symbol">,</span><span class="normal"> $size</span><span class="symbol">);</span>
<span class="normal">my $img</span><span class="symbol">;</span>
<span class="function">sysopen</span><span class="symbol">(</span><span class="normal">my $i</span><span class="symbol">,</span><span class="normal"> $image</span><span class="symbol">,</span><span class="normal"> </span><span class="variable">O_RDONLY</span><span class="symbol">);</span>
<span class="function">sysseek</span><span class="symbol">(</span><span class="normal">$i</span><span class="symbol">,</span><span class="normal"> $start</span><span class="symbol">,</span><span class="normal"> </span><span class="variable">SEEK_CUR</span><span class="symbol">);</span>
<span class="normal">my $j</span><span class="symbol">=</span><span class="function">sysread</span><span class="symbol">(</span><span class="normal">$i</span><span class="symbol">,</span><span class="normal"> $img</span><span class="symbol">,</span><span class="normal"> $size</span><span class="symbol">);</span>
<span class="keyword">if</span><span class="normal"> </span><span class="symbol">(</span><span class="normal">$j </span><span class="symbol">!=</span><span class="normal"> $size</span><span class="symbol">)</span><span class="normal"> </span><span class="cbracket">{</span>
<span class="normal"> </span><span class="function">printf</span><span class="symbol">(</span><span class="string">"Short read while trying to read EFI system partition\n"</span><span class="symbol">);</span>
<span class="normal"> exit </span><span class="number">1</span><span class="symbol">;</span>
<span class="cbracket">}</span>
<span class="function">close</span><span class="symbol">(</span><span class="normal">$i</span><span class="symbol">);</span>
<span class="function">printf</span><span class="symbol">(</span><span class="string">"Writing efi image %s size %d\n"</span><span class="symbol">,</span><span class="normal"> $output</span><span class="symbol">,</span><span class="normal"> $size</span><span class="symbol">);</span>
<span class="function">sysopen</span><span class="symbol">(</span><span class="normal">my $o</span><span class="symbol">,</span><span class="normal"> $output</span><span class="symbol">,</span><span class="normal"> </span><span class="variable">O_CREAT</span><span class="symbol">|</span><span class="variable">O_TRUNC</span><span class="symbol">|</span><span class="variable">O_WRONLY</span><span class="symbol">);</span>
<span class="function">syswrite</span><span class="symbol">(</span><span class="normal">$o</span><span class="symbol">,</span><span class="normal"> $img</span><span class="symbol">,</span><span class="normal"> $size</span><span class="symbol">);</span>
<span class="function">close</span><span class="symbol">(</span><span class="normal">$o</span><span class="symbol">);</span></tt></pre>
</div>