<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>dpkg123的博客</title>
  
  <subtitle>Test Page</subtitle>
  <link href="https://dpkg123.netlify.app/atom.xml" rel="self"/>
  
  <link href="https://dpkg123.netlify.app/"/>
  <updated>2025-11-13T20:50:33.000Z</updated>
  <id>https://dpkg123.netlify.app/</id>
  
  <author>
    <name>dpkg123</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>使用gcov和perf优化代码实战</title>
    <link href="https://dpkg123.netlify.app/2025/11/14/%E4%BD%BF%E7%94%A8gcov%E5%92%8Cperf%E4%BC%98%E5%8C%96%E4%BB%A3%E7%A0%81%E5%AE%9E%E6%88%98/"/>
    <id>https://dpkg123.netlify.app/2025/11/14/%E4%BD%BF%E7%94%A8gcov%E5%92%8Cperf%E4%BC%98%E5%8C%96%E4%BB%A3%E7%A0%81%E5%AE%9E%E6%88%98/</id>
    <published>2025-11-13T20:50:33.000Z</published>
    <updated>2025-11-13T20:50:33.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="起源"><a href="#起源" class="headerlink" title="起源"></a>起源</h2><p>最近几个月除了正常的刷版号，折腾 Android Kernel 以外我还学了一点点 C 语言和比较基本的编译原理。为此我专门写了一个 BrainFuck Compiler(简称 bfc，下同)。主要是 BrainFuck(简称 bf，下同) 只有8个字符，学习起来还是比较简单的，就是有点费手。不过当我在测试 awib.bf 的时候发现在生成 C 代码时总会比其他的 bf 慢上零点几秒。我一开始考虑到可能是 awib 比较大处理比较慢的问题。</p><p>直到我在折腾如何优化内核的时候偶然了解到 pgo ，里面就提到了 gcov 这个工具。于是就开始了今天的折腾。</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>由于 gcc 自带 gcov，且不需要 lcov 这种可视化工具，所以只需要安装 perf 即可，而 perf 命令是来自 linux-tools:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo apt install linux-tools*</span><br></pre></td></tr></table></figure><h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><p>在编译的时候语言通过参数启用插桩:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -fprofile-arcs -ftest-coverage bfc.c -O0 -g3 -o bfc</span><br></pre></td></tr></table></figure><p>然后会生成 bfc.gcno 文件。</p><p>这个时候再运行一下 perf:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">$ perf record ./bfc -f tests/awib.b awub.c</span><br><span class="line">WARNING: Kernel address maps (/proc/&#123;kallsyms,modules&#125;) are restricted,</span><br><span class="line">check /proc/sys/kernel/kptr_restrict and /proc/sys/kernel/perf_event_paranoid.</span><br><span class="line"></span><br><span class="line">Samples <span class="keyword">in</span> kernel <span class="built_in">functions</span> may not be resolved <span class="keyword">if</span> a suitable vmlinux</span><br><span class="line">file is not found <span class="keyword">in</span> the buildid cache or <span class="keyword">in</span> the vmlinux path.</span><br><span class="line"></span><br><span class="line">Samples <span class="keyword">in</span> kernel modules won<span class="string">&#x27;t be resolved at all.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">If some relocation was applied (e.g. kexec) symbols may be misresolved</span></span><br><span class="line"><span class="string">even with a suitable vmlinux or kallsyms file.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">Couldn&#x27;</span>t record kernel reference relocation symbol</span><br><span class="line">Symbol resolution may be skewed <span class="keyword">if</span> relocation was used (e.g. kexec).</span><br><span class="line">Check /proc/kallsyms permission or run as root.</span><br><span class="line">[ perf record: Woken up 1 <span class="built_in">times</span> to write data ]</span><br><span class="line">[ perf record: Captured and wrote 0.012 MB perf.data (287 samples) ]</span><br></pre></td></tr></table></figure><p>此时会生成 bfc.gcda 和 perf.data<br>这个时候再运行一下:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ perf report</span><br></pre></td></tr></table></figure><p>我们得到了更详细的数据:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">71.77%  bfc      bfc                    [.] generate_c_code</span><br><span class="line"> 2.46%  bfc      bfc                    [.] optimize_arithmetic</span><br><span class="line"> 2.38%  bfc      libc.so.6              [.] _IO_file_xsputn</span><br><span class="line"> 2.05%  bfc      bfc                    [.] parse_bf_code</span><br><span class="line"> 1.28%  bfc      libc.so.6              [.] _IO_fwrite</span><br><span class="line"> 1.11%  bfc      [unknown]              [k] 0xffffffe675e9ffb8</span><br><span class="line"> 1.05%  bfc      bfc                    [.] is_copy_loop</span><br><span class="line"> 1.00%  bfc      bfc                    [.] add_instruction</span><br><span class="line"> 0.94%  bfc      [unknown]              [k] 0xffffffdb211cbe40</span><br><span class="line"> 0.87%  bfc      bfc                    [.] eliminate_dead_code</span><br><span class="line"> 0.69%  bfc      bfc                    [.] is_clear_loop</span><br><span class="line"> 0.66%  bfc      [unknown]              [k] 0xffffffdb211cbdf0</span><br><span class="line"> 0.56%  bfc      bfc                    [.] build_bracket_mapping</span><br><span class="line"> 0.54%  bfc      bfc                    [.] propagate_constants</span><br><span class="line"> 0.48%  bfc      [unknown]              [k] 0xffffffdb203e6190</span><br><span class="line"> 0.48%  bfc      libc.so.6              [.] 0x00000000000a3118</span><br></pre></td></tr></table></figure><p>这个时候我们就知道是 generate_c_code 这个函数使用了71.77% 的 cpu。</p><p>接下来使用:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ gcov bfc.c</span><br><span class="line">File <span class="string">&#x27;bfc.c&#x27;</span></span><br><span class="line">Lines executed:83.27% of 550</span><br><span class="line">Creating <span class="string">&#x27;bfc.c.gcov&#x27;</span></span><br><span class="line"></span><br><span class="line">Lines executed:83.27% of 550</span><br></pre></td></tr></table></figure><p>生成 bfc.c.gcov 查看 generate_c_code 函数中有哪些行执行了多次从而占用了大量的 cpu:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">     -:  <span class="number">670</span>:        <span class="comment">// 添加适当的缩进</span></span><br><span class="line"><span class="number">223005</span>:  <span class="number">671</span>:        <span class="keyword">for</span> (<span class="type">int</span> d = <span class="number">0</span>; d &lt; loop_depth; d++) &#123;</span><br><span class="line"><span class="number">208225</span>:  <span class="number">672</span>:            <span class="built_in">fprintf</span>(output, <span class="string">&quot;    &quot;</span>);</span><br><span class="line">     -:  <span class="number">673</span>:        &#125;</span><br></pre></td></tr></table></figure><p>这个是添加缩进，但是这个不是大头，先暂且略过</p><p>然后发现了:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">    <span class="number">1202</span>:  <span class="number">775</span>:                <span class="keyword">if</span> (loop_depth &gt; <span class="number">0</span>) &#123;</span><br><span class="line">       -:  <span class="number">776</span>:                    <span class="comment">// 查找对应的 LOOP_START 位置</span></span><br><span class="line">    <span class="number">1202</span>:  <span class="number">777</span>:                    <span class="type">int</span> end_pc = i;</span><br><span class="line">    <span class="number">1202</span>:  <span class="number">778</span>:                    <span class="type">int</span> start_pc = <span class="number">-1</span>;</span><br><span class="line"><span class="number">11045175</span>:  <span class="number">779</span>:                    <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j &lt; instr_count; j++) &#123;</span><br><span class="line"><span class="number">11045175</span>:  <span class="number">780</span>:                        <span class="keyword">if</span> (instructions[j].type == BF_LOOP_START &amp;&amp;</span><br><span class="line">  <span class="number">727682</span>:  <span class="number">781</span>:                            !instructions[j].eliminated &amp;&amp;</span><br><span class="line">  <span class="number">727682</span>:  <span class="number">782</span>:                            bracket_map[j] == end_pc) &#123;</span><br><span class="line">    <span class="number">1202</span>:  <span class="number">783</span>:                            start_pc = j;</span><br><span class="line">    <span class="number">1202</span>:  <span class="number">784</span>:                                <span class="keyword">break</span>;</span><br><span class="line">       -:  <span class="number">785</span>:                        &#125;</span><br><span class="line">       -:  <span class="number">786</span>:                    &#125;</span><br></pre></td></tr></table></figure><p>不难看出这个循环执行了 1100w 次是导致 cpu 占用过大的罪魁祸首。</p><h2 id="优化"><a href="#优化" class="headerlink" title="优化"></a>优化</h2><p>在 Brainfuck 解释器中，当执行到 <code>]</code>（循环结束）时，需要快速找到它对应的 <code>[</code>（循环开始）的位置，以便决定是否跳回循环开头。</p><p>这个 for 循环在每次遇到<code>]</code>时就遍历整个 bf 代码，而 awib 本身就是一个用 bf 写的 bf 解释器，代码量非常大。所以就出现了一个 for 循环执行了最坏的情况，即 O(n) 次。</p><p>而且我当时并不知道我事先在处理语法错误的位置的时候已经预处理了(这个还是问 llm 才得到的，我一开始并不知道，我笨，我紫菜):</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">build_bracket_mapping</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (bracket_map) <span class="built_in">free</span>(bracket_map);</span><br><span class="line">    bracket_map = <span class="built_in">calloc</span>(instr_count, <span class="keyword">sizeof</span>(<span class="type">int</span>));</span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> *<span class="built_in">stack</span> = <span class="built_in">malloc</span>(instr_count * <span class="keyword">sizeof</span>(<span class="type">int</span>));</span><br><span class="line">    <span class="type">int</span> top = <span class="number">-1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i &lt; instr_count; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (instructions[i].type == BF_LOOP_START) &#123;</span><br><span class="line">            <span class="built_in">stack</span>[++top] = i;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (instructions[i].type == BF_LOOP_END) &#123;</span><br><span class="line">            <span class="keyword">if</span> (top &lt; <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;语法错误: 多余的 ] 在位置 %d\n&quot;</span>, i);</span><br><span class="line">                <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="type">int</span> start = <span class="built_in">stack</span>[top--];</span><br><span class="line">            bracket_map[start] = i;</span><br><span class="line">            bracket_map[i] = start;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (top &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="built_in">fprintf</span>(<span class="built_in">stderr</span>, <span class="string">&quot;语法错误: 缺少 ]\n&quot;</span>);</span><br><span class="line">        <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">free</span>(<span class="built_in">stack</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>最后的解决办法就是扬掉遍历，使用预处理:</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="deletion">- int start_pc = -1;</span></span><br><span class="line"><span class="addition">+ int start_pc = bracket_map[end_pc];</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>根据 perf report 得知优化明显:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">18.56%  bfc      libc.so.6              [.] _IO_fwrite</span><br><span class="line">10.66%  bfc      bfc                    [.] generate_c_code</span><br><span class="line"> 5.32%  bfc      bfc                    [.] parse_bf_code</span><br><span class="line"> 3.88%  bfc      libc.so.6              [.] _IO_file_xsputn</span><br><span class="line"> 3.61%  bfc      [unknown]              [k] 0xffffffdb2039245c</span><br><span class="line"> 3.40%  bfc      bfc                    [.] is_copy_loop</span><br><span class="line"> 3.21%  bfc      bfc                    [.] propagate_constants</span><br><span class="line"> 3.18%  bfc      bfc                    [.] optimize_arithmetic</span><br><span class="line"> 2.60%  bfc      libc.so.6              [.] 0x00000000000a3114</span><br><span class="line"> 2.42%  bfc      libc.so.6              [.] 0x00000000000a311c</span><br><span class="line"> 2.12%  bfc      [unknown]              [k] 0xffffffe675e9ffb8</span><br></pre></td></tr></table></figure><p>查看循环次数</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1202</span>:  <span class="number">775</span>:                <span class="keyword">if</span> (loop_depth &gt; <span class="number">0</span>) &#123;</span><br><span class="line">   -:  <span class="number">776</span>:                    <span class="comment">// 查找对应的 LOOP_START 位置</span></span><br><span class="line"><span class="number">1202</span>:  <span class="number">777</span>:                    <span class="type">int</span> end_pc = i;</span><br><span class="line"><span class="number">1202</span>:  <span class="number">778</span>:                    <span class="type">int</span> start_pc = bracket_map[end_pc];</span><br><span class="line">   -:  <span class="number">779</span>:</span><br><span class="line">   -:  <span class="number">780</span>:                    <span class="comment">// 只有当循环体没有退出机制时，才插入 mem[ptr]--</span></span><br><span class="line"><span class="number">1202</span>:  <span class="number">781</span>:                    <span class="keyword">if</span> (start_pc != <span class="number">-1</span> &amp;&amp; !loop_exits_eventually(start_pc, end_pc)) &#123;</span><br><span class="line"><span class="number">4575</span>:  <span class="number">782</span>:                        <span class="keyword">for</span> (<span class="type">int</span> d = <span class="number">0</span>; d &lt; loop_depth; d++) &#123;</span><br><span class="line"><span class="number">4230</span>:  <span class="number">783</span>:                            <span class="built_in">fprintf</span>(output, <span class="string">&quot;    &quot;</span>);</span><br><span class="line">   -:  <span class="number">784</span>:                        &#125;</span><br><span class="line"> <span class="number">345</span>:  <span class="number">785</span>:                        <span class="built_in">fprintf</span>(output, <span class="string">&quot;mem[ptr]--;\n&quot;</span>);</span><br></pre></td></tr></table></figure><p>可以看到调用次数仅为 1202 次，符合预期。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="C语言" scheme="https://dpkg123.netlify.app/tags/C%E8%AF%AD%E8%A8%80/"/>
    
    <category term="优化" scheme="https://dpkg123.netlify.app/tags/%E4%BC%98%E5%8C%96/"/>
    
    <category term="gcov" scheme="https://dpkg123.netlify.app/tags/gcov/"/>
    
    <category term="perf" scheme="https://dpkg123.netlify.app/tags/perf/"/>
    
  </entry>
  
  <entry>
    <title>f2fs 二三事</title>
    <link href="https://dpkg123.netlify.app/2025/09/08/f2fs%E4%BA%8C%E4%B8%89%E4%BA%8B/"/>
    <id>https://dpkg123.netlify.app/2025/09/08/f2fs%E4%BA%8C%E4%B8%89%E4%BA%8B/</id>
    <published>2025-09-07T21:09:47.000Z</published>
    <updated>2025-09-07T21:09:47.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>F2FS(Flash Friendly File System) 是三星在 2012 年设计，2016 年大规模普及的一种较为新颖且获得了 Linux 内核支持的一种文件系统。目的是为了更好支持 NAND 一类的闪存设备。这在嵌入式设备中尤为明显。</p><p>例如，在安卓设备中，F2FS 的读写性能普遍超过了为通用块设计、未对闪存深度优化的 ext4。这也是华为 mate9 “18 个月流畅不卡”的底气所在。原因是华为工程师基于 F2FS 进行了深度优化。</p><h2 id="差异"><a href="#差异" class="headerlink" title="差异"></a>差异</h2><p>F2FS 相较于 ext4 的优缺点。</p><ul><li>更快的随机读写速度</li><li>更长的闪存寿命 </li><li>更低的碎片整理频率</li><li>更小众，目前只有安卓设备在大规模推广</li><li>更高的存储占用</li><li>更大的大文件读取波动</li></ul><p>F2FS 相较于 BTRFS 的优缺点。</p><ul><li>更快的随机读写速度</li><li>更长的闪存寿命 </li><li>更低的系统开销</li><li>更积极的 TRIM</li><li>更少的功能</li><li>更低的数据回复率</li><li>更小众，目前只有安卓设备在大规模推广</li><li>更大的大文件读取波动</li></ul><h2 id="优化"><a href="#优化" class="headerlink" title="优化"></a>优化</h2><p>WIP</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="f2fs" scheme="https://dpkg123.netlify.app/tags/f2fs/"/>
    
  </entry>
  
  <entry>
    <title>内核编译排错</title>
    <link href="https://dpkg123.netlify.app/2025/06/25/%E5%86%85%E6%A0%B8%E7%BC%96%E8%AF%91%E6%8E%92%E9%94%99/"/>
    <id>https://dpkg123.netlify.app/2025/06/25/%E5%86%85%E6%A0%B8%E7%BC%96%E8%AF%91%E6%8E%92%E9%94%99/</id>
    <published>2025-06-25T15:24:06.000Z</published>
    <updated>2025-06-25T15:24:06.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>#KernelSU# #内核比rom还重要# #内核#<br>(coolapk 不支持 Markdown ，凑活看吧.jpg)</p><p>注:<br>1.本人是小白，如有勘误请多多指教。<br>2.我会默认读者看过我上一篇文章。</p><p>context (仅供娱乐):<br>你是一个开挂大手子，听说昨天有个大佬开发了 xx 最新内核驱动能过三角洲检测。你为了带妹装逼于是就要到了文件。然后跟着 coolapk 上不计其数的编译教程开始编译，然后遇到了一堆报错，然后就没有然后了。</p><p>所以遇到编译报错要怎么办呢？删库跑路吗？不！报错不应该成为阻挡每个人求知的脚步。本文章会列出部分报错供参考。</p><p>注: 本文章会有一些旁门左道，请谨慎使用。</p><p>编译前报错<br>1.xxx not found<br>依赖没装全，解决办法用包管理器搜索相关字符串然后安装。但是有些包会没有，例如 生成 dtbo.img 时部分源码的 mkdtboimg.py 会用到 Python2. 但是软件源里没有。<br>解决办法办法： 1.用旧版本源安装，2.手动编译，3.关掉生成 dtbo 选项，只生成内核，以此类推。<br>2. .config file does noe exist<br>检查配置阶段是否配置了 O&#x3D; 变量，如果配置过了则需要添加进去。<br>3. can’t source xxx&#x2F;Kconfig<br>没有 Kconfig 文件，多出于 oplus 内核。<br>解决办法: 下载对应的 vendor kernel source 并放到指定位置。可查看 xxx 指向的链接然后调整位置。<br>4. gold linker is not supported.<br>内核不支持 gold 连接器，解决办法: 换成 bfd linker 或者 lld linker。如 LD&#x3D;ld.lld<br>5. &#x2F;usr&#x2F;bin&#x2F;ld: scripts&#x2F;dtc&#x2F;dtc-parser.tab.o:(.bss+0x50): multiple definition of &#96;yylloc’; scripts&#x2F;dtc&#x2F;dtc-lexer.lex.o:(.bss+0x0): first defined here<br>检查 本机 linker 的路径。如果认为没有问题但还是出现了这个报错的话请将 YYLTYPE yylloc 这行前面加上 extern<br>6. Kconfig: syntax error&#x2F;invaild option<br>Kconfig 语法问题，没救了，换个源码吧，<br>7. exec format error<br>多出现在 arm64 环境编译时，而对应工具使用了不同的编译架构，如 amd64<br>解决方法: 使用 box64 或者 qemu-user-static</p><p>编译时报错(指的是从 WARP 到 OBJCOPY 阶段)<br>此阶段排错方向为 编译器 &gt; 配置文件 &gt; 源码<br>当然并不是一定得遵循这个方向。这个方向只是给个参考。<br>注: 我们的目标是先解决报错，再解决启动的问题。<br>注: 少部分报错是配置阶段直接使用 defconfig 导致的<br>注: 善用 ai，不要滥用，也不要伸手。多动脑。</p><p>1.固定报错部分</p><ul><li>1.error：CROSS_COMPILE_ARM32 not defined or empty, the compat vDSO will not be built.<br>没有指定 32 位交叉编译器<br>解决办法: 1,指定一个 32 位交叉编译器。2,配置文件中关掉 CONFIG_COMPAT_VDSO</li><li>2.ld: unknown -xxx option<br>linker 不支持这个参数<br>解决办法: 1,换一个支持的 linker, 2.检查报错文件夹的 Makefile 或者 KBuild 是否有这个参数然后删掉。</li><li>3.xxx.h not found<br>没有这个头文件<br>解决办法: 使用 find 命令找到这个头文件，复制到报错目录，修改编译报错的 c 文件中出错的行(编译器会给出来)改成 “xxx.h”</li><li>4.no number named xxx<br>类没有成员变量 xxx，处理类定义之前，发现了同名的宏，在预处理阶段把类成员当成了宏作为宏的替换<br>解决方法:</li></ul><p>#ifdef xxx<br>#undef xxx<br>#endif</p><p>2.不固定报错部分</p><ul><li>1.带-Werror参数报错并给出了修正提示<br>解决方法: 1.在编译参数添加 KCFLAGS+&#x3D;”-Wno-error”.2.修改对应Makefile并在第一行添加 KCFLAGS+&#x3D;”-Wno-error” 3.按照提示修改，4.换编译器，5.配置文件关掉这个功能，6.换源码</li><li>2.-Werror参数报错但没有出了修正提示<br>解决办法同上，但第三点不适用。</li><li>3.编译错误但是错误点指向的符号<br>检查是否漏写分号，花括号等，或者换一个源码<br>3.链接部分</li><li>1.符号问题<br>多为符号未定义或者符号重定义。<br>符号未定义: 检查符号是否声明，是否定义了实现。是否在作用范围内，或者关掉对应选项<br>2.符号重定义<br>函数不匹配，检查对应函数或者头文件，如一个是 #include &lt;asm&#x2F;uaccess.h&gt; 一个是#include &lt;linyx&#x2F;uaccess.h&gt; 且都调用了相同的函数，这个时候需要吧asm改成linux，或者关掉对应选项<br>3类似于 .Section mismatch in reference from the function bootloader_log_probe() to the function .init.text:of_bootloader_log_platform_data() 这样的报错<br>一个用了 __init 一个没用，__init的意思是仅在系统启动时使用。检查函数是否启动后一直使用然后确定是否去掉或加上 __init</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="Android" scheme="https://dpkg123.netlify.app/tags/Android/"/>
    
    <category term="内核" scheme="https://dpkg123.netlify.app/tags/%E5%86%85%E6%A0%B8/"/>
    
    <category term="编译" scheme="https://dpkg123.netlify.app/tags/%E7%BC%96%E8%AF%91/"/>
    
  </entry>
  
  <entry>
    <title>关于高通gunyah虚拟化的一些研究</title>
    <link href="https://dpkg123.netlify.app/2025/03/03/%E5%85%B3%E4%BA%8E%E9%AB%98%E9%80%9Agunyah%E8%99%9A%E6%8B%9F%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E7%A0%94%E7%A9%B6/"/>
    <id>https://dpkg123.netlify.app/2025/03/03/%E5%85%B3%E4%BA%8E%E9%AB%98%E9%80%9Agunyah%E8%99%9A%E6%8B%9F%E5%8C%96%E7%9A%84%E4%B8%80%E4%BA%9B%E7%A0%94%E7%A9%B6/</id>
    <published>2025-03-03T10:08:31.000Z</published>
    <updated>2025-03-03T10:08:31.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>咕咕咕</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="虚拟化 Android" scheme="https://dpkg123.netlify.app/tags/%E8%99%9A%E6%8B%9F%E5%8C%96-Android/"/>
    
  </entry>
  
  <entry>
    <title>安卓内核编译速通</title>
    <link href="https://dpkg123.netlify.app/2025/02/13/%E5%AE%89%E5%8D%93%E5%86%85%E6%A0%B8%E7%BC%96%E8%AF%91%E9%80%9F%E9%80%9A/"/>
    <id>https://dpkg123.netlify.app/2025/02/13/%E5%AE%89%E5%8D%93%E5%86%85%E6%A0%B8%E7%BC%96%E8%AF%91%E9%80%9F%E9%80%9A/</id>
    <published>2025-02-13T09:55:21.000Z</published>
    <updated>2025-02-13T09:55:21.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>灵感来源:前几天捣鼓k9的内核偶然想到的</p><p>注:本人小白一枚，如有错误请指出</p><p>注:本文为速通文章，存在奇技淫巧，这些奇技淫巧可能会导致编译出来的内核刷入后开不开机或功耗增大等副作用</p><p>注:请确保手机已经root</p><h2 id="1-准备工作"><a href="#1-准备工作" class="headerlink" title="1.准备工作"></a>1.准备工作</h2><p>准备一个linux环境，实体机或虚拟机都行，要求4+64起步。</p><h2 id="2-安装依赖"><a href="#2-安装依赖" class="headerlink" title="2.安装依赖"></a>2.安装依赖</h2><p>运行: </p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install clang lld bison flex make pypy binutils binutils-aarch64-linux-gnu binutils-arm-linux-gnueabihf git -y</span><br><span class="line">sudo <span class="built_in">ln</span> -s /usr/bin/pypy /usr/bin/python </span><br><span class="line">sudo <span class="built_in">ln</span> -s /usr/bin/pypy /usr/bin/python2        </span><br></pre></td></tr></table></figure><p>解释:</p><ul><li>clang: c编译器，google从某一个安卓版本起使用魔改clang编译安卓内核，但是这是速通所以就不去谷歌拉巨大编译链了</li><li>lld: 连接器，跟clang一起隶属于llvm项目，是llvm的前端</li><li>bison,flex: 语法分析器，flex将.lex文件翻译成.c文件，bison将.y文件翻译成.y和.h文件:</li><li>make: 一个自动化编译工具，通过解析makefile描述的文件和规则执行编译操作</li><li>pypy: 用于执行scripts里的mkdtboimg.py生成dtbo.img，如果软件源里没有可以用python3版本的mkdtboimg.py替代</li><li>binutils:一个编译工具集合，提供例如as,ar等一系列工具，例如头图的 AR built-in.a.但是一般安装的是本机架构的binutils，对于交叉编译来说语言安装对应架构的binutils</li></ul><h2 id="3-获取源码"><a href="#3-获取源码" class="headerlink" title="3.获取源码"></a>3.获取源码</h2><p>一般在github搜索就能找到，例如:</p><p>kernel_xiaomi(小米)_sm8250(手机对应的soc代号，可以百度，例如骁龙855,860对应sm8150,骁龙845对应sdm845,骁龙835对应msm8998)</p><h2 id="4-确认手机配置文件"><a href="#4-确认手机配置文件" class="headerlink" title="4.确认手机配置文件"></a>4.确认手机配置文件</h2><p>手机有root的话直接提取&#x2F;proc&#x2F;config.gz然后解压gz文件就能获取本机配置文件扔在内核源码根目录下的arch&#x2F;arm64&#x2F;configs&#x2F;xxx_defconfig就可以了</p><h2 id="5-克隆源码"><a href="#5-克隆源码" class="headerlink" title="5.克隆源码"></a>5.克隆源码</h2><p>运行:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> 内核源码网址 --depth=1</span><br></pre></td></tr></table></figure><p>内核编译一般情况下只需要拉取一层的git提交记录就可以了。如果要多拉基层就把1改成对应的数字</p><h2 id="6-编译"><a href="#6-编译" class="headerlink" title="6.编译"></a>6.编译</h2><p>在源码根目录下执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_ARM32=arm-linux-gnuabeihf- CC=clang LD=ld.lld HOSTCC=clang HOSTLD=ld.lld O=out KCFLAGS+=-Wno-error xxx_defconfig all</span><br></pre></td></tr></table></figure><p>解释:</p><ul><li>make: 执行构建指令</li><li>ARCH&#x3D;arm64: 编译内核架构为arm64</li><li>CROSS_COMPILE: 指定交叉编译器，由于是速通使用默认binutils就可以，默认是64位，ARM32是32位</li><li>CC&#x3D;clang: 内核编译器为clang</li><li>LD&#x3D;ld.lld: 内核链接器为lld</li><li>HOSTCC&#x3D;clang: 使用本机编译器为clang，上图中的conf和dtc都是通过本机编译器而不是内核编译器来编译的</li><li>HOSTLD&#x3D;ld.lld: 使用本机编译器为ld.lld</li><li>O&#x3D;out: 构建目录为out，防止污染源码</li><li>KCFLAGS+&#x3D;-Wno-error: 在KCFLAGS里追加-Wno-error参数，绝大多数编译内核导致的错误通常都是因为kbuild默认启用了-Werror参数导致，魔改编译器习以为常的代码在原汁原味编译器上会被视为警告，而-Werror参数是默认所有警告都被当做是错误:</li></ul><p>然后就可以在arch&#x2F;arm64&#x2F;boot下找到Image开头的内核文件了。</p><p>如果还是遇到-Werror&#x3D;xxx的错误呢？</p><p>那就编辑根目录下的Makefile，删除所有带有werror的字样，然后重新编译。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="Android" scheme="https://dpkg123.netlify.app/tags/Android/"/>
    
    <category term="内核" scheme="https://dpkg123.netlify.app/tags/%E5%86%85%E6%A0%B8/"/>
    
    <category term="编译" scheme="https://dpkg123.netlify.app/tags/%E7%BC%96%E8%AF%91/"/>
    
    <category term="速通" scheme="https://dpkg123.netlify.app/tags/%E9%80%9F%E9%80%9A/"/>
    
    <category term="教程" scheme="https://dpkg123.netlify.app/tags/%E6%95%99%E7%A8%8B/"/>
    
    <category term="奇技淫巧" scheme="https://dpkg123.netlify.app/tags/%E5%A5%87%E6%8A%80%E6%B7%AB%E5%B7%A7/"/>
    
  </entry>
  
  <entry>
    <title>使用github工作流全自动构建postmarketos刷机包</title>
    <link href="https://dpkg123.netlify.app/2025/02/13/%E4%BD%BF%E7%94%A8github%E5%B7%A5%E4%BD%9C%E6%B5%81%E5%85%A8%E8%87%AA%E5%8A%A8%E6%9E%84%E5%BB%BApostmarketos%E5%88%B7%E6%9C%BA%E5%8C%85/"/>
    <id>https://dpkg123.netlify.app/2025/02/13/%E4%BD%BF%E7%94%A8github%E5%B7%A5%E4%BD%9C%E6%B5%81%E5%85%A8%E8%87%AA%E5%8A%A8%E6%9E%84%E5%BB%BApostmarketos%E5%88%B7%E6%9C%BA%E5%8C%85/</id>
    <published>2025-02-13T09:45:38.000Z</published>
    <updated>2025-02-13T09:45:38.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>前几天我在给p maports 提交 PR 的时候偶然浏览了一下 PostmarketOS 的<a href="https://build.postmarketos.org/">构建工作流</a>的配置文件的时候偶然发现了这行:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">yes</span> <span class="string">&quot;&quot;</span> | pmbootstrap --aports=<span class="variable">$PWD</span>/pmaports -q init</span><br></pre></td></tr></table></figure><p>我一直以为 yes 命令就是个不断输出 yes 的奇葩玩意儿，现在看来还可以通过管道符来实现自动输入的操作。</p><h2 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h2><p>让我们看看 pmbootstrap init 的流程:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">user@pmos-build ~&gt; pmbootstrap init</span><br><span class="line">[19:23:28] Location of the <span class="string">&#x27;work&#x27;</span> path. Multiple chroots (native, device <span class="built_in">arch</span>, device rootfs) will be created <span class="keyword">in</span> there.</span><br><span class="line">[19:23:28] Work path [/home/user/.local/var/pmbootstrap]: /home/user/pmwork</span><br><span class="line">[19:23:46] Setting up the native <span class="built_in">chroot</span> and cloning the package build recipes (pmaports)...</span><br><span class="line">[19:23:46] Clone git repository: https://gitlab.com/postmarketOS/pmaports.git</span><br><span class="line">正克隆到 <span class="string">&#x27;/home/user/pmwork/cache_git/pmaports&#x27;</span>...</span><br><span class="line">正在更新文件: 100% (6298/6298), 完成.</span><br><span class="line">[19:24:54] NOTE: pmaports path: /usr/share/pmbootstrap/aports</span><br><span class="line">[19:24:54] NOTE: you are using pmbootstrap version 1.50.1, but version 2.3.0 is required.</span><br><span class="line">[19:24:54] ERROR: Please update your pmbootstrap version (with your distribution<span class="string">&#x27;s package manager, or with pip,  depending on how you have installed it). If that is not possible, consider cloning the latest version of pmbootstrap from git.</span></span><br><span class="line"><span class="string">[19:24:54] See also: &lt;https://postmarketos.org/troubleshooting&gt;</span></span><br><span class="line"><span class="string">Run &#x27;</span>pmbootstrap <span class="built_in">log</span><span class="string">&#x27; for details.</span></span><br></pre></td></tr></table></figure><p>稳定的其中一个坏处就是软件包太老，更何况 pmbootstrap 原来是可以通过 pip 安装的:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">user@pmos-build ~&gt; pip install pmbootstrap</span><br><span class="line">error: externally-managed-environment</span><br><span class="line"></span><br><span class="line">× This environment is externally managed</span><br><span class="line">╰─&gt; To install Python packages system-wide, try apt install</span><br><span class="line">    python3-xyz, <span class="built_in">where</span> xyz is the package you are trying to</span><br><span class="line">    install.</span><br><span class="line"></span><br><span class="line">    If you wish to install a non-Debian-packaged Python package,</span><br><span class="line">    create a virtual environment using python3 -m venv path/to/venv.</span><br><span class="line">    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make</span><br><span class="line">    sure you have python3-full installed.</span><br><span class="line"></span><br><span class="line">    If you wish to install a non-Debian packaged Python application,</span><br><span class="line">    it may be easiest to use pipx install xyz, <span class="built_in">which</span> will manage a</span><br><span class="line">    virtual environment <span class="keyword">for</span> you. Make sure you have pipx installed.</span><br><span class="line"></span><br><span class="line">    See /usr/share/doc/python3.11/README.venv <span class="keyword">for</span> more information.</span><br><span class="line"></span><br><span class="line">note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.</span><br><span class="line">hint: See PEP 668 <span class="keyword">for</span> the detailed specification.</span><br></pre></td></tr></table></figure><p>虽然可以用 pipx 这样的方式来解决，但是我试过不知道为什么装不了。</p><p>或者直接克隆最新的 pmbootstrap 然后复制到 &#x2F;usr&#x2F;local&#x2F;bin 里。</p><p>我一直认为 pmbootstrap 初始化后应该会保存配置的。因为你再执行一遍 pmbootstrap 的时候会显示你第一次配置过的选项。</p><p>然后我就在折腾管道符的时候知道了 –details-to-stdout 选项:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">$ ~&gt; <span class="built_in">printf</span> <span class="string">&quot;%s\n&quot;</span> <span class="string">&quot;edge&quot;</span> <span class="string">&quot;xiaomi&quot;</span> <span class="string">&quot;raphael&quot;</span> <span class="string">&quot;user&quot;</span> <span class="string">&quot;xfce4&quot;</span> <span class="string">&quot;n&quot;</span> <span class="string">&quot;none&quot;</span> <span class="string">&quot;en_US&quot;</span> <span class="string">&quot;xiaomi-raphael&quot;</span> <span class="string">&quot;y&quot;</span> | ./pmbootstrap/pmbootstrap.py -q init</span><br><span class="line">[09:08:51] Location of the <span class="string">&#x27;work&#x27;</span> path. Multiple chroots (native, device <span class="built_in">arch</span>, device rootfs) will be created <span class="keyword">in</span> there.</span><br><span class="line">[09:08:51] Setting up the native <span class="built_in">chroot</span> and cloning the package build recipes (pmaports)...</span><br><span class="line">[09:08:51] Clone git repository: https://gitlab.com/postmarketOS/pmaports.git</span><br><span class="line">[09:08:49] Channel [edge]: [09:08:49] Vendor [qemu]: [09:08:49] Device codename [amd64]: [09:08:49] Kernel [lts]: [09:08:49] Username [user]: [09:08:49] Provider [default]: [09:08:50] User interface [console]: [09:08:50] Change them? (y/n) [n]: [09:08:50] Extra packages [none]: [09:08:50] Use this timezone instead of GMT? (y/n) [y]: [09:08:50] Locale [en_US]: [09:08:50] Device hostname (short form, e.g. <span class="string">&#x27;foo&#x27;</span>) [qemu-amd64]: [09:08:50] Build outdated packages during <span class="string">&#x27;pmbootstrap install&#x27;</span>? (y/n) [y]: [09:08:51] Work path [/home/runner/.local/var/pmbootstrap]: Cloning into <span class="string">&#x27;/home/runner/work/repo/repo/edge/cache_git/pmaports&#x27;</span>...</span><br><span class="line">[09:08:56] Choose the postmarketOS release channel.</span><br><span class="line">[09:08:56] Available (10):</span><br><span class="line">[09:08:56] * edge: Rolling release / Most devices / Occasional breakage: https://postmarketos.org/edge</span><br><span class="line">[09:08:56] * v24.06: Latest release / Recommended <span class="keyword">for</span> best stability</span><br><span class="line">[09:08:56] * v23.12: Old release (unsupported)</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: Invalid channel specified, please <span class="built_in">type</span> <span class="keyword">in</span> one from the list above.</span><br><span class="line">[09:08:56] ERROR: EOF when reading a line</span><br><span class="line">[09:08:56] See also: &lt;https://postmarketos.org/troubleshooting&gt;</span><br><span class="line">[09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: [09:08:56] Channel [edge]: </span><br><span class="line">Run <span class="string">&#x27;pmbootstrap log&#x27;</span> <span class="keyword">for</span> details.</span><br><span class="line"></span><br><span class="line">Before you report this error, ensure that pmbootstrap is up to <span class="built_in">date</span>.</span><br><span class="line">Find the latest version here: https://gitlab.com/postmarketOS/pmbootstrap/-/tags</span><br><span class="line">Your version: 3.0.0_alpha</span><br></pre></td></tr></table></figure><p>然后使用 –details-to-stdout 选项运行:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[05:20:52] Pmbootstrap v3.0.0_alpha (Python 3.10.12 (main, Jul 29 2024, 16:56:48) [GCC 11.4.0])</span><br><span class="line">[05:20:52] $ pmbootstrap ./pmbootstrap/pmbootstrap.py --details-to-stdout init</span><br><span class="line">[05:20:52] Location of the <span class="string">&#x27;work&#x27;</span> path. Multiple chroots (native, device <span class="built_in">arch</span>, device rootfs) will be created <span class="keyword">in</span> there.</span><br><span class="line">[05:20:52] Work path [/home/runner/.local/var/pmbootstrap]: [05:20:52] Work path [/home/runner/.local/var/pmbootstrap]: /home/runner/.local/var/pmbootstrap</span><br><span class="line">[05:20:52] Save config: /home/runner/.config/pmbootstrap_v3.cfg</span><br></pre></td></tr></table></figure><p>然后就找到了配置文件:</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[pmbootstrap]</span></span><br><span class="line"><span class="attr">aports</span> = /home/pmos/.local/var/pmbootstrap/cache_git/pmaports</span><br><span class="line"><span class="attr">device</span> = xiaomi-raphael</span><br><span class="line"><span class="attr">is_default_channel</span> = <span class="literal">False</span></span><br><span class="line"><span class="attr">timezone</span> = Asia/Shanghai</span><br><span class="line"><span class="attr">ui</span> = xfce4</span><br><span class="line"><span class="attr">work</span> = /home/pmos/.local/var/pmbootstrap</span><br><span class="line"></span><br><span class="line"><span class="section">[providers]</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mirrors]</span></span><br></pre></td></tr></table></figure><p>于是就有了一个大胆的想法:</p><p>我们可以先把配置文件放到指定目录然后再使用 yes 管道符进行全自动确认:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Initialize</span> <span class="string">pmbootstrap</span></span><br><span class="line">  <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">     sudo aria2c  https://github.com/username/repo/raw/main/pmbootstrap_v3.cfg</span></span><br><span class="line"><span class="string">     sudo mv pmbootstrap_v3.cfg -v /home/runner/.config/pmbootstrap_v3.cfg</span></span><br><span class="line"><span class="string">     sudo chmod 777 -v /home/runner/.config/pmbootstrap_v3.cfg</span></span><br><span class="line"><span class="string">     yes &#x27;&#x27; | ./pmbootstrap/pmbootstrap.py --details-to-stdout init</span></span><br></pre></td></tr></table></figure><p>当然这种对于新设备来说是不使用的。</p><p>不过我们可以使用下面的方法进行初始化:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Initialize</span> <span class="string">pmbootstrap</span></span><br><span class="line">  <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">     sudo chmod 777 -v /home/runner/.config/pmbootstrap_v3.cfg</span></span><br><span class="line"><span class="string">     yes &#x27;&#x27; | ./pmbootstrap/pmbootstrap.py --details-to-stdout init</span></span><br><span class="line"><span class="string">     sudo aria2c  https://github.com/username/repo/raw/main/pmbootstrap_v3.cfg</span></span><br><span class="line"><span class="string">     sudo mv pmbootstrap_v3.cfg -v /home/runner/.config/pmbootstrap_v3.cfg</span></span><br><span class="line"><span class="string">     mv *-xiaomi-raphael /home/pmos/.local/var/pmbootstrap/cache_git/pmaports/device/testing/ #假设已经通过 checkout 拉取了 pmos 的设备树</span></span><br><span class="line"><span class="string">     yes &#x27;&#x27; | ./pmbootstrap/pmbootstrap.py --details-to-stdout init</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="手机" scheme="https://dpkg123.netlify.app/tags/%E6%89%8B%E6%9C%BA/"/>
    
    <category term="刷机" scheme="https://dpkg123.netlify.app/tags/%E5%88%B7%E6%9C%BA/"/>
    
    <category term="Android" scheme="https://dpkg123.netlify.app/tags/Android/"/>
    
    <category term="Root" scheme="https://dpkg123.netlify.app/tags/Root/"/>
    
    <category term="Github" scheme="https://dpkg123.netlify.app/tags/Github/"/>
    
    <category term="CI" scheme="https://dpkg123.netlify.app/tags/CI/"/>
    
    <category term="Linux" scheme="https://dpkg123.netlify.app/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>PostmarketOS移植常见问题</title>
    <link href="https://dpkg123.netlify.app/2024/08/12/PostmarketOS%E7%A7%BB%E6%A4%8D%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/"/>
    <id>https://dpkg123.netlify.app/2024/08/12/PostmarketOS%E7%A7%BB%E6%A4%8D%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/</id>
    <published>2024-08-12T10:10:55.000Z</published>
    <updated>2024-08-12T10:10:55.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>这篇文章简单介绍下我移植k20pro-PostmarketOS出现的问题以及解决方法</p><p>移植教程可以参考<a href="https://ivonblog.com/posts/xperia5-ii-postmarketos-porting/">这篇文章</a></p><p>注:以下问题需要执行<code>pmbootstrap log</code>才能找到，或者在pmbootstrap的工作目录里的<code>log.txt</code>里找到</p><p>建议编译内核前先删除pmbootstrap的工作目录里的<code>log.txt</code></p><h1 id="问题1-xxx-patch无法打补丁"><a href="#问题1-xxx-patch无法打补丁" class="headerlink" title="问题1: xxx patch无法打补丁"></a>问题1: xxx patch无法打补丁</h1><p>这个问题出现在执行<code>pmbootstrap kconfig edit</code>时</p><p>解决办法:</p><p>在<code>linux-xiaomi-raphael/APKBUILD</code>中删除所有.patch字样</p><h1 id="问题2-asm-type-h-no-such-file-or-directory"><a href="#问题2-asm-type-h-no-such-file-or-directory" class="headerlink" title="问题2: asm&#x2F;type.h :no such file or directory"></a>问题2: asm&#x2F;type.h :no such file or directory</h1><p>这个问题出现在执行<code>pmbootstrap build linux-xiaomi-raphael</code>时</p><p>解决办法:</p><p>执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ pmbootstrap <span class="built_in">chroot</span></span><br><span class="line">$ apk add linux-headers </span><br><span class="line"><span class="comment">#注:第二条命令需要在第一条命令执行成功后再执行</span></span><br></pre></td></tr></table></figure><h1 id="问题3-gzip-cpio-command-not-found"><a href="#问题3-gzip-cpio-command-not-found" class="headerlink" title="问题3: gzip(cpio) command not found"></a>问题3: gzip(cpio) command not found</h1><p>同上</p><p>解决办法:</p><p>将上面的<code>linux-headers</code>换成gzip(cpio)</p><h1 id="问题4-c语言错误"><a href="#问题4-c语言错误" class="headerlink" title="问题4 c语言错误"></a>问题4 c语言错误</h1><p>同上</p><p>解决办法:</p><p>如果你是c语言大佬，可以试试修复</p><p>否则尝逝更换编译器为<code>clang</code></p><p>在<code>linux-xiaomi-raphael/APKBUILD</code>中添加以下字段</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">CC=&quot;clang&quot;</span><br><span class="line">HOSTCC=&quot;clang&quot;</span><br></pre></td></tr></table></figure><p>或者使用gcc6&#x2F;gcc4(仅限老旧手机)</p><p>在<code>linux-xiaomi-raphael/APKBUILD</code>中添加以下字段</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># Compiler: GCC 6 (doesn&#x27;t boot when compiled with newer versions)</span><br><span class="line">if [ &quot;$&#123;CC:0:5&#125;&quot; != &quot;gcc6-&quot; ]; then</span><br><span class="line">CC=&quot;gcc6-$CC&quot;</span><br><span class="line">HOSTCC=&quot;gcc6-gcc&quot;</span><br><span class="line">CROSS_COMPILE=&quot;gcc6-$CROSS_COMPILE&quot;</span><br><span class="line">fi</span><br></pre></td></tr></table></figure><p>如果要使用gcc4,请将上面字段的6改成4</p><p>如果还是不行的话，建议更换一个问题较少的内核<del>这里着重点名小米，官方内核就是一坨shit</del></p><h1 id="问题5-Permission-denied"><a href="#问题5-Permission-denied" class="headerlink" title="问题5: Permission denied"></a>问题5: Permission denied</h1><p>这个问题可能出现在执行<code>pmbootstrap build linux-xiaomi-raphael</code>或者<code>pmbootstrap install</code>的时候</p><p>解决办法:</p><p>换个目录并将目录权限设置成<code>755</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">chmod</span> 755 $(pmbootstrap_work_dir)</span><br></pre></td></tr></table></figure><h1 id="问题6-xxx-h-no-such-file-or-directory"><a href="#问题6-xxx-h-no-such-file-or-directory" class="headerlink" title="问题6: xxx.h no such file or directory"></a>问题6: xxx.h no such file or directory</h1><p>这个问题出现在执行<code>pmbootstrap build linux-xiaomi-raphael</code>时，且问题多出自与小米官方内核<del>雷军，金凡！</del></p><p>解决办法:</p><p>使用find命令找到缺失的文件然后将文件复制到报错的文件的目录中</p><h1 id="问题7-include-linux-compiler-gcc-h-2-2-error-error-“Please-don’t-include-directly-include-instead-”"><a href="#问题7-include-linux-compiler-gcc-h-2-2-error-error-“Please-don’t-include-directly-include-instead-”" class="headerlink" title="问题7:..&#x2F;include&#x2F;linux&#x2F;compiler-gcc.h:2:2: error: #error “Please don’t include &lt;linux&#x2F;compiler-gcc.h&gt; directly, include &lt;linux&#x2F;compiler.h&gt; instead.”"></a>问题7:..&#x2F;include&#x2F;linux&#x2F;compiler-gcc.h:2:2: error: #error “Please don’t include &lt;linux&#x2F;compiler-gcc.h&gt; directly, include &lt;linux&#x2F;compiler.h&gt; instead.”</h1><p>同上</p><p>解决办法:</p><p>将<code>APKBUILD</code>中的</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">prepare() &#123;</span><br><span class="line">default_prepare</span><br><span class="line">. downstreamkernel_prepare</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>换成</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">prepare() &#123;</span><br><span class="line">default_prepare</span><br><span class="line">REPLACE_GCCH=0</span><br><span class="line">. downstreamkernel_prepare</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="问题8-losetup-home-pmos-rootfs-xiaomi-raphael-img-failed-to-set-up-loop-device-no-such-file-or-directory"><a href="#问题8-losetup-home-pmos-rootfs-xiaomi-raphael-img-failed-to-set-up-loop-device-no-such-file-or-directory" class="headerlink" title="问题8: losetup: &#x2F;home&#x2F;pmos&#x2F;rootfs&#x2F;xiaomi-raphael.img: failed to set up loop device: no such file or directory"></a>问题8: losetup: &#x2F;home&#x2F;pmos&#x2F;rootfs&#x2F;xiaomi-raphael.img: failed to set up loop device: no such file or directory</h1><p>这个问题出现在执行<code>pmbootstrap indtall</code>时</p><p>解决办法:</p><p>在后面添加<code>--android-recovery-zip</code>，只构建卡刷包</p><h1 id="问题9-deviceinfo-missing-dtb"><a href="#问题9-deviceinfo-missing-dtb" class="headerlink" title="问题9: deviceinfo: missing dtb"></a>问题9: deviceinfo: missing dtb</h1><p>同上</p><p>解决办法: 在<code>deviceinfo中</code>的<code>deviceinfo_dtb</code>选项中添加编译好的dtb路径，一般添加在<code>$pkgdir/boot/dtbs/</code>中:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">deviceinfo_format_version=&quot;0&quot;</span><br><span class="line">deviceinfo_name=&quot;Xiaomi Redmi K20 Pro&quot;</span><br><span class="line">deviceinfo_manufacturer=&quot;Xiaomi&quot;</span><br><span class="line">deviceinfo_codename=&quot;xiaomi-raphael&quot;</span><br><span class="line">deviceinfo_year=&quot;2019&quot;</span><br><span class="line">deviceinfo_dtb=&quot;qcom/sm8150-xiaomi-raphael&quot;</span><br><span class="line">deviceinfo_modules_initfs=&quot;gpi i2c_qcom_geni goodix_i2c qcom_pmi8998_charger qcom_fg&quot;</span><br><span class="line">deviceinfo_arch=&quot;aarch64&quot;</span><br></pre></td></tr></table></figure><h1 id="问题10-python2-command-not-found"><a href="#问题10-python2-command-not-found" class="headerlink" title="问题10: python2: command not found"></a>问题10: python2: command not found</h1><p>出现在mkdtboimg中。而且从Alpine3.16开始就不再提供。</p><p>解决办法:</p><p>1.切换版本到v20.06(不推荐)</p><p>2.修改源码，可以参考以下patch:</p><figure class="highlight diff"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br><span class="line">574</span><br><span class="line">575</span><br><span class="line">576</span><br><span class="line">577</span><br><span class="line">578</span><br><span class="line">579</span><br><span class="line">580</span><br><span class="line">581</span><br><span class="line">582</span><br><span class="line">583</span><br><span class="line">584</span><br><span class="line">585</span><br><span class="line">586</span><br><span class="line">587</span><br><span class="line">588</span><br><span class="line">589</span><br><span class="line">590</span><br><span class="line">591</span><br><span class="line">592</span><br><span class="line">593</span><br><span class="line">594</span><br><span class="line">595</span><br><span class="line">596</span><br><span class="line">597</span><br><span class="line">598</span><br><span class="line">599</span><br><span class="line">600</span><br><span class="line">601</span><br><span class="line">602</span><br><span class="line">603</span><br><span class="line">604</span><br><span class="line">605</span><br><span class="line">606</span><br><span class="line">607</span><br><span class="line">608</span><br><span class="line">609</span><br><span class="line">610</span><br><span class="line">611</span><br><span class="line">612</span><br><span class="line">613</span><br><span class="line">614</span><br><span class="line">615</span><br><span class="line">616</span><br><span class="line">617</span><br><span class="line">618</span><br><span class="line">619</span><br><span class="line">620</span><br><span class="line">621</span><br><span class="line">622</span><br><span class="line">623</span><br><span class="line">624</span><br><span class="line">625</span><br><span class="line">626</span><br><span class="line">627</span><br><span class="line">628</span><br><span class="line">629</span><br><span class="line">630</span><br><span class="line">631</span><br><span class="line">632</span><br><span class="line">633</span><br><span class="line">634</span><br><span class="line">635</span><br><span class="line">636</span><br><span class="line">637</span><br><span class="line">638</span><br><span class="line">639</span><br><span class="line">640</span><br><span class="line">641</span><br><span class="line">642</span><br><span class="line">643</span><br><span class="line">644</span><br><span class="line">645</span><br><span class="line">646</span><br><span class="line">647</span><br><span class="line">648</span><br><span class="line">649</span><br><span class="line">650</span><br><span class="line">651</span><br><span class="line">652</span><br><span class="line">653</span><br><span class="line">654</span><br><span class="line">655</span><br><span class="line">656</span><br><span class="line">657</span><br><span class="line">658</span><br><span class="line">659</span><br><span class="line">660</span><br><span class="line">661</span><br><span class="line">662</span><br><span class="line">663</span><br><span class="line">664</span><br><span class="line">665</span><br><span class="line">666</span><br><span class="line">667</span><br><span class="line">668</span><br><span class="line">669</span><br><span class="line">670</span><br><span class="line">671</span><br><span class="line">672</span><br><span class="line">673</span><br><span class="line">674</span><br><span class="line">675</span><br><span class="line">676</span><br><span class="line">677</span><br><span class="line">678</span><br><span class="line">679</span><br><span class="line">680</span><br><span class="line">681</span><br><span class="line">682</span><br><span class="line">683</span><br><span class="line">684</span><br><span class="line">685</span><br><span class="line">686</span><br><span class="line">687</span><br><span class="line">688</span><br><span class="line">689</span><br><span class="line">690</span><br><span class="line">691</span><br><span class="line">692</span><br><span class="line">693</span><br><span class="line">694</span><br><span class="line">695</span><br><span class="line">696</span><br><span class="line">697</span><br><span class="line">698</span><br><span class="line">699</span><br><span class="line">700</span><br><span class="line">701</span><br><span class="line">702</span><br><span class="line">703</span><br><span class="line">704</span><br><span class="line">705</span><br><span class="line">706</span><br><span class="line">707</span><br><span class="line">708</span><br><span class="line">709</span><br><span class="line">710</span><br><span class="line">711</span><br><span class="line">712</span><br><span class="line">713</span><br><span class="line">714</span><br><span class="line">715</span><br><span class="line">716</span><br><span class="line">717</span><br><span class="line">718</span><br><span class="line">719</span><br><span class="line">720</span><br><span class="line">721</span><br><span class="line">722</span><br><span class="line">723</span><br><span class="line">724</span><br><span class="line">725</span><br><span class="line">726</span><br><span class="line">727</span><br><span class="line">728</span><br><span class="line">729</span><br><span class="line">730</span><br><span class="line">731</span><br><span class="line">732</span><br><span class="line">733</span><br><span class="line">734</span><br><span class="line">735</span><br><span class="line">736</span><br><span class="line">737</span><br><span class="line">738</span><br><span class="line">739</span><br><span class="line">740</span><br><span class="line">741</span><br><span class="line">742</span><br><span class="line">743</span><br><span class="line">744</span><br><span class="line">745</span><br><span class="line">746</span><br><span class="line">747</span><br><span class="line">748</span><br><span class="line">749</span><br><span class="line">750</span><br><span class="line">751</span><br><span class="line">752</span><br><span class="line">753</span><br><span class="line">754</span><br><span class="line">755</span><br><span class="line">756</span><br><span class="line">757</span><br><span class="line">758</span><br><span class="line">759</span><br><span class="line">760</span><br><span class="line">761</span><br><span class="line">762</span><br><span class="line">763</span><br><span class="line">764</span><br><span class="line">765</span><br><span class="line">766</span><br><span class="line">767</span><br><span class="line">768</span><br><span class="line">769</span><br><span class="line">770</span><br><span class="line">771</span><br><span class="line">772</span><br><span class="line">773</span><br><span class="line">774</span><br><span class="line">775</span><br><span class="line">776</span><br><span class="line">777</span><br><span class="line">778</span><br><span class="line">779</span><br><span class="line">780</span><br><span class="line">781</span><br><span class="line">782</span><br><span class="line">783</span><br><span class="line">784</span><br><span class="line">785</span><br><span class="line">786</span><br><span class="line">787</span><br><span class="line">788</span><br><span class="line">789</span><br><span class="line">790</span><br><span class="line">791</span><br><span class="line">792</span><br><span class="line">793</span><br><span class="line">794</span><br><span class="line">795</span><br><span class="line">796</span><br><span class="line">797</span><br><span class="line">798</span><br><span class="line">799</span><br><span class="line">800</span><br><span class="line">801</span><br><span class="line">802</span><br><span class="line">803</span><br><span class="line">804</span><br><span class="line">805</span><br><span class="line">806</span><br><span class="line">807</span><br><span class="line">808</span><br><span class="line">809</span><br><span class="line">810</span><br><span class="line">811</span><br><span class="line">812</span><br><span class="line">813</span><br><span class="line">814</span><br><span class="line">815</span><br><span class="line">816</span><br><span class="line">817</span><br><span class="line">818</span><br><span class="line">819</span><br><span class="line">820</span><br><span class="line">821</span><br><span class="line">822</span><br><span class="line">823</span><br><span class="line">824</span><br><span class="line">825</span><br><span class="line">826</span><br><span class="line">827</span><br><span class="line">828</span><br><span class="line">829</span><br><span class="line">830</span><br><span class="line">831</span><br><span class="line">832</span><br><span class="line">833</span><br><span class="line">834</span><br><span class="line">835</span><br><span class="line">836</span><br><span class="line">837</span><br><span class="line">838</span><br><span class="line">839</span><br><span class="line">840</span><br><span class="line">841</span><br><span class="line">842</span><br><span class="line">843</span><br><span class="line">844</span><br><span class="line">845</span><br><span class="line">846</span><br><span class="line">847</span><br><span class="line">848</span><br><span class="line">849</span><br><span class="line">850</span><br><span class="line">851</span><br><span class="line">852</span><br><span class="line">853</span><br><span class="line">854</span><br><span class="line">855</span><br><span class="line">856</span><br><span class="line">857</span><br><span class="line">858</span><br><span class="line">859</span><br><span class="line">860</span><br><span class="line">861</span><br><span class="line">862</span><br><span class="line">863</span><br><span class="line">864</span><br><span class="line">865</span><br><span class="line">866</span><br><span class="line">867</span><br><span class="line">868</span><br><span class="line">869</span><br><span class="line">870</span><br><span class="line">871</span><br><span class="line">872</span><br><span class="line">873</span><br><span class="line">874</span><br><span class="line">875</span><br><span class="line">876</span><br><span class="line">877</span><br><span class="line">878</span><br><span class="line">879</span><br><span class="line">880</span><br><span class="line">881</span><br><span class="line">882</span><br><span class="line">883</span><br><span class="line">884</span><br><span class="line">885</span><br><span class="line">886</span><br><span class="line">887</span><br><span class="line">888</span><br><span class="line">889</span><br><span class="line">890</span><br><span class="line">891</span><br><span class="line">892</span><br><span class="line">893</span><br><span class="line">894</span><br><span class="line">895</span><br><span class="line">896</span><br><span class="line">897</span><br><span class="line">898</span><br><span class="line">899</span><br><span class="line">900</span><br><span class="line">901</span><br><span class="line">902</span><br><span class="line">903</span><br><span class="line">904</span><br><span class="line">905</span><br><span class="line">906</span><br><span class="line">907</span><br><span class="line">908</span><br><span class="line">909</span><br><span class="line">910</span><br><span class="line">911</span><br><span class="line">912</span><br><span class="line">913</span><br><span class="line">914</span><br><span class="line">915</span><br><span class="line">916</span><br><span class="line">917</span><br><span class="line">918</span><br><span class="line">919</span><br><span class="line">920</span><br><span class="line">921</span><br><span class="line">922</span><br><span class="line">923</span><br><span class="line">924</span><br><span class="line">925</span><br><span class="line">926</span><br><span class="line">927</span><br><span class="line">928</span><br><span class="line">929</span><br><span class="line">930</span><br><span class="line">931</span><br><span class="line">932</span><br><span class="line">933</span><br><span class="line">934</span><br><span class="line">935</span><br><span class="line">936</span><br><span class="line">937</span><br><span class="line">938</span><br><span class="line">939</span><br><span class="line">940</span><br><span class="line">941</span><br><span class="line">942</span><br><span class="line">943</span><br><span class="line">944</span><br><span class="line">945</span><br><span class="line">946</span><br><span class="line">947</span><br><span class="line">948</span><br><span class="line">949</span><br><span class="line">950</span><br><span class="line">951</span><br><span class="line">952</span><br><span class="line">953</span><br><span class="line">954</span><br><span class="line">955</span><br><span class="line">956</span><br><span class="line">957</span><br><span class="line">958</span><br><span class="line">959</span><br><span class="line">960</span><br><span class="line">961</span><br><span class="line">962</span><br><span class="line">963</span><br><span class="line">964</span><br><span class="line">965</span><br><span class="line">966</span><br><span class="line">967</span><br><span class="line">968</span><br><span class="line">969</span><br><span class="line">970</span><br><span class="line">971</span><br><span class="line">972</span><br><span class="line">973</span><br><span class="line">974</span><br><span class="line">975</span><br><span class="line">976</span><br></pre></td><td class="code"><pre><span class="line">From 88cdbae9030bea8e6a7233af3b4adf0d62930498 Mon Sep 17 00:00:00 2001</span><br><span class="line">From: dabao1955 &lt;dabao1955@163.com&gt;</span><br><span class="line">Date: Tue, 6 Aug 2024 20:53:07 +0800</span><br><span class="line">Subject: [PATCH] Makefile.lib: Use Python3 to make dtbo image</span><br><span class="line"></span><br><span class="line">Signed-off-by: dabao1955 &lt;dabao1955@163.com&gt;</span><br><span class="line"><span class="comment">---</span></span><br><span class="line"> scripts/Makefile.lib            |   2 +-</span><br><span class="line"> scripts/dtc/libfdt/mkdtboimg.py | 281 ++++++++++----------------------</span><br><span class="line"> 2 files changed, 83 insertions(+), 200 deletions(-)</span><br><span class="line"></span><br><span class="line"><span class="comment">diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib</span></span><br><span class="line"><span class="comment">index f4ba87cfa..de8981871 100644</span></span><br><span class="line"><span class="comment">--- a/scripts/Makefile.lib</span></span><br><span class="line"><span class="comment">+++ b/scripts/Makefile.lib</span></span><br><span class="line"><span class="meta">@@ -310,7 +310,7 @@</span> dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)</span><br><span class="line"> # mkdtimg</span><br><span class="line"> #----------------------------------------------------------------------------</span><br><span class="line"> quiet_cmd_mkdtimg = DTBOIMG $@</span><br><span class="line"><span class="deletion">-cmd_mkdtimg = python2 $(srctree)/scripts/dtc/libfdt/mkdtboimg.py create $@ --page_size=4096 $(filter-out FORCE,$^)</span></span><br><span class="line"><span class="addition">+cmd_mkdtimg = python3 $(srctree)/scripts/dtc/libfdt/mkdtboimg.py create $@ --page_size=4096 $(filter-out FORCE,$^)</span></span><br><span class="line"> </span><br><span class="line"> # cat</span><br><span class="line"> # ---------------------------------------------------------------------------</span><br><span class="line"><span class="comment">diff --git a/scripts/dtc/libfdt/mkdtboimg.py b/scripts/dtc/libfdt/mkdtboimg.py</span></span><br><span class="line"><span class="comment">index 03f0fd1b7..7b907da89 100644</span></span><br><span class="line"><span class="comment">--- a/scripts/dtc/libfdt/mkdtboimg.py</span></span><br><span class="line"><span class="comment">+++ b/scripts/dtc/libfdt/mkdtboimg.py</span></span><br><span class="line"><span class="meta">@@ -1,4 +1,4 @@</span></span><br><span class="line"><span class="deletion">-#! /usr/bin/env python</span></span><br><span class="line"><span class="addition">+#! /usr/bin/env python3</span></span><br><span class="line"> # Copyright 2017, The Android Open Source Project</span><br><span class="line"> #</span><br><span class="line"> # Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span><br><span class="line"><span class="meta">@@ -12,51 +12,46 @@</span></span><br><span class="line"> # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span><br><span class="line"> # See the License for the specific language governing permissions and</span><br><span class="line"> # limitations under the License.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> from __future__ import print_function</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> &quot;&quot;&quot;Tool for packing multiple DTB/DTBO files into a single image&quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> import argparse</span><br><span class="line"><span class="addition">+import fnmatch</span></span><br><span class="line"> import os</span><br><span class="line"><span class="addition">+import struct</span></span><br><span class="line"><span class="addition">+import zlib</span></span><br><span class="line"> from array import array</span><br><span class="line"> from collections import namedtuple</span><br><span class="line"><span class="deletion">-import struct</span></span><br><span class="line"> from sys import stdout</span><br><span class="line"><span class="deletion">-import zlib</span></span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> class CompressionFormat(object):</span><br><span class="line">     &quot;&quot;&quot;Enum representing DT compression format for a DT entry.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line">     NO_COMPRESSION = 0x00</span><br><span class="line">     ZLIB_COMPRESSION = 0x01</span><br><span class="line">     GZIP_COMPRESSION = 0x02</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> class DtEntry(object):</span><br><span class="line">     &quot;&quot;&quot;Provides individual DT image file arguments to be added to a DTBO.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Attributes:</span><br><span class="line"><span class="deletion">-        _REQUIRED_KEYS: &#x27;keys&#x27; needed to be present in the dictionary passed to instantiate</span></span><br><span class="line"><span class="deletion">-            an object of this class.</span></span><br><span class="line"><span class="deletion">-        _COMPRESSION_FORMAT_MASK: Mask to retrieve compression info for DT entry from flags field</span></span><br><span class="line"><span class="addition">+        REQUIRED_KEYS_V0: &#x27;keys&#x27; needed to be present in the dictionary passed to instantiate</span></span><br><span class="line"><span class="addition">+            an object of this class when a DTBO header of version 0 is used.</span></span><br><span class="line"><span class="addition">+        REQUIRED_KEYS_V1: &#x27;keys&#x27; needed to be present in the dictionary passed to instantiate</span></span><br><span class="line"><span class="addition">+            an object of this class when a DTBO header of version 1 is used.</span></span><br><span class="line"><span class="addition">+        COMPRESSION_FORMAT_MASK: Mask to retrieve compression info for DT entry from flags field</span></span><br><span class="line">             when a DTBO header of version 1 is used.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-    _COMPRESSION_FORMAT_MASK = 0x0f</span></span><br><span class="line"><span class="deletion">-    REQUIRED_KEYS = (&#x27;dt_file&#x27;, &#x27;dt_size&#x27;, &#x27;dt_offset&#x27;, &#x27;id&#x27;, &#x27;rev&#x27;, &#x27;flags&#x27;,</span></span><br><span class="line"><span class="deletion">-                     &#x27;custom0&#x27;, &#x27;custom1&#x27;, &#x27;custom2&#x27;)</span></span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="addition">+    COMPRESSION_FORMAT_MASK = 0x0f</span></span><br><span class="line"><span class="addition">+    REQUIRED_KEYS_V0 = (&#x27;dt_file&#x27;, &#x27;dt_size&#x27;, &#x27;dt_offset&#x27;, &#x27;id&#x27;, &#x27;rev&#x27;,</span></span><br><span class="line"><span class="addition">+                     &#x27;custom0&#x27;, &#x27;custom1&#x27;, &#x27;custom2&#x27;, &#x27;custom3&#x27;)</span></span><br><span class="line"><span class="addition">+    REQUIRED_KEYS_V1 = (&#x27;dt_file&#x27;, &#x27;dt_size&#x27;, &#x27;dt_offset&#x27;, &#x27;id&#x27;, &#x27;rev&#x27;,</span></span><br><span class="line"><span class="addition">+                     &#x27;flags&#x27;, &#x27;custom0&#x27;, &#x27;custom1&#x27;, &#x27;custom2&#x27;)</span></span><br><span class="line">     @staticmethod</span><br><span class="line">     def __get_number_or_prop(arg):</span><br><span class="line">         &quot;&quot;&quot;Converts string to integer or reads the property from DT image.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             arg: String containing the argument provided on the command line.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Returns:</span><br><span class="line">             An integer property read from DT file or argument string</span><br><span class="line">             converted to integer</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if not arg or arg[0] == &#x27;+&#x27; or arg[0] == &#x27;-&#x27;:</span><br><span class="line">             raise ValueError(&#x27;Invalid argument passed to DTImage&#x27;)</span><br><span class="line">         if arg[0] == &#x27;/&#x27;:</span><br><span class="line"><span class="meta">@@ -69,34 +64,37 @@</span> class DtEntry(object):</span><br><span class="line">             elif arg.startswith(&#x27;0&#x27;):</span><br><span class="line">                 base = 8</span><br><span class="line">             return int(arg, base)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def __init__(self, **kwargs):</span><br><span class="line">         &quot;&quot;&quot;Constructor for DtEntry object.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Initializes attributes from dictionary object that contains</span><br><span class="line">         values keyed with names equivalent to the class&#x27;s attributes.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             kwargs: Dictionary object containing values to instantiate</span><br><span class="line">                 class members with. Expected keys in dictionary are from</span><br><span class="line">                 the tuple (_REQUIRED_KEYS)</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-        missing_keys = set(self.REQUIRED_KEYS) - set(kwargs)</span></span><br><span class="line"><span class="addition">+        self.__version = kwargs[&#x27;version&#x27;]</span></span><br><span class="line"><span class="addition">+        required_keys = None</span></span><br><span class="line"><span class="addition">+        if self.__version == 0:</span></span><br><span class="line"><span class="addition">+            required_keys = self.REQUIRED_KEYS_V0</span></span><br><span class="line"><span class="addition">+        elif self.__version == 1:</span></span><br><span class="line"><span class="addition">+            required_keys = self.REQUIRED_KEYS_V1</span></span><br><span class="line"><span class="addition">+        missing_keys = set(required_keys) - set(kwargs)</span></span><br><span class="line">         if missing_keys:</span><br><span class="line">             raise ValueError(&#x27;Missing keys in DtEntry constructor: %r&#x27; %</span><br><span class="line">                              sorted(missing_keys))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         self.__dt_file = kwargs[&#x27;dt_file&#x27;]</span><br><span class="line">         self.__dt_offset = kwargs[&#x27;dt_offset&#x27;]</span><br><span class="line">         self.__dt_size = kwargs[&#x27;dt_size&#x27;]</span><br><span class="line">         self.__id = self.__get_number_or_prop(kwargs[&#x27;id&#x27;])</span><br><span class="line">         self.__rev = self.__get_number_or_prop(kwargs[&#x27;rev&#x27;])</span><br><span class="line"><span class="deletion">-        self.__flags = self.__get_number_or_prop(kwargs[&#x27;flags&#x27;])</span></span><br><span class="line"><span class="addition">+        if self.__version == 1:</span></span><br><span class="line"><span class="addition">+            self.__flags = self.__get_number_or_prop(kwargs[&#x27;flags&#x27;])</span></span><br><span class="line">         self.__custom0 = self.__get_number_or_prop(kwargs[&#x27;custom0&#x27;])</span><br><span class="line">         self.__custom1 = self.__get_number_or_prop(kwargs[&#x27;custom1&#x27;])</span><br><span class="line">         self.__custom2 = self.__get_number_or_prop(kwargs[&#x27;custom2&#x27;])</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="addition">+        if self.__version == 0:</span></span><br><span class="line"><span class="addition">+            self.__custom3 = self.__get_number_or_prop(kwargs[&#x27;custom3&#x27;])</span></span><br><span class="line">     def __str__(self):</span><br><span class="line">         sb = []</span><br><span class="line">         sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:d&#125;&#x27;.format(key=&#x27;dt_size&#x27;,</span><br><span class="line"><span class="meta">@@ -107,86 +105,78 @@</span> class DtEntry(object):</span><br><span class="line">                                                    value=self.__id))</span><br><span class="line">         sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;rev&#x27;,</span><br><span class="line">                                                    value=self.__rev))</span><br><span class="line"><span class="addition">+        if self.__version == 1:</span></span><br><span class="line"><span class="addition">+            sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;flags&#x27;,</span></span><br><span class="line"><span class="addition">+                                                       value=self.__flags))</span></span><br><span class="line">         sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;custom[0]&#x27;,</span><br><span class="line"><span class="deletion">-                                                   value=self.__flags))</span></span><br><span class="line"><span class="deletion">-        sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;custom[1]&#x27;,</span></span><br><span class="line">                                                    value=self.__custom0))</span><br><span class="line"><span class="deletion">-        sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;custom[2]&#x27;,</span></span><br><span class="line"><span class="addition">+        sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;custom[1]&#x27;,</span></span><br><span class="line">                                                    value=self.__custom1))</span><br><span class="line"><span class="deletion">-        sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;custom[3]&#x27;,</span></span><br><span class="line"><span class="addition">+        sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;custom[2]&#x27;,</span></span><br><span class="line">                                                    value=self.__custom2))</span><br><span class="line"><span class="addition">+        if self.__version == 0:</span></span><br><span class="line"><span class="addition">+            sb.append(&#x27;&#123;key:&gt;20&#125; = &#123;value:08x&#125;&#x27;.format(key=&#x27;custom[3]&#x27;,</span></span><br><span class="line"><span class="addition">+                                                       value=self.__custom3))</span></span><br><span class="line">         return &#x27;\n&#x27;.join(sb)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-    def compression_info(self, version):</span></span><br><span class="line"><span class="addition">+    def compression_info(self):</span></span><br><span class="line">         &quot;&quot;&quot;CompressionFormat: compression format for DT image file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">            Args:</span><br><span class="line">                 version: Version of DTBO header, compression is only</span><br><span class="line">                          supported from version 1.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-        if version is 0:</span></span><br><span class="line"><span class="addition">+        if self.__version == 0:</span></span><br><span class="line">             return CompressionFormat.NO_COMPRESSION</span><br><span class="line"><span class="deletion">-        return self.flags &amp; self._COMPRESSION_FORMAT_MASK</span></span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="addition">+        return self.flags &amp; self.COMPRESSION_FORMAT_MASK</span></span><br><span class="line">     @property</span><br><span class="line">     def dt_file(self):</span><br><span class="line">         &quot;&quot;&quot;file: File handle to the DT image file.&quot;&quot;&quot;</span><br><span class="line">         return self.__dt_file</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def size(self):</span><br><span class="line">         &quot;&quot;&quot;int: size in bytes of the DT image file.&quot;&quot;&quot;</span><br><span class="line">         return self.__dt_size</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @size.setter</span><br><span class="line">     def size(self, value):</span><br><span class="line">         self.__dt_size = value</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def dt_offset(self):</span><br><span class="line">         &quot;&quot;&quot;int: offset in DTBO file for this DT image.&quot;&quot;&quot;</span><br><span class="line">         return self.__dt_offset</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @dt_offset.setter</span><br><span class="line">     def dt_offset(self, value):</span><br><span class="line">         self.__dt_offset = value</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def image_id(self):</span><br><span class="line">         &quot;&quot;&quot;int: DT entry _id for this DT image.&quot;&quot;&quot;</span><br><span class="line">         return self.__id</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def rev(self):</span><br><span class="line">         &quot;&quot;&quot;int: DT entry _rev for this DT image.&quot;&quot;&quot;</span><br><span class="line">         return self.__rev</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def flags(self):</span><br><span class="line">         &quot;&quot;&quot;int: DT entry _flags for this DT image.&quot;&quot;&quot;</span><br><span class="line">         return self.__flags</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def custom0(self):</span><br><span class="line">         &quot;&quot;&quot;int: DT entry _custom0 for this DT image.&quot;&quot;&quot;</span><br><span class="line">         return self.__custom0</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def custom1(self):</span><br><span class="line">         &quot;&quot;&quot;int: DT entry _custom1 for this DT image.&quot;&quot;&quot;</span><br><span class="line">         return self.__custom1</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def custom2(self):</span><br><span class="line">         &quot;&quot;&quot;int: DT entry custom2 for this DT image.&quot;&quot;&quot;</span><br><span class="line">         return self.__custom2</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="addition">+    @property</span></span><br><span class="line"><span class="addition">+    def custom3(self):</span></span><br><span class="line"><span class="addition">+        &quot;&quot;&quot;int: DT entry custom3 for this DT image.&quot;&quot;&quot;</span></span><br><span class="line"><span class="addition">+        return self.__custom3</span></span><br><span class="line"> class Dtbo(object):</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line">     Provides parser, reader, writer for dumping and creating Device Tree Blob</span><br><span class="line">     Overlay (DTBO) images.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Attributes:</span><br><span class="line">         _DTBO_MAGIC: Device tree table header magic.</span><br><span class="line">         _ACPIO_MAGIC: Advanced Configuration and Power Interface table header</span><br><span class="line"><span class="meta">@@ -198,7 +188,6 @@</span> class Dtbo(object):</span><br><span class="line">         _GZIP_COMPRESSION_WBITS: Argument &#x27;wbits&#x27; for gzip compression</span><br><span class="line">         _ZLIB_DECOMPRESSION_WBITS: Argument &#x27;wbits&#x27; for zlib/gzip compression</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     _DTBO_MAGIC = 0xd7b7ab1e</span><br><span class="line">     _ACPIO_MAGIC = 0x41435049</span><br><span class="line">     _DT_TABLE_HEADER_SIZE = struct.calcsize(&#x27;&gt;8I&#x27;)</span><br><span class="line"><span class="meta">@@ -207,10 +196,8 @@</span> class Dtbo(object):</span><br><span class="line">     _DT_ENTRY_HEADER_INTS = 8</span><br><span class="line">     _GZIP_COMPRESSION_WBITS = 31</span><br><span class="line">     _ZLIB_DECOMPRESSION_WBITS = 47</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def _update_dt_table_header(self):</span><br><span class="line">         &quot;&quot;&quot;Converts header entries into binary data for DTBO header.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Packs the current Device tree table header attribute values in</span><br><span class="line">         metadata buffer.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="meta">@@ -219,44 +206,41 @@</span> class Dtbo(object):</span><br><span class="line">                          self.dt_entry_size, self.dt_entry_count,</span><br><span class="line">                          self.dt_entries_offset, self.page_size,</span><br><span class="line">                          self.version)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def _update_dt_entry_header(self, dt_entry, metadata_offset):</span><br><span class="line">         &quot;&quot;&quot;Converts each DT entry header entry into binary data for DTBO file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Packs the current device tree table entry attribute into</span><br><span class="line">         metadata buffer as device tree entry header.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             dt_entry: DtEntry object for the header to be packed.</span><br><span class="line">             metadata_offset: Offset into metadata buffer to begin writing.</span><br><span class="line">             dtbo_offset: Offset where the DT image file for this dt_entry can</span><br><span class="line">                 be found in the resulting DTBO image.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-        struct.pack_into(&#x27;&gt;8I&#x27;, self.__metadata, metadata_offset, dt_entry.size,</span></span><br><span class="line"><span class="deletion">-                         dt_entry.dt_offset, dt_entry.image_id, dt_entry.rev,</span></span><br><span class="line"><span class="deletion">-                         dt_entry.flags, dt_entry.custom0, dt_entry.custom1,</span></span><br><span class="line"><span class="deletion">-                         dt_entry.custom2)</span></span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="addition">+        if self.version == 0:</span></span><br><span class="line"><span class="addition">+            struct.pack_into(&#x27;&gt;8I&#x27;, self.__metadata, metadata_offset, dt_entry.size,</span></span><br><span class="line"><span class="addition">+                             dt_entry.dt_offset, dt_entry.image_id, dt_entry.rev,</span></span><br><span class="line"><span class="addition">+                             dt_entry.custom0, dt_entry.custom1, dt_entry.custom2,</span></span><br><span class="line"><span class="addition">+                             dt_entry.custom3)</span></span><br><span class="line"><span class="addition">+        elif self.version == 1:</span></span><br><span class="line"><span class="addition">+            struct.pack_into(&#x27;&gt;8I&#x27;, self.__metadata, metadata_offset, dt_entry.size,</span></span><br><span class="line"><span class="addition">+                             dt_entry.dt_offset, dt_entry.image_id, dt_entry.rev,</span></span><br><span class="line"><span class="addition">+                             dt_entry.flags, dt_entry.custom0, dt_entry.custom1,</span></span><br><span class="line"><span class="addition">+                             dt_entry.custom2)</span></span><br><span class="line">     def _update_metadata(self):</span><br><span class="line">         &quot;&quot;&quot;Updates the DTBO metadata.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Initialize the internal metadata buffer and fill it with all Device</span><br><span class="line">         Tree table entries and update the DTBO header.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-        self.__metadata = array(&#x27;c&#x27;, &#x27; &#x27; * self.__metadata_size)</span></span><br><span class="line"><span class="addition">+        self.__metadata = array(&#x27;b&#x27;, b&#x27; &#x27; * self.__metadata_size)</span></span><br><span class="line">         metadata_offset = self.header_size</span><br><span class="line">         for dt_entry in self.__dt_entries:</span><br><span class="line">             self._update_dt_entry_header(dt_entry, metadata_offset)</span><br><span class="line">             metadata_offset += self.dt_entry_size</span><br><span class="line">         self._update_dt_table_header()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def _read_dtbo_header(self, buf):</span><br><span class="line">         &quot;&quot;&quot;Reads DTBO file header into metadata buffer.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Unpack and read the DTBO table header from given buffer. The</span><br><span class="line">         buffer size must exactly be equal to _DT_TABLE_HEADER_SIZE.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             buf: Bytebuffer read directly from the file of size</span><br><span class="line">                 _DT_TABLE_HEADER_SIZE.</span><br><span class="line"><span class="meta">@@ -264,63 +248,57 @@</span> class Dtbo(object):</span><br><span class="line">         (self.magic, self.total_size, self.header_size,</span><br><span class="line">          self.dt_entry_size, self.dt_entry_count, self.dt_entries_offset,</span><br><span class="line">          self.page_size, self.version) = struct.unpack_from(&#x27;&gt;8I&#x27;, buf, 0)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         # verify the header</span><br><span class="line">         if self.magic != self._DTBO_MAGIC and self.magic != self._ACPIO_MAGIC:</span><br><span class="line">             raise ValueError(&#x27;Invalid magic number 0x%x in DTBO/ACPIO file&#x27; %</span><br><span class="line">                              (self.magic))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if self.header_size != self._DT_TABLE_HEADER_SIZE:</span><br><span class="line">             raise ValueError(&#x27;Invalid header size (%d) in DTBO/ACPIO file&#x27; %</span><br><span class="line">                              (self.header_size))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if self.dt_entry_size != self._DT_ENTRY_HEADER_SIZE:</span><br><span class="line">             raise ValueError(&#x27;Invalid DT entry header size (%d) in DTBO/ACPIO file&#x27; %</span><br><span class="line">                              (self.dt_entry_size))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def _read_dt_entries_from_metadata(self):</span><br><span class="line">         &quot;&quot;&quot;Reads individual DT entry headers from metadata buffer.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Unpack and read the DTBO DT entry headers from the internal buffer.</span><br><span class="line">         The buffer size must exactly be equal to _DT_TABLE_HEADER_SIZE +</span><br><span class="line">         (_DT_ENTRY_HEADER_SIZE * dt_entry_count). The method raises exception</span><br><span class="line">         if DT entries have already been set for this object.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if self.__dt_entries:</span><br><span class="line">             raise ValueError(&#x27;DTBO DT entries can be added only once&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-        offset = self.dt_entries_offset / 4</span></span><br><span class="line"><span class="addition">+        offset = self.dt_entries_offset // 4</span></span><br><span class="line">         params = &#123;&#125;</span><br><span class="line"><span class="addition">+        params[&#x27;version&#x27;] = self.version</span></span><br><span class="line">         params[&#x27;dt_file&#x27;] = None</span><br><span class="line">         for i in range(0, self.dt_entry_count):</span><br><span class="line">             dt_table_entry = self.__metadata[offset:offset + self._DT_ENTRY_HEADER_INTS]</span><br><span class="line">             params[&#x27;dt_size&#x27;] = dt_table_entry[0]</span><br><span class="line">             params[&#x27;dt_offset&#x27;] = dt_table_entry[1]</span><br><span class="line">             for j in range(2, self._DT_ENTRY_HEADER_INTS):</span><br><span class="line"><span class="deletion">-                params[DtEntry.REQUIRED_KEYS[j + 1]] = str(dt_table_entry[j])</span></span><br><span class="line"><span class="addition">+                required_keys = None</span></span><br><span class="line"><span class="addition">+                if self.version == 0:</span></span><br><span class="line"><span class="addition">+                    required_keys = DtEntry.REQUIRED_KEYS_V0</span></span><br><span class="line"><span class="addition">+                elif self.version == 1:</span></span><br><span class="line"><span class="addition">+                    required_keys = DtEntry.REQUIRED_KEYS_V1</span></span><br><span class="line"><span class="addition">+                params[required_keys[j + 1]] = str(dt_table_entry[j])</span></span><br><span class="line">             dt_entry = DtEntry(**params)</span><br><span class="line">             self.__dt_entries.append(dt_entry)</span><br><span class="line">             offset += self._DT_ENTRY_HEADER_INTS</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def _read_dtbo_image(self):</span><br><span class="line">         &quot;&quot;&quot;Parse the input file and instantiate this object.&quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         # First check if we have enough to read the header</span><br><span class="line">         file_size = os.fstat(self.__file.fileno()).st_size</span><br><span class="line">         if file_size &lt; self._DT_TABLE_HEADER_SIZE:</span><br><span class="line">             raise ValueError(&#x27;Invalid DTBO file&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         self.__file.seek(0)</span><br><span class="line">         buf = self.__file.read(self._DT_TABLE_HEADER_SIZE)</span><br><span class="line">         self._read_dtbo_header(buf)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         self.__metadata_size = (self.header_size +</span><br><span class="line">                                 self.dt_entry_count * self.dt_entry_size)</span><br><span class="line">         if file_size &lt; self.__metadata_size:</span><br><span class="line">             raise ValueError(&#x27;Invalid or truncated DTBO file of size %d expected %d&#x27; %</span><br><span class="line">                              file_size, self.__metadata_size)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         num_ints = (self._DT_TABLE_HEADER_INTS +</span><br><span class="line">                     self.dt_entry_count * self._DT_ENTRY_HEADER_INTS)</span><br><span class="line">         if self.dt_entries_offset &gt; self._DT_TABLE_HEADER_SIZE:</span><br><span class="line"><span class="meta">@@ -330,10 +308,8 @@</span> class Dtbo(object):</span><br><span class="line">         self.__metadata = struct.unpack(format_str,</span><br><span class="line">                                         self.__file.read(self.__metadata_size))</span><br><span class="line">         self._read_dt_entries_from_metadata()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def _find_dt_entry_with_same_file(self, dt_entry):</span><br><span class="line">         &quot;&quot;&quot;Finds DT Entry that has identical backing DT file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             dt_entry: DtEntry object whose &#x27;dtfile&#x27; we find for existence in the</span><br><span class="line">                 current &#x27;dt_entries&#x27;.</span><br><span class="line"><span class="meta">@@ -341,28 +317,23 @@</span> class Dtbo(object):</span><br><span class="line">             If a match by file path is found, the corresponding DtEntry object</span><br><span class="line">             from internal list is returned. If not, &#x27;None&#x27; is returned.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         dt_entry_path = os.path.realpath(dt_entry.dt_file.name)</span><br><span class="line">         for entry in self.__dt_entries:</span><br><span class="line">             entry_path = os.path.realpath(entry.dt_file.name)</span><br><span class="line">             if entry_path == dt_entry_path:</span><br><span class="line">                 return entry</span><br><span class="line">         return None</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def __init__(self, file_handle, dt_type=&#x27;dtb&#x27;, page_size=None, version=0):</span><br><span class="line">         &quot;&quot;&quot;Constructor for Dtbo Object</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             file_handle: The Dtbo File handle corresponding to this object.</span><br><span class="line">                 The file handle can be used to write to (in case of &#x27;create&#x27;)</span><br><span class="line">                 or read from (in case of &#x27;dump&#x27;)</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         self.__file = file_handle</span><br><span class="line">         self.__dt_entries = []</span><br><span class="line">         self.__metadata = None</span><br><span class="line">         self.__metadata_size = 0</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         # if page_size is given, assume the object is being instantiated to</span><br><span class="line">         # create a DTBO file</span><br><span class="line">         if page_size:</span><br><span class="line"><span class="meta">@@ -380,7 +351,6 @@</span> class Dtbo(object):</span><br><span class="line">             self.__metadata_size = self._DT_TABLE_HEADER_SIZE</span><br><span class="line">         else:</span><br><span class="line">             self._read_dtbo_image()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def __str__(self):</span><br><span class="line">         sb = []</span><br><span class="line">         sb.append(&#x27;dt_table_header:&#x27;)</span><br><span class="line"><span class="meta">@@ -399,22 +369,17 @@</span> class Dtbo(object):</span><br><span class="line">             sb.append(str(dt_entry))</span><br><span class="line">             count = count + 1</span><br><span class="line">         return &#x27;\n&#x27;.join(sb)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     @property</span><br><span class="line">     def dt_entries(self):</span><br><span class="line">         &quot;&quot;&quot;Returns a list of DtEntry objects found in DTBO file.&quot;&quot;&quot;</span><br><span class="line">         return self.__dt_entries</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def compress_dt_entry(self, compression_format, dt_entry_file):</span><br><span class="line">         &quot;&quot;&quot;Compresses a DT entry.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             compression_format: Compression format for DT Entry</span><br><span class="line">             dt_entry_file: File handle to read DT entry from.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Returns:</span><br><span class="line">             Compressed DT entry and its length.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Raises:</span><br><span class="line">             ValueError if unrecognized compression format is found.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line"><span class="meta">@@ -426,10 +391,8 @@</span> class Dtbo(object):</span><br><span class="line">             CompressionFormat.ZLIB_COMPRESSION: compress_zlib,</span><br><span class="line">             CompressionFormat.GZIP_COMPRESSION: compress_gzip,</span><br><span class="line">         &#125;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if compression_format not in compression_obj_dict:</span><br><span class="line">             ValueError(&quot;Bad compression format %d&quot; % compression_format)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if compression_format is CompressionFormat.NO_COMPRESSION:</span><br><span class="line">             dt_entry = dt_entry_file.read()</span><br><span class="line">         else:</span><br><span class="line"><span class="meta">@@ -438,41 +401,32 @@</span> class Dtbo(object):</span><br><span class="line">             dt_entry = compression_object.compress(dt_entry_file.read())</span><br><span class="line">             dt_entry += compression_object.flush()</span><br><span class="line">         return dt_entry, len(dt_entry)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def add_dt_entries(self, dt_entries):</span><br><span class="line">         &quot;&quot;&quot;Adds DT image files to the DTBO object.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Adds a list of Dtentry Objects to the DTBO image. The changes are not</span><br><span class="line">         committed to the output file until commit() is called.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             dt_entries: List of DtEntry object to be added.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Returns:</span><br><span class="line">             A buffer containing all DT entries.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Raises:</span><br><span class="line">             ValueError: if the list of DT entries is empty or if a list of DT entries</span><br><span class="line">                 has already been added to the DTBO.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line">         if not dt_entries:</span><br><span class="line">             raise ValueError(&#x27;Attempted to add empty list of DT entries&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if self.__dt_entries:</span><br><span class="line">             raise ValueError(&#x27;DTBO DT entries can be added only once&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         dt_entry_count = len(dt_entries)</span><br><span class="line">         dt_offset = (self.header_size +</span><br><span class="line">                      dt_entry_count * self.dt_entry_size)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-        dt_entry_buf = &quot;&quot;</span></span><br><span class="line"><span class="addition">+        dt_entry_buf = b&quot;&quot;</span></span><br><span class="line">         for dt_entry in dt_entries:</span><br><span class="line">             if not isinstance(dt_entry, DtEntry):</span><br><span class="line">                 raise ValueError(&#x27;Adding invalid DT entry object to DTBO&#x27;)</span><br><span class="line">             entry = self._find_dt_entry_with_same_file(dt_entry)</span><br><span class="line"><span class="deletion">-            dt_entry_compression_info = dt_entry.compression_info(self.version)</span></span><br><span class="line"><span class="deletion">-            if entry and (entry.compression_info(self.version)</span></span><br><span class="line"><span class="deletion">-                          == dt_entry_compression_info):</span></span><br><span class="line"><span class="addition">+            dt_entry_compression_info = dt_entry.compression_info()</span></span><br><span class="line"><span class="addition">+            if entry and (entry.compression_info() == dt_entry_compression_info):</span></span><br><span class="line">                 dt_entry.dt_offset = entry.dt_offset</span><br><span class="line">                 dt_entry.size = entry.size</span><br><span class="line">             else:</span><br><span class="line"><span class="meta">@@ -486,31 +440,25 @@</span> class Dtbo(object):</span><br><span class="line">             self.dt_entry_count += 1</span><br><span class="line">             self.__metadata_size += self.dt_entry_size</span><br><span class="line">             self.total_size += self.dt_entry_size</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         return dt_entry_buf</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def extract_dt_file(self, idx, fout, decompress):</span><br><span class="line">         &quot;&quot;&quot;Extract DT Image files embedded in the DTBO file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Extracts Device Tree blob image file at given index into a file handle.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             idx: Index of the DT entry in the DTBO file.</span><br><span class="line">             fout: File handle where the DTB at index idx to be extracted into.</span><br><span class="line">             decompress: If a DT entry is compressed, decompress it before writing</span><br><span class="line">                 it to the file handle.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Raises:</span><br><span class="line">             ValueError: if invalid DT entry index or compression format is detected.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line">         if idx &gt; self.dt_entry_count:</span><br><span class="line">             raise ValueError(&#x27;Invalid index %d of DtEntry&#x27; % idx)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         size = self.dt_entries[idx].size</span><br><span class="line">         offset = self.dt_entries[idx].dt_offset</span><br><span class="line">         self.__file.seek(offset, 0)</span><br><span class="line">         fout.seek(0)</span><br><span class="line"><span class="deletion">-        compression_format = self.dt_entries[idx].compression_info(self.version)</span></span><br><span class="line"><span class="addition">+        compression_format = self.dt_entries[idx].compression_info()</span></span><br><span class="line">         if decompress and compression_format:</span><br><span class="line">             if (compression_format == CompressionFormat.ZLIB_COMPRESSION or</span><br><span class="line">                 compression_format == CompressionFormat.GZIP_COMPRESSION):</span><br><span class="line"><span class="meta">@@ -519,47 +467,35 @@</span> class Dtbo(object):</span><br><span class="line">                 raise ValueError(&quot;Unknown compression format detected&quot;)</span><br><span class="line">         else:</span><br><span class="line">             fout.write(self.__file.read(size))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     def commit(self, dt_entry_buf):</span><br><span class="line">         &quot;&quot;&quot;Write out staged changes to the DTBO object to create a DTBO file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Writes a fully instantiated Dtbo Object into the output file using the</span><br><span class="line">         file handle present in &#x27;_file&#x27;. No checks are performed on the object</span><br><span class="line">         except for existence of output file handle on the object before writing</span><br><span class="line">         out the file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         Args:</span><br><span class="line">             dt_entry_buf: Buffer containing all DT entries.</span><br><span class="line">         &quot;&quot;&quot;</span><br><span class="line">         if not self.__file:</span><br><span class="line">             raise ValueError(&#x27;No file given to write to.&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         if not self.__dt_entries:</span><br><span class="line">             raise ValueError(&#x27;No DT image files to embed into DTBO image given.&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         self._update_metadata()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">         self.__file.seek(0)</span><br><span class="line">         self.__file.write(self.__metadata)</span><br><span class="line">         self.__file.write(dt_entry_buf)</span><br><span class="line">         self.__file.flush()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def parse_dt_entry(global_args, arglist):</span><br><span class="line">     &quot;&quot;&quot;Parse arguments for single DT entry file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Parses command line arguments for single DT image file while</span><br><span class="line">     creating a Device tree blob overlay (DTBO).</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         global_args: Dtbo object containing global default values</span><br><span class="line">             for DtEntry attributes.</span><br><span class="line">         arglist: Command line argument list for this DtEntry.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Returns:</span><br><span class="line">         A Namespace object containing all values to instantiate DtEntry object.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     parser = argparse.ArgumentParser(add_help=False)</span><br><span class="line">     parser.add_argument(&#x27;dt_file&#x27;, nargs=&#x27;?&#x27;,</span><br><span class="line">                         type=argparse.FileType(&#x27;rb&#x27;),</span><br><span class="line"><span class="meta">@@ -580,21 +516,19 @@</span> def parse_dt_entry(global_args, arglist):</span><br><span class="line">     parser.add_argument(&#x27;--custom2&#x27;, type=str, dest=&#x27;custom2&#x27;,</span><br><span class="line">                         action=&#x27;store&#x27;,</span><br><span class="line">                         default=global_args.global_custom2)</span><br><span class="line"><span class="addition">+    parser.add_argument(&#x27;--custom3&#x27;, type=str, dest=&#x27;custom3&#x27;,</span></span><br><span class="line"><span class="addition">+                        action=&#x27;store&#x27;,</span></span><br><span class="line"><span class="addition">+                        default=global_args.global_custom3)</span></span><br><span class="line">     return parser.parse_args(arglist)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def parse_dt_entries(global_args, arg_list):</span><br><span class="line">     &quot;&quot;&quot;Parse all DT entries from command line.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Parse all DT image files and their corresponding attribute from</span><br><span class="line">     command line</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         global_args: Argument containing default global values for _id,</span><br><span class="line">             _rev and customX.</span><br><span class="line">         arg_list: The remainder of the command line after global options</span><br><span class="line">             DTBO creation have been parsed.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Returns:</span><br><span class="line">         A List of DtEntry objects created after parsing the command line</span><br><span class="line">         given in argument.</span><br><span class="line"><span class="meta">@@ -607,12 +541,10 @@</span> def parse_dt_entries(global_args, arg_list):</span><br><span class="line">         if not arg.startswith(&quot;--&quot;):</span><br><span class="line">             img_file_idx.append(idx)</span><br><span class="line">         idx = idx + 1</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     if not img_file_idx:</span><br><span class="line">         raise ValueError(&#x27;Input DT images must be provided&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     total_images = len(img_file_idx)</span><br><span class="line"><span class="deletion">-    for idx in xrange(total_images):</span></span><br><span class="line"><span class="addition">+    for idx in range(total_images):</span></span><br><span class="line">         start_idx = img_file_idx[idx]</span><br><span class="line">         if idx == total_images - 1:</span><br><span class="line">             argv = arg_list[start_idx:]</span><br><span class="line"><span class="meta">@@ -621,15 +553,13 @@</span> def parse_dt_entries(global_args, arg_list):</span><br><span class="line">             argv = arg_list[start_idx:end_idx]</span><br><span class="line">         args = parse_dt_entry(global_args, argv)</span><br><span class="line">         params = vars(args)</span><br><span class="line"><span class="addition">+        params[&#x27;version&#x27;] = global_args.version</span></span><br><span class="line">         params[&#x27;dt_offset&#x27;] = 0</span><br><span class="line">         params[&#x27;dt_size&#x27;] = os.fstat(params[&#x27;dt_file&#x27;].fileno()).st_size</span><br><span class="line">         dt_entries.append(DtEntry(**params))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     return dt_entries</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def parse_config_option(line, is_global, dt_keys, global_key_types):</span><br><span class="line">     &quot;&quot;&quot;Parses a single line from the configuration file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         line: String containing the key=value line from the file.</span><br><span class="line">         is_global: Boolean indicating if we should parse global or DT entry</span><br><span class="line"><span class="meta">@@ -639,27 +569,21 @@</span> def parse_config_option(line, is_global, dt_keys, global_key_types):</span><br><span class="line">         global_key_types: A dict of global options and their corresponding types. It</span><br><span class="line">             contains all exclusive valid global option strings in configuration</span><br><span class="line">             file that are not repeated in dt entry options.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Returns:</span><br><span class="line">         Returns a tuple for parsed key and value for the option. Also, checks</span><br><span class="line">         the key to make sure its valid.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     if line.find(&#x27;=&#x27;) == -1:</span><br><span class="line">         raise ValueError(&#x27;Invalid line (%s) in configuration file&#x27; % line)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     key, value = (x.strip() for x in line.split(&#x27;=&#x27;))</span><br><span class="line">     if is_global and key in global_key_types:</span><br><span class="line">         if global_key_types[key] is int:</span><br><span class="line">             value = int(value)</span><br><span class="line">     elif key not in dt_keys:</span><br><span class="line">         raise ValueError(&#x27;Invalid option (%s) in configuration file&#x27; % key)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     return key, value</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def parse_config_file(fin, dt_keys, global_key_types):</span><br><span class="line">     &quot;&quot;&quot;Parses the configuration file for creating DTBO image.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         fin: File handle for configuration file</span><br><span class="line">         is_global: Boolean indicating if we should parse global or DT entry</span><br><span class="line"><span class="meta">@@ -669,7 +593,6 @@</span> def parse_config_file(fin, dt_keys, global_key_types):</span><br><span class="line">         global_key_types: A dict of global options and their corresponding types. It</span><br><span class="line">             contains all exclusive valid global option strings in configuration</span><br><span class="line">             file that are not repeated in dt entry options.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Returns:</span><br><span class="line">         global_args, dt_args: Tuple of a dictionary with global arguments</span><br><span class="line">         and a list of dictionaries for all DT entry specific arguments the</span><br><span class="line"><span class="meta">@@ -683,13 +606,11 @@</span> def parse_config_file(fin, dt_keys, global_key_types):</span><br><span class="line">                   &#x27;rev&#x27; : &lt;value2&gt; ...&#125;, ...</span><br><span class="line">                 ]</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     # set all global defaults</span><br><span class="line">     global_args = dict((k, &#x27;0&#x27;) for k in dt_keys)</span><br><span class="line">     global_args[&#x27;dt_type&#x27;] = &#x27;dtb&#x27;</span><br><span class="line">     global_args[&#x27;page_size&#x27;] = 2048</span><br><span class="line">     global_args[&#x27;version&#x27;] = 0</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     dt_args = []</span><br><span class="line">     found_dt_entry = False</span><br><span class="line">     count = -1</span><br><span class="line"><span class="meta">@@ -714,24 +635,19 @@</span> def parse_config_file(fin, dt_keys, global_key_types):</span><br><span class="line">             dt_args.append(&#123;&#125;)</span><br><span class="line">             dt_args[-1][&#x27;filename&#x27;] = line.strip()</span><br><span class="line">     return global_args, dt_args</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def parse_create_args(arg_list):</span><br><span class="line">     &quot;&quot;&quot;Parse command line arguments for &#x27;create&#x27; sub-command.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         arg_list: All command line arguments except the outfile file name.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Returns:</span><br><span class="line">         The list of remainder of the command line arguments after parsing</span><br><span class="line">         for &#x27;create&#x27;.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     image_arg_index = 0</span><br><span class="line">     for arg in arg_list:</span><br><span class="line">         if not arg.startswith(&quot;--&quot;):</span><br><span class="line">             break</span><br><span class="line">         image_arg_index = image_arg_index + 1</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     argv = arg_list[0:image_arg_index]</span><br><span class="line">     remainder = arg_list[image_arg_index:]</span><br><span class="line">     parser = argparse.ArgumentParser(prog=&#x27;create&#x27;, add_help=False)</span><br><span class="line"><span class="meta">@@ -753,57 +669,49 @@</span> def parse_create_args(arg_list):</span><br><span class="line">                         action=&#x27;store&#x27;, default=&#x27;0&#x27;)</span><br><span class="line">     parser.add_argument(&#x27;--custom2&#x27;, type=str, dest=&#x27;global_custom2&#x27;,</span><br><span class="line">                         action=&#x27;store&#x27;, default=&#x27;0&#x27;)</span><br><span class="line"><span class="addition">+    parser.add_argument(&#x27;--custom3&#x27;, type=str, dest=&#x27;global_custom3&#x27;,</span></span><br><span class="line"><span class="addition">+                        action=&#x27;store&#x27;, default=&#x27;0&#x27;)</span></span><br><span class="line">     args = parser.parse_args(argv)</span><br><span class="line">     return args, remainder</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def parse_dump_cmd_args(arglist):</span><br><span class="line">     &quot;&quot;&quot;Parse command line arguments for &#x27;dump&#x27; sub-command.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         arglist: List of all command line arguments including the outfile</span><br><span class="line">             file name if exists.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Returns:</span><br><span class="line">         A namespace object of parsed arguments.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     parser = argparse.ArgumentParser(prog=&#x27;dump&#x27;)</span><br><span class="line">     parser.add_argument(&#x27;--output&#x27;, &#x27;-o&#x27;, nargs=&#x27;?&#x27;,</span><br><span class="line"><span class="deletion">-                        type=argparse.FileType(&#x27;wb&#x27;),</span></span><br><span class="line"><span class="addition">+                        type=argparse.FileType(&#x27;w&#x27;),</span></span><br><span class="line">                         dest=&#x27;outfile&#x27;,</span><br><span class="line">                         default=stdout)</span><br><span class="line">     parser.add_argument(&#x27;--dtb&#x27;, &#x27;-b&#x27;, nargs=&#x27;?&#x27;, type=str,</span><br><span class="line">                         dest=&#x27;dtfilename&#x27;)</span><br><span class="line">     parser.add_argument(&#x27;--decompress&#x27;, action=&#x27;store_true&#x27;, dest=&#x27;decompress&#x27;)</span><br><span class="line">     return parser.parse_args(arglist)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def parse_config_create_cmd_args(arglist):</span><br><span class="line">     &quot;&quot;&quot;Parse command line arguments for &#x27;cfg_create subcommand.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         arglist: A list of all command line arguments including the</span><br><span class="line">             mandatory input configuration file name.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Returns:</span><br><span class="line">         A Namespace object of parsed arguments.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line">     parser = argparse.ArgumentParser(prog=&#x27;cfg_create&#x27;)</span><br><span class="line">     parser.add_argument(&#x27;conf_file&#x27;, nargs=&#x27;?&#x27;,</span><br><span class="line"><span class="deletion">-                        type=argparse.FileType(&#x27;rb&#x27;),</span></span><br><span class="line"><span class="addition">+                        type=argparse.FileType(&#x27;r&#x27;),</span></span><br><span class="line">                         default=None)</span><br><span class="line">     cwd = os.getcwd()</span><br><span class="line">     parser.add_argument(&#x27;--dtb-dir&#x27;, &#x27;-d&#x27;, nargs=&#x27;?&#x27;, type=str,</span><br><span class="line">                         dest=&#x27;dtbdir&#x27;, default=cwd)</span><br><span class="line">     return parser.parse_args(arglist)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def create_dtbo_image(fout, argv):</span><br><span class="line">     &quot;&quot;&quot;Create Device Tree Blob Overlay image using provided arguments.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         fout: Output file handle to write to.</span><br><span class="line">         argv: list of command line arguments.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     global_args, remainder = parse_create_args(argv)</span><br><span class="line">     if not remainder:</span><br><span class="line">         raise ValueError(&#x27;List of dtimages to add to DTBO not provided&#x27;)</span><br><span class="line"><span class="meta">@@ -812,14 +720,11 @@</span> def create_dtbo_image(fout, argv):</span><br><span class="line">     dt_entry_buf = dtbo.add_dt_entries(dt_entries)</span><br><span class="line">     dtbo.commit(dt_entry_buf)</span><br><span class="line">     fout.close()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def dump_dtbo_image(fin, argv):</span><br><span class="line">     &quot;&quot;&quot;Dump DTBO file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Dump Device Tree Blob Overlay metadata as output and the device</span><br><span class="line">     tree image files embedded in the DTBO image into file(s) provided</span><br><span class="line">     as arguments</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         fin: Input DTBO image files.</span><br><span class="line">         argv: list of command line arguments.</span><br><span class="line"><span class="meta">@@ -833,10 +738,8 @@</span> def dump_dtbo_image(fin, argv):</span><br><span class="line">                 dtbo.extract_dt_file(idx, fout, args.decompress)</span><br><span class="line">     args.outfile.write(str(dtbo) + &#x27;\n&#x27;)</span><br><span class="line">     args.outfile.close()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def create_dtbo_image_from_config(fout, argv):</span><br><span class="line">     &quot;&quot;&quot;Create DTBO file from a configuration file.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         fout: Output file handle to write to.</span><br><span class="line">         argv: list of command line arguments.</span><br><span class="line"><span class="meta">@@ -844,16 +747,20 @@</span> def create_dtbo_image_from_config(fout, argv):</span><br><span class="line">     args = parse_config_create_cmd_args(argv)</span><br><span class="line">     if not args.conf_file:</span><br><span class="line">         raise ValueError(&#x27;Configuration file must be provided&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="deletion">-    _DT_KEYS = (&#x27;id&#x27;, &#x27;rev&#x27;, &#x27;flags&#x27;, &#x27;custom0&#x27;, &#x27;custom1&#x27;, &#x27;custom2&#x27;)</span></span><br><span class="line"><span class="addition">+    _DT_KEYS = (&#x27;id&#x27;, &#x27;rev&#x27;, &#x27;flags&#x27;, &#x27;custom0&#x27;, &#x27;custom1&#x27;, &#x27;custom2&#x27;, &#x27;custom3&#x27;)</span></span><br><span class="line">     _GLOBAL_KEY_TYPES = &#123;&#x27;dt_type&#x27;: str, &#x27;page_size&#x27;: int, &#x27;version&#x27;: int&#125;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     global_args, dt_args = parse_config_file(args.conf_file,</span><br><span class="line">                                              _DT_KEYS, _GLOBAL_KEY_TYPES)</span><br><span class="line"><span class="addition">+    version = global_args[&#x27;version&#x27;]</span></span><br><span class="line">     params = &#123;&#125;</span><br><span class="line"><span class="addition">+    params[&#x27;version&#x27;] = version</span></span><br><span class="line">     dt_entries = []</span><br><span class="line">     for dt_arg in dt_args:</span><br><span class="line"><span class="deletion">-        filepath = args.dtbdir + os.sep + dt_arg[&#x27;filename&#x27;]</span></span><br><span class="line"><span class="addition">+        filepath = dt_arg[&#x27;filename&#x27;]</span></span><br><span class="line"><span class="addition">+        if not os.path.isabs(filepath):</span></span><br><span class="line"><span class="addition">+            for root, dirnames, filenames in os.walk(args.dtbdir):</span></span><br><span class="line"><span class="addition">+                for filename in fnmatch.filter(filenames, os.path.basename(filepath)):</span></span><br><span class="line"><span class="addition">+                    filepath = os.path.join(root, filename)</span></span><br><span class="line">         params[&#x27;dt_file&#x27;] = open(filepath, &#x27;rb&#x27;)</span><br><span class="line">         params[&#x27;dt_offset&#x27;] = 0</span><br><span class="line">         params[&#x27;dt_size&#x27;] = os.fstat(params[&#x27;dt_file&#x27;].fileno()).st_size</span><br><span class="line"><span class="meta">@@ -863,16 +770,13 @@</span> def create_dtbo_image_from_config(fout, argv):</span><br><span class="line">             else:</span><br><span class="line">                 params[key] = dt_arg[key]</span><br><span class="line">         dt_entries.append(DtEntry(**params))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     # Create and write DTBO file</span><br><span class="line"><span class="deletion">-    dtbo = Dtbo(fout, global_args[&#x27;dt_type&#x27;], global_args[&#x27;page_size&#x27;], global_args[&#x27;version&#x27;])</span></span><br><span class="line"><span class="addition">+    dtbo = Dtbo(fout, global_args[&#x27;dt_type&#x27;], global_args[&#x27;page_size&#x27;], version)</span></span><br><span class="line">     dt_entry_buf = dtbo.add_dt_entries(dt_entries)</span><br><span class="line">     dtbo.commit(dt_entry_buf)</span><br><span class="line">     fout.close()</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def print_default_usage(progname):</span><br><span class="line">     &quot;&quot;&quot;Prints program&#x27;s default help string.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         progname: This program&#x27;s name.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="meta">@@ -882,10 +786,8 @@</span> def print_default_usage(progname):</span><br><span class="line">     sb.append(&#x27;    commands:&#x27;)</span><br><span class="line">     sb.append(&#x27;      help, dump, create, cfg_create&#x27;)</span><br><span class="line">     print(&#x27;\n&#x27;.join(sb))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def print_dump_usage(progname):</span><br><span class="line">     &quot;&quot;&quot;Prints usage for &#x27;dump&#x27; sub-command.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         progname: This program&#x27;s name.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="meta">@@ -897,10 +799,8 @@</span> def print_dump_usage(progname):</span><br><span class="line">     sb.append(&#x27;      -b, --dtb &lt;filename&gt;     Dump dtb/dtbo files from image.&#x27;)</span><br><span class="line">     sb.append(&#x27;                               Will output to &lt;filename&gt;.0, &lt;filename&gt;.1, etc.&#x27;)</span><br><span class="line">     print(&#x27;\n&#x27;.join(sb))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def print_create_usage(progname):</span><br><span class="line">     &quot;&quot;&quot;Prints usage for &#x27;create&#x27; subcommand.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         progname: This program&#x27;s name.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="meta">@@ -916,16 +816,14 @@</span> def print_create_usage(progname):</span><br><span class="line">     sb.append(&#x27;      --custom0=&lt;number&gt;&#x27;)</span><br><span class="line">     sb.append(&#x27;      --custom1=&lt;number&gt;&#x27;)</span><br><span class="line">     sb.append(&#x27;      --custom2=&lt;number&gt;\n&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"><span class="addition">+    sb.append(&#x27;      --custom3=&lt;number&gt;\n&#x27;)</span></span><br><span class="line">     sb.append(&#x27;      The value could be a number or a DT node path.&#x27;)</span><br><span class="line">     sb.append(&#x27;      &lt;number&gt; could be a 32-bits digit or hex value, ex. 68000, 0x6800.&#x27;)</span><br><span class="line">     sb.append(&#x27;      &lt;path&gt; format is &lt;full_node_path&gt;:&lt;property_name&gt;, ex. /board/:id,&#x27;)</span><br><span class="line">     sb.append(&#x27;      will read the value in given FTB file with the path.&#x27;)</span><br><span class="line">     print(&#x27;\n&#x27;.join(sb))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def print_cfg_create_usage(progname):</span><br><span class="line">     &quot;&quot;&quot;Prints usage for &#x27;cfg_create&#x27; sub-command.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         progname: This program&#x27;s name.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="meta">@@ -935,10 +833,8 @@</span> def print_cfg_create_usage(progname):</span><br><span class="line">     sb.append(&#x27;      -d, --dtb-dir &lt;dir&gt;      The path to load dtb files.&#x27;)</span><br><span class="line">     sb.append(&#x27;                               Default is load from the current path.&#x27;)</span><br><span class="line">     print(&#x27;\n&#x27;.join(sb))</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def print_usage(cmd, _):</span><br><span class="line">     &quot;&quot;&quot;Prints usage for this program.</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     Args:</span><br><span class="line">         cmd: The string sub-command for which help (usage) is requested.</span><br><span class="line">     &quot;&quot;&quot;</span><br><span class="line"><span class="meta">@@ -946,58 +842,45 @@</span> def print_usage(cmd, _):</span><br><span class="line">     if not cmd:</span><br><span class="line">         print_default_usage(prog_name)</span><br><span class="line">         return</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     HelpCommand = namedtuple(&#x27;HelpCommand&#x27;, &#x27;help_cmd, help_func&#x27;)</span><br><span class="line">     help_commands = (HelpCommand(&#x27;dump&#x27;, print_dump_usage),</span><br><span class="line">                      HelpCommand(&#x27;create&#x27;, print_create_usage),</span><br><span class="line">                      HelpCommand(&#x27;cfg_create&#x27;, print_cfg_create_usage),</span><br><span class="line">                      )</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     if cmd == &#x27;all&#x27;:</span><br><span class="line">         print_default_usage(prog_name)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     for help_cmd, help_func in help_commands:</span><br><span class="line">         if cmd == &#x27;all&#x27; or cmd == help_cmd:</span><br><span class="line">             help_func(prog_name)</span><br><span class="line">             if cmd != &#x27;all&#x27;:</span><br><span class="line">                 return</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     print(&#x27;Unsupported help command: %s&#x27; % cmd, end=&#x27;\n\n&#x27;)</span><br><span class="line">     print_default_usage(prog_name)</span><br><span class="line">     return</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> def main():</span><br><span class="line">     &quot;&quot;&quot;Main entry point for mkdtboimg.&quot;&quot;&quot;</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     parser = argparse.ArgumentParser(prog=&#x27;mkdtboimg.py&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     subparser = parser.add_subparsers(title=&#x27;subcommand&#x27;,</span><br><span class="line">                                       description=&#x27;Valid subcommands&#x27;)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     create_parser = subparser.add_parser(&#x27;create&#x27;, add_help=False)</span><br><span class="line">     create_parser.add_argument(&#x27;argfile&#x27;, nargs=&#x27;?&#x27;,</span><br><span class="line">                                action=&#x27;store&#x27;, help=&#x27;Output File&#x27;,</span><br><span class="line">                                type=argparse.FileType(&#x27;wb&#x27;))</span><br><span class="line">     create_parser.set_defaults(func=create_dtbo_image)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     config_parser = subparser.add_parser(&#x27;cfg_create&#x27;, add_help=False)</span><br><span class="line">     config_parser.add_argument(&#x27;argfile&#x27;, nargs=&#x27;?&#x27;,</span><br><span class="line">                                action=&#x27;store&#x27;,</span><br><span class="line">                                type=argparse.FileType(&#x27;wb&#x27;))</span><br><span class="line">     config_parser.set_defaults(func=create_dtbo_image_from_config)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     dump_parser = subparser.add_parser(&#x27;dump&#x27;, add_help=False)</span><br><span class="line">     dump_parser.add_argument(&#x27;argfile&#x27;, nargs=&#x27;?&#x27;,</span><br><span class="line">                              action=&#x27;store&#x27;,</span><br><span class="line">                              type=argparse.FileType(&#x27;rb&#x27;))</span><br><span class="line">     dump_parser.set_defaults(func=dump_dtbo_image)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     help_parser = subparser.add_parser(&#x27;help&#x27;, add_help=False)</span><br><span class="line">     help_parser.add_argument(&#x27;argfile&#x27;, nargs=&#x27;?&#x27;, action=&#x27;store&#x27;)</span><br><span class="line">     help_parser.set_defaults(func=print_usage)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line">     (subcmd, subcmd_args) = parser.parse_known_args()</span><br><span class="line">     subcmd.func(subcmd.argfile, subcmd_args)</span><br><span class="line"><span class="deletion">-</span></span><br><span class="line"> if __name__ == &#x27;__main__&#x27;:</span><br><span class="line">     main()</span><br><span class="line"><span class="deletion">-- </span></span><br><span class="line">2.45.2</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="android" scheme="https://dpkg123.netlify.app/tags/android/"/>
    
    <category term="PostmarketOS" scheme="https://dpkg123.netlify.app/tags/PostmarketOS/"/>
    
    <category term="ROM移植" scheme="https://dpkg123.netlify.app/tags/ROM%E7%A7%BB%E6%A4%8D/"/>
    
    <category term="刷机" scheme="https://dpkg123.netlify.app/tags/%E5%88%B7%E6%9C%BA/"/>
    
  </entry>
  
  <entry>
    <title>本地搭建第三方alpine repo</title>
    <link href="https://dpkg123.netlify.app/2024/03/23/%E6%9C%AC%E5%9C%B0%E6%90%AD%E5%BB%BA%E7%AC%AC%E4%B8%89%E6%96%B9alpine-repo/"/>
    <id>https://dpkg123.netlify.app/2024/03/23/%E6%9C%AC%E5%9C%B0%E6%90%AD%E5%BB%BA%E7%AC%AC%E4%B8%89%E6%96%B9alpine-repo/</id>
    <published>2024-03-22T19:48:45.000Z</published>
    <updated>2024-03-22T19:48:45.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>警告: 本文章可能会出现部分没说清楚的地方，欢迎补充。</p><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><ul><li>一个 alpine 容器</li><li>一双手</li></ul><h2 id="安装依赖"><a href="#安装依赖" class="headerlink" title="安装依赖"></a>安装依赖</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo apk add abuild</span><br></pre></td></tr></table></figure><h2 id="编写-APKBUILD"><a href="#编写-APKBUILD" class="headerlink" title="编写 APKBUILD"></a>编写 APKBUILD</h2><p>一个简单的 APKBUILD 示例:</p><figure class="highlight bash"><figcaption><span>APKBUILD</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Maintainer: username &lt;username@mail.com&gt;</span></span><br><span class="line">pkgname=project</span><br><span class="line">pkgver=x.x.x</span><br><span class="line">pkgrel=x</span><br><span class="line">pkgdesc=<span class="string">&quot;&quot;</span></span><br><span class="line">url=<span class="string">&quot;https://github.com/username/project&quot;</span></span><br><span class="line"><span class="built_in">arch</span>=<span class="string">&quot;aarch64&quot;</span></span><br><span class="line">_carch=<span class="string">&quot;arm64&quot;</span></span><br><span class="line">license=<span class="string">&quot;Apache-2.0&quot;</span></span><br><span class="line">makedepends=<span class="string">&quot;</span></span><br><span class="line"><span class="string">        bash</span></span><br><span class="line"><span class="string">        go</span></span><br><span class="line"><span class="string">        ...</span></span><br><span class="line"><span class="string">&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Source</span></span><br><span class="line"><span class="built_in">source</span>=<span class="string">&quot;</span></span><br><span class="line"><span class="string">        v0.56.0.tar.gz::https://github.com/username/project/archive/refs/tags/v0.56.0.tar.gz&quot;</span></span><br><span class="line"></span><br><span class="line">builddir=<span class="string">&quot;<span class="variable">$srcdir</span>/<span class="variable">$pkgname</span>-<span class="variable">$pkgver</span>&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">prepare</span></span>() &#123;</span><br><span class="line">        ./configure --prefix=<span class="string">&quot;<span class="variable">$pkgdir</span>&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">build</span></span>() &#123;</span><br><span class="line">        make</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="title">package</span></span>() &#123;</span><br><span class="line">make install</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">sha512sums=<span class="string">&quot;</span></span><br><span class="line"><span class="string">&quot;</span></span><br></pre></td></tr></table></figure><p>一些常见的选项解释:</p><ul><li>pkgname 软件包名称</li><li>pkgver 软件包版本</li><li>pkgrel 软件的附加版本，例如这里的 <code>lzip (1.24.1-r0)</code>:</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">user@localhost ~/a/s/frp (main)&gt; sudo apk add abuild</span><br><span class="line">fetch https://mirrors.bfsu.edu.cn/alpine/edge/main/aarch64/APKINDEX.tar.gz</span><br><span class="line">fetch https://mirrors.bfsu.edu.cn/alpine/edge/community/aarch64/APKINDEX.tar.gz</span><br><span class="line">(1/9) Installing attr (2.5.2-r0)</span><br><span class="line">(2/9) Installing libcap-getcap (2.69-r1)</span><br><span class="line">(3/9) Installing fakeroot (1.33-r0)</span><br><span class="line">(4/9) Installing lzip (1.24.1-r0)</span><br><span class="line">(5/9) Installing openssl (3.2.1-r0)</span><br><span class="line">(6/9) Installing patch (2.7.6-r10)</span><br><span class="line">(7/9) Installing pkgconf (2.1.1-r0)</span><br><span class="line">(8/9) Installing abuild (3.12.0-r5)</span><br><span class="line">Executing abuild-3.12.0-r5.pre-install</span><br><span class="line">(9/9) Installing abuild-sudo (3.12.0-r5)</span><br><span class="line">Executing busybox-1.36.1-r19.trigger</span><br><span class="line">OK: 164 MiB <span class="keyword">in</span> 103 packages</span><br></pre></td></tr></table></figure><ul><li>pkgdesc 软件包描述</li><li>url 项目网址，可以贴github项目</li><li>arch 目标架构，可以通过查看<a href="https://mirrors.tuna.tsinghua.edu.cn/alpine/latest-stable/community/">软件源</a>得知</li><li>license 软件许可</li><li>makedepends 构建所需依赖</li><li>source 软件源码获取，只支持.tar.gz格式，例如:</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">source</span>=<span class="string">&quot;</span></span><br><span class="line"><span class="string">        xxx.tar.gz::&lt;源码下载url&gt;&quot;</span></span><br></pre></td></tr></table></figure><ul><li>builddir 编译软件包的目录，例如如果要在xxx文件夹下编译就写xxx</li><li>prepare函数 可以填写在编译前的一些前置依赖构建，例如</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="title">prepare</span></span>() &#123;</span><br><span class="line">go mod download</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这样就可以在准备阶段下载go软件包</p><ul><li>build函数 一般填写编译指令，例如 make</li><li>install函数 一般填写安装指令，例如 make install</li><li>sh512sums 使用 abuild checksum自动填充:</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">user@localhost ~/a/s/frp (main)&gt; abuild checksum</span><br><span class="line">&gt;&gt;&gt; frp: Fetching v0.56.0.tar.gz::https://github.com/fatedier/frp/archive/refs/tags/v0.56.0.tar.gz</span><br><span class="line">  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current</span><br><span class="line">                                 Dload  Upload   Total   Spent    Left  Speed</span><br><span class="line">  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0</span><br><span class="line">100 1054k    0 1054k    0     0   467k      0 --:--:--  0:00:02 --:--:-- 1291k</span><br><span class="line">&gt;&gt;&gt; frp: Updating the sha512sums <span class="keyword">in</span> /home/user/alpine-software-repos/source/frp/APKBUILD...</span><br></pre></td></tr></table></figure><p>当然也可以编写例如post-install脚本来在安装后进行一些初始化功能。</p><h3 id="一些常见变量的解释"><a href="#一些常见变量的解释" class="headerlink" title="一些常见变量的解释"></a>一些常见变量的解释</h3><ul><li>$srcdir 一般为自动设定</li><li>$pkgname APKBUILD 中设定的软件包名</li><li>$pkgver APKBUILD 中设定的软件包版本</li></ul><h2 id="构建"><a href="#构建" class="headerlink" title="构建"></a>构建</h2><p>执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">abuild -r</span><br></pre></td></tr></table></figure><p>构建的软件包在用户文件夹下的package文件夹<br>下面是一个详细的构建流程，以构建frp为例:</p><figure class="highlight bash"><figcaption><span>logcat</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br></pre></td><td class="code"><pre><span class="line">user@localhost ~/a/s/frp (main)&gt; sudo abuild -r -f -F</span><br><span class="line">&gt;&gt;&gt; frp: Building <span class="built_in">source</span>/frp 0.56.0-r0 (using abuild 3.12.0-r5) started Sat, 23 Mar 2024 23:38:40 +0800</span><br><span class="line">&gt;&gt;&gt; frp: Checking sanity of /home/user/alpine-software-repos/source/frp/APKBUILD...</span><br><span class="line">&gt;&gt;&gt; frp: Analyzing dependencies...</span><br><span class="line">&gt;&gt;&gt; frp: Installing <span class="keyword">for</span> build: build-base bash go wget</span><br><span class="line">WARNING: opening /root/packages//source: No such file or directory</span><br><span class="line">(1/18) Installing jansson (2.14-r4)</span><br><span class="line">(2/18) Installing zstd-libs (1.5.5-r9)</span><br><span class="line">(3/18) Installing binutils (2.42-r0)</span><br><span class="line">(4/18) Installing libgomp (13.2.1_git20240309-r0)</span><br><span class="line">(5/18) Installing libatomic (13.2.1_git20240309-r0)</span><br><span class="line">(6/18) Installing gmp (6.3.0-r0)</span><br><span class="line">(7/18) Installing isl26 (0.26-r1)</span><br><span class="line">(8/18) Installing mpfr4 (4.2.1-r0)</span><br><span class="line">(9/18) Installing mpc1 (1.3.1-r1)</span><br><span class="line">(10/18) Installing gcc (13.2.1_git20240309-r0)</span><br><span class="line">(11/18) Installing libstdc++-dev (13.2.1_git20240309-r0)</span><br><span class="line">(12/18) Installing musl-dev (1.2.5-r0)</span><br><span class="line">(13/18) Installing g++ (13.2.1_git20240309-r0)</span><br><span class="line">(14/18) Installing fortify-headers (1.1-r3)</span><br><span class="line">(15/18) Installing build-base (0.5-r3)</span><br><span class="line">(16/18) Installing binutils-gold (2.42-r0)</span><br><span class="line">(17/18) Installing go (1.22.1-r1)</span><br><span class="line">(18/18) Installing .makedepends-frp (20240323.153842)</span><br><span class="line">Executing busybox-1.36.1-r19.trigger</span><br><span class="line">OK: 542 MiB <span class="keyword">in</span> 121 packages</span><br><span class="line">&gt;&gt;&gt; frp: Cleaning up srcdir</span><br><span class="line">&gt;&gt;&gt; frp: Cleaning up pkgdir</span><br><span class="line">&gt;&gt;&gt; frp: Cleaning up tmpdir</span><br><span class="line">&gt;&gt;&gt; frp: Fetching v0.56.0.tar.gz::https://github.com/fatedier/frp/archive/refs/tags/v0.56.0.tar.gz</span><br><span class="line">&gt;&gt;&gt; frp: Fetching v0.56.0.tar.gz::https://github.com/fatedier/frp/archive/refs/tags/v0.56.0.tar.gz</span><br><span class="line">&gt;&gt;&gt; frp: Checking sha512sums...</span><br><span class="line">v0.56.0.tar.gz: OK</span><br><span class="line">&gt;&gt;&gt; frp: Unpacking /var/cache/distfiles/v0.56.0.tar.gz...</span><br><span class="line">go <span class="built_in">fmt</span> ./...</span><br><span class="line"><span class="built_in">env</span> CGO_ENABLED=0 go build -trimpath -ldflags <span class="string">&quot;-s -w&quot;</span> -tags frps -o bin/frps ./cmd/frps</span><br><span class="line">go version go1.22.1 linux/arm64</span><br><span class="line"><span class="built_in">env</span> CGO_ENABLED=0 go build -trimpath -ldflags <span class="string">&quot;-s -w&quot;</span> -tags frpc -o bin/frpc ./cmd/frpc</span><br><span class="line">&gt;&gt;&gt; WARNING: frp: APKBUILD does not run any tests!</span><br><span class="line">    Alpine policy will soon require that packages have any relevant testsuites run during the build process.</span><br><span class="line">    To fix, either define a check() <span class="keyword">function</span>, or <span class="built_in">declare</span> !check <span class="keyword">in</span> <span class="variable">$options</span> to indicate the package does not have a testsuite.</span><br><span class="line"><span class="built_in">mkdir</span>: created directory <span class="string">&#x27;/home/user/alpine-software-repos/source/frp/pkg/frp/etc&#x27;</span></span><br><span class="line"><span class="built_in">mkdir</span>: created directory <span class="string">&#x27;/home/user/alpine-software-repos/source/frp/pkg/frp/etc/frp&#x27;</span></span><br><span class="line">--2024-03-23 23:39:49--  https://github.com/fatedier/frp/raw/dev/conf/frpc_full_example.toml</span><br><span class="line">Resolving github.com (github.com)... 28.0.0.144</span><br><span class="line">Connecting to github.com (github.com)|28.0.0.144|:443... connected.</span><br><span class="line">HTTP request sent, awaiting response... 302 Found</span><br><span class="line">Location: https://raw.githubusercontent.com/fatedier/frp/dev/conf/frpc_full_example.toml [following]</span><br><span class="line">--2024-03-23 23:39:52--  https://raw.githubusercontent.com/fatedier/frp/dev/conf/frpc_full_example.toml</span><br><span class="line">Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 28.0.2.190</span><br><span class="line">Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|28.0.2.190|:443... connected.</span><br><span class="line">HTTP request sent, awaiting response... 200 OK</span><br><span class="line">Length: 12411 (12K) [text/plain]</span><br><span class="line">Saving to: <span class="string">&#x27;/home/user/alpine-software-repos/source/frp/pkg/frp/etc/frp/frpc.toml&#x27;</span></span><br><span class="line"></span><br><span class="line">/home/user/alpine-r 100%[===============================&gt;]  12.12K  --.-KB/s    <span class="keyword">in</span> 0.002s</span><br><span class="line"></span><br><span class="line">2024-03-23 23:39:54 (7.84 MB/s) - <span class="string">&#x27;/home/user/alpine-software-repos/source/frp/pkg/frp/etc/frp/frpc.toml&#x27;</span> saved [12411/12411]</span><br><span class="line"></span><br><span class="line">--2024-03-23 23:39:54--  https://github.com/fatedier/frp/raw/dev/conf/frps_full_example.toml</span><br><span class="line">Resolving github.com (github.com)... 28.0.0.144</span><br><span class="line">Connecting to github.com (github.com)|28.0.0.144|:443... connected.</span><br><span class="line">HTTP request sent, awaiting response... 302 Found</span><br><span class="line">Location: https://raw.githubusercontent.com/fatedier/frp/dev/conf/frps_full_example.toml [following]</span><br><span class="line">--2024-03-23 23:39:58--  https://raw.githubusercontent.com/fatedier/frp/dev/conf/frps_full_example.toml</span><br><span class="line">Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 28.0.2.190</span><br><span class="line">Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|28.0.2.190|:443... connected.</span><br><span class="line">HTTP request sent, awaiting response... 200 OK</span><br><span class="line">Length: 6162 (6.0K) [text/plain]</span><br><span class="line">Saving to: <span class="string">&#x27;/home/user/alpine-software-repos/source/frp/pkg/frp/etc/frp/frps.toml&#x27;</span></span><br><span class="line"></span><br><span class="line">/home/user/alpine-r 100%[===============================&gt;]   6.02K  --.-KB/s    <span class="keyword">in</span> 0.001s</span><br><span class="line"></span><br><span class="line">2024-03-23 23:40:01 (7.36 MB/s) - <span class="string">&#x27;/home/user/alpine-software-repos/source/frp/pkg/frp/etc/frp/frps.toml&#x27;</span> saved [6162/6162]</span><br><span class="line"></span><br><span class="line">&gt;&gt;&gt; frp: Running postcheck <span class="keyword">for</span> frp</span><br><span class="line">&gt;&gt;&gt; frp: Preparing package frp...</span><br><span class="line">&gt;&gt;&gt; frp: Stripping binaries</span><br><span class="line">&gt;&gt;&gt; frp: Scanning shared objects</span><br><span class="line">&gt;&gt;&gt; frp: Tracing dependencies...</span><br><span class="line">&gt;&gt;&gt; frp: Package size: 31.8 MB</span><br><span class="line">&gt;&gt;&gt; frp: Compressing data...</span><br><span class="line">&gt;&gt;&gt; frp: Create checksum...</span><br><span class="line">&gt;&gt;&gt; frp: Create frp-0.56.0-r0.apk</span><br><span class="line">&gt;&gt;&gt; frp: Build complete at Sat, 23 Mar 2024 23:40:08 +0800 elapsed time 0h 1m 28s</span><br><span class="line">&gt;&gt;&gt; frp: Cleaning up srcdir</span><br><span class="line">&gt;&gt;&gt; frp: Cleaning up pkgdir</span><br><span class="line">&gt;&gt;&gt; frp: Uninstalling dependencies...</span><br><span class="line">(1/18) Purging .makedepends-frp (20240323.153842)</span><br><span class="line">(2/18) Purging build-base (0.5-r3)</span><br><span class="line">(3/18) Purging g++ (13.2.1_git20240309-r0)</span><br><span class="line">(4/18) Purging libstdc++-dev (13.2.1_git20240309-r0)</span><br><span class="line">(5/18) Purging gcc (13.2.1_git20240309-r0)</span><br><span class="line">(6/18) Purging binutils (2.42-r0)</span><br><span class="line">(7/18) Purging libatomic (13.2.1_git20240309-r0)</span><br><span class="line">(8/18) Purging libgomp (13.2.1_git20240309-r0)</span><br><span class="line">(9/18) Purging fortify-headers (1.1-r3)</span><br><span class="line">(10/18) Purging go (1.22.1-r1)</span><br><span class="line">(11/18) Purging binutils-gold (2.42-r0)</span><br><span class="line">(12/18) Purging isl26 (0.26-r1)</span><br><span class="line">(13/18) Purging jansson (2.14-r4)</span><br><span class="line">(14/18) Purging mpc1 (1.3.1-r1)</span><br><span class="line">(15/18) Purging mpfr4 (4.2.1-r0)</span><br><span class="line">(16/18) Purging musl-dev (1.2.5-r0)</span><br><span class="line">(17/18) Purging zstd-libs (1.5.5-r9)</span><br><span class="line">(18/18) Purging gmp (6.3.0-r0)</span><br><span class="line">Executing busybox-1.36.1-r19.trigger</span><br><span class="line">OK: 164 MiB <span class="keyword">in</span> 103 packages</span><br><span class="line">&gt;&gt;&gt; frp: Updating the <span class="built_in">source</span>/aarch64 repository index...</span><br><span class="line">&gt;&gt;&gt; frp: Signing the index...</span><br></pre></td></tr></table></figure><h2 id="搭建软件源"><a href="#搭建软件源" class="headerlink" title="搭建软件源"></a>搭建软件源</h2><p>创建文件夹</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">mkdir</span> -p /var/www/root/alpine</span><br></pre></td></tr></table></figure><p>初始化新的APK仓库</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">apk index -o APKINDEX.tar.gz /var/www/root/alpine/*.apk</span><br></pre></td></tr></table></figure><p>开启nginx</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nginx -s reload</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="alpine" scheme="https://dpkg123.netlify.app/tags/alpine/"/>
    
    <category term="软件源" scheme="https://dpkg123.netlify.app/tags/%E8%BD%AF%E4%BB%B6%E6%BA%90/"/>
    
  </entry>
  
  <entry>
    <title>折腾ts action遇到的其中一个问题</title>
    <link href="https://dpkg123.netlify.app/2024/02/12/%E6%8A%98%E8%85%BEts-action%E9%81%87%E5%88%B0%E7%9A%84%E5%85%B6%E4%B8%AD%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/"/>
    <id>https://dpkg123.netlify.app/2024/02/12/%E6%8A%98%E8%85%BEts-action%E9%81%87%E5%88%B0%E7%9A%84%E5%85%B6%E4%B8%AD%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98/</id>
    <published>2024-02-11T22:01:08.000Z</published>
    <updated>2024-02-11T22:01:08.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h3 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h3><p>这是一个简单的ts示例:</p><figure class="highlight bash"><figcaption><span>TypeScript</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">import os from <span class="string">&quot;os&quot;</span>;</span><br><span class="line">import * as core from <span class="string">&quot;@actions/core&quot;</span>;</span><br><span class="line">import * as io from <span class="string">&quot;@actions/io&quot;</span>;</span><br><span class="line">import * as <span class="built_in">exec</span> from <span class="string">&quot;@actions/exec&quot;</span>;</span><br><span class="line"></span><br><span class="line">async <span class="keyword">function</span> post(): Promise&lt;void&gt; &#123;</span><br><span class="line">    <span class="keyword">if</span> (await io.which(<span class="string">&quot;<span class="variable">$HOME</span>/gcc-64/bin&quot;</span>)) &#123;</span><br><span class="line">        await exec.exec(<span class="string">&quot;HOME/gcc-64/bin/aarch64-linux-android-as --version&quot;</span>);</span><br><span class="line">        <span class="built_in">return</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (await io.which(<span class="string">&quot;<span class="variable">$HOME</span>/clang/bin/clang&quot;</span>)) &#123;</span><br><span class="line">        await exec.exec(<span class="string">&quot;<span class="variable">$HOME</span>/clang/bin/clang --version&quot;</span>);</span><br><span class="line">        <span class="built_in">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">(async () =&gt; &#123;</span><br><span class="line">    try &#123;</span><br><span class="line">        await post();</span><br><span class="line">    &#125; catch (error) &#123;</span><br><span class="line">        console.log(<span class="string">&quot;Failed to run post step.&quot;</span>);</span><br><span class="line">        <span class="built_in">return</span> 1;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure><p>请分析当编译成cjs时运行node index.js时当$HOME&#x2F;clang和$HOME&#x2F;gcc-64都不存在时是否会报错。</p><h3 id="解答"><a href="#解答" class="headerlink" title="解答"></a>解答</h3><p>答案:不会。</p><p>假设<code>io.which</code>方法正常工作，如果两个路径<code>$HOME/gcc-64/bin</code>和<code>$HOME/clang/bin</code>都不存在，则<code>io.which</code>返回的是<code>undefined</code>或者<code>false</code>，因此两个条件判断都不满足，函数将直接结束执行，并不会执行<code>await exec.exec(...)</code>语句，也就不会抛出错误。</p><p>在这种情况下，如果<code>io.which</code>方法和<code>exec.exec</code>方法实现都是正确的，只有在尝试执行不存在的路径时才会报错。但代码中并没有提供发生错误时的处理，只是在最外层的自调用匿名函数中捕获异常，并打印“Failed to run post step.”。如果异常未被内部<code>try-catch</code>正确处理，确实会导致运行时报错。</p><p>因此，如果其他部分实现正确，环境不存在导致的错误会被内部逻辑处理，不会向用户抛出异常。</p><p>解决方法:<br>将</p><figure class="highlight bash"><figcaption><span>TypeScript</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">console.log(<span class="string">&quot;Failed to run post step.&quot;</span>);</span><br><span class="line">        <span class="built_in">return</span> 1;</span><br></pre></td></tr></table></figure><p>改成</p><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&quot;Failed to run post step.&quot;</span>);</span><br><span class="line">        process.<span class="title function_">exit</span>(<span class="number">1</span>);</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="TypeScript" scheme="https://dpkg123.netlify.app/tags/TypeScript/"/>
    
    <category term="Github Actions" scheme="https://dpkg123.netlify.app/tags/Github-Actions/"/>
    
  </entry>
  
  <entry>
    <title>dtc编译教程</title>
    <link href="https://dpkg123.netlify.app/2024/01/29/dtc%E7%BC%96%E8%AF%91%E6%95%99%E7%A8%8B/"/>
    <id>https://dpkg123.netlify.app/2024/01/29/dtc%E7%BC%96%E8%AF%91%E6%95%99%E7%A8%8B/</id>
    <published>2024-01-29T15:26:53.000Z</published>
    <updated>2024-01-29T15:26:53.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><blockquote><p>警告:本文章是给 arm64 linux 准备的。</p></blockquote><h2 id="安装依赖"><a href="#安装依赖" class="headerlink" title="安装依赖"></a>安装依赖</h2><p>直接从 lineageOS 依赖抄一份就行了。</p><p>除此之外还要安装以下东西:</p><ul><li>bison</li><li>pkg-config</li><li>libyaml-dev</li></ul><h2 id="下载源码"><a href="#下载源码" class="headerlink" title="下载源码"></a>下载源码</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget https://android.googlesource.com/platform/external/dtc/archive/refs/heads/android11-release.tar.gz -o dtc.tar.gz</span><br></pre></td></tr></table></figure><p>如果要下载其他版本就把 android11 改成 android[版本号] 就行。最低为 android10.</p><h2 id="解压"><a href="#解压" class="headerlink" title="解压"></a>解压</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -xzf dtc.tar.gz </span><br></pre></td></tr></table></figure><h2 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h2><p>然后直接编译即可。编译后会生成 dtc 文件。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make dtc -j8</span><br></pre></td></tr></table></figure><h2 id="debug"><a href="#debug" class="headerlink" title="debug"></a>debug</h2><p>这里阐述下遇到的问题:</p><h3 id="make-没有规则可制作目标“dtc-parser-h”，由“dtc-lexer-lex-o”-需求。-停止。"><a href="#make-没有规则可制作目标“dtc-parser-h”，由“dtc-lexer-lex-o”-需求。-停止。" class="headerlink" title="make: *** 没有规则可制作目标“dtc-parser.h”，由“dtc-lexer.lex.o” 需求。 停止。"></a>make: *** 没有规则可制作目标“dtc-parser.h”，由“dtc-lexer.lex.o” 需求。 停止。</h3><figure class="highlight bash"><figcaption><span>logcat</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">         BISON dtc-parser.tab.c</span><br><span class="line">dtc-parser.y: 警告: 3 项偏移/归约冲突 [-Wconflicts-sr]</span><br><span class="line">dtc-parser.y: note: rerun with option <span class="string">&#x27;-Wcounterexamples&#x27;</span> to generate conflict counterexamples</span><br><span class="line">         LEX dtc-lexer.lex.c</span><br><span class="line">         DEP treesource.c</span><br><span class="line">         DEP livetree.c</span><br><span class="line">         DEP fstree.c</span><br><span class="line">         DEP flattree.c</span><br><span class="line">         DEP dtc.c</span><br><span class="line">         DEP data.c</span><br><span class="line">         DEP checks.c</span><br><span class="line">         DEP convert-dtsv0-lexer.lex.c</span><br><span class="line">         DEP dtc-parser.tab.c</span><br><span class="line">         DEP dtc-lexer.lex.c</span><br><span class="line">         CC srcpos.o</span><br><span class="line">         CC util.o</span><br><span class="line">         CC convert-dtsv0-lexer.lex.o</span><br><span class="line">         CC dtc.o</span><br><span class="line">         CC checks.o</span><br><span class="line">         CC data.o</span><br><span class="line">         CC flattree.o</span><br><span class="line">         CC fstree.o</span><br><span class="line">         CC livetree.o</span><br><span class="line">         CC treesource.o</span><br><span class="line">make: *** 没有规则可制作目标“dtc-parser.h”，由“dtc-lexer.lex.o” 需求。 停止。</span><br><span class="line">make: *** 正在等待未完成的任务....</span><br></pre></td></tr></table></figure><p>解决方法: 手动执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bison -d dtc-parser.y -o dtc-parser.h</span><br></pre></td></tr></table></figure><p>然后有可能遇到以下错误:</p><figure class="highlight bash"><figcaption><span>logcat</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">         DEP dtc-parser.tab.c</span><br><span class="line">         DEP dtc-lexer.lex.c</span><br><span class="line">         CC dtc-lexer.lex.o</span><br><span class="line">         CC dtc-parser.tab.o</span><br><span class="line">         LD dtc</span><br><span class="line">/bin/ld: dtc-parser.tab.o:/home/user/rootfs/android10/dtc-parser.tab.c:1086: multiple definition of `yylloc<span class="string">&#x27;; dtc-lexer.lex.o:/home/user/rootfs/android10/dtc-lexer.l:41: first defined here</span></span><br><span class="line"><span class="string">collect2: 笨蛋！ld 返回 1</span></span><br><span class="line"><span class="string">make: *** [Makefile:312：dtc] 错误 1</span></span><br></pre></td></tr></table></figure><p>解决办法: 删掉 dtc-parser.tab.c 第1086行。<br>曾经也试过将 <code>YYLTYPE yylloc</code> 改成 <code>extern YYLTYPE yylloc</code> ，但是会出现以下问题:</p><figure class="highlight bash"><figcaption><span>logcat</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">         DEP dtc-parser.tab.c</span><br><span class="line">         CC dtc-parser.tab.o</span><br><span class="line">dtc-parser.tab.c:1086:16: 笨蛋！对‘yylloc’冗余的重声明 [-Werror=redundant-decls]</span><br><span class="line"> 1086 | extern YYLTYPE yylloc</span><br><span class="line">      |                ^~~~~~</span><br><span class="line">In file included from dtc-parser.tab.c:112:</span><br><span class="line">dtc-parser.tab.h:131:16: 才...才不会告诉你...：‘yylloc’的前一个声明</span><br><span class="line">  131 | extern YYLTYPE yylloc;</span><br><span class="line">      |                ^~~~~~</span><br><span class="line">cc1：所有的警告都被当作是错误</span><br><span class="line">make: *** [Makefile:316：dtc-parser.tab.o] 错误 1</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="android" scheme="https://dpkg123.netlify.app/tags/android/"/>
    
    <category term="dtc" scheme="https://dpkg123.netlify.app/tags/dtc/"/>
    
    <category term="dtb" scheme="https://dpkg123.netlify.app/tags/dtb/"/>
    
  </entry>
  
  <entry>
    <title>OPPO Reno6 ColorOS13.1内核源码编译记录</title>
    <link href="https://dpkg123.netlify.app/2024/01/15/OPPO%20Reno6%20ColorOS13.1%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91%E8%AE%B0%E5%BD%95/"/>
    <id>https://dpkg123.netlify.app/2024/01/15/OPPO%20Reno6%20ColorOS13.1%E5%86%85%E6%A0%B8%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91%E8%AE%B0%E5%BD%95/</id>
    <published>2024-01-15T15:03:25.000Z</published>
    <updated>2024-01-15T15:03:25.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>前几天看到<a href="https://github.com/oppo-source/android_kernel_oppo_mt6877/"> OPPO 的 mt6877 源码</a>放出了<a href="https://github.com/oppo-source/android_kernel_oppo_mt6877/tree/oppo/mt6877_t_13.1.0_reno6_5g"> Reno6 ColorOS13.1 分支</a>。遂拉下来编译。</p><h2 id="Config"><a href="#Config" class="headerlink" title="Config"></a>Config</h2><p>首先需要知道 Reno6 ColorOS13.1 的内核用的是什么配置。</p><p>保险起见还是应该直接拿本机的 config 文件来进行编译。但是一方面 ColorOS13 太烂，烂的依托答辩。另一方面笔者没有解锁 Bootloader.而解锁又会清除数据。所以这条道路基本是行不通的。</p><p>根据查看本机信息得到 ColorOS 11.x&#x2F;12.x 的内核版本是不变的，使用的配置均为 k6877v1_64_defconfig ，遂使用 k6877v1_64_k419_defconfig 来进行编译。</p><h2 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h2><p>这方面就没有啥太多想说的，无非就是安装依赖，拉取源码，然后写一个脚本编译然后就该干啥干啥了。</p><p>哦对了，如果要编译 OPLUS 内核的话，建议在 内核源码根目录的 nativefeatrues.memk 或者 oplus_native_features.mk 注释掉以下内容:</p><p>还有，如果是新机型的话，别忘了拉vendor源码。</p><figure class="highlight bash"><figcaption><span>Makefile</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#OPLUS_FEATURE_SECURE_EXECGUARD=yes</span></span><br><span class="line"><span class="comment">#OPLUS_FEATURE_SECURE_GUARD=yes</span></span><br><span class="line"><span class="comment">#OPLUS_FEATURE_SECURE_KEVENTUPLOAD=yes</span></span><br><span class="line"><span class="comment">#OPLUS_FEATURE_SECURE_KEYINTERFACESGUARD=yes</span></span><br><span class="line"><span class="comment">#OPLUS_FEATURE_SECURE_MOUNTGUARD=yes</span></span><br><span class="line"><span class="comment">#OPLUS_FEATURE_SECURE_ROOTGUARD=yes</span></span><br></pre></td></tr></table></figure><p>还要注释相关配置文件的内容:</p><figure class="highlight bash"><figcaption><span>defconfig</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#ifdef CONFIG_OPLUS_SECURE_GUARD</span></span><br><span class="line">CONFIG_OPLUS_ROOT_CHECK=y</span><br><span class="line">CONFIG_OPLUS_EXECVE_BLOCK=y</span><br><span class="line">CONFIG_OPLUS_MOUNT_BLOCK=y</span><br><span class="line">CONFIG_OPLUS_SECURE_GUARD=y</span><br><span class="line"><span class="comment">#endif /*CONFIG_OPLUS_SECURE_GUARD*/</span></span><br></pre></td></tr></table></figure><h2 id="fix"><a href="#fix" class="headerlink" title="fix"></a>fix</h2><p>然而不出以为的话应该会出意外。</p><p>然后果然出意外了。</p><figure class="highlight bash"><figcaption><span>logcat</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">In file included from ../drivers/misc/mediatek/sensor/2.0/oplus_sensor_devinfo/oplus_sensor_feedback/sensor_feedback.c:24:</span><br><span class="line">In file included from ../drivers/misc/mediatek/scp/rv/scp_helper.h:15:</span><br><span class="line">../drivers/misc/mediatek/scp/rv/scp_feature_define.h:9:10: fatal error: <span class="string">&#x27;scp.h&#x27;</span> file not found</span><br><span class="line"><span class="comment">#include &quot;scp.h&quot;</span></span><br><span class="line">         ^~~~~~~</span><br><span class="line">1 error generated.</span><br><span class="line">make[8]: *** [../scripts/Makefile.build:334: drivers/misc/mediatek/sensor/2.0/oplus_sensor_devinfo/oplus_sensor_feedback/sensor_feedback.o] Error 1</span><br><span class="line">make[7]: *** [../scripts/Makefile.build:637: drivers/misc/mediatek/sensor/2.0/oplus_sensor_devinfo/oplus_sensor_feedback] Error 2</span><br><span class="line">make[6]: *** [../scripts/Makefile.build:637: drivers/misc/mediatek/sensor/2.0/oplus_sensor_devinfo] Error 2</span><br><span class="line">make[5]: *** [../scripts/Makefile.build:637: drivers/misc/mediatek/sensor/2.0] Error 2</span><br><span class="line">make[4]: *** [../scripts/Makefile.build:637: drivers/misc/mediatek/sensor] Error 2</span><br><span class="line">make[4]: *** Waiting <span class="keyword">for</span> unfinished <span class="built_in">jobs</span>....</span><br><span class="line">  CC      drivers/misc/mediatek/scp/rv/scp_hwvoter_dbg.o</span><br><span class="line">  AR      drivers/misc/mediatek/sspm/v2/built-in.a</span><br><span class="line">  AR      drivers/misc/mediatek/sspm/built-in.a</span><br><span class="line">  CC      drivers/spi/spi.o</span><br><span class="line">  CC      drivers/spi/spi-mt65xx.o</span><br><span class="line">  CC      drivers/spi/spi-mt65xx-dev.o</span><br><span class="line">  AR      drivers/misc/mediatek/scp/rv/built-in.a</span><br><span class="line">  AR      drivers/misc/mediatek/scp/built-in.a</span><br><span class="line">make[3]: *** [../scripts/Makefile.build:637: drivers/misc/mediatek] Error 2</span><br><span class="line">make[2]: *** [../scripts/Makefile.build:637: drivers/misc] Error 2</span><br><span class="line">make[2]: *** Waiting <span class="keyword">for</span> unfinished <span class="built_in">jobs</span>....</span><br></pre></td></tr></table></figure><p>遂通过 find 命令找到了该文件的位置:</p><figure class="highlight bash"><figcaption><span>find</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">drivers/misc/mediatek/scp/include/scp.h</span><br></pre></td></tr></table></figure><p>于是就通过 ln 命令进行了软连接。考虑到头文件里可能还嵌入头文件，遂把剩下的头文件也 ln了过去。</p><p>你以为这就完了吗？</p><p>接着编译发现又出现了以下问题:</p><figure class="highlight bash"><figcaption><span>logcat</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"> DTC     <span class="built_in">arch</span>/arm64/boot/dts/mediatek/oplus6877_20181.dtb</span><br><span class="line">  AR      lib/crypto/built-in.a</span><br><span class="line">../arch/arm64/boot/dts/mediatek/oplus6877_20181.dts:1039:10: fatal error: <span class="string">&#x27;oplus6877_20181/cust.dtsi&#x27;</span> file not found</span><br><span class="line"><span class="comment">#include &quot;oplus6877_20181/cust.dtsi&quot;</span></span><br><span class="line">         ^~~~~~~~~~~~~~~~~~~~~~~~~~~</span><br><span class="line">1 error generated.</span><br><span class="line">make[3]: *** [scripts/Makefile.lib:298: <span class="built_in">arch</span>/arm64/boot/dts/mediatek/oplus6877_20181.dtb] Error 1</span><br><span class="line">make[2]: *** [../scripts/Makefile.build:637: <span class="built_in">arch</span>/arm64/boot/dts/mediatek] Error 2</span><br><span class="line">make[1]: *** [<span class="built_in">arch</span>/arm64/Makefile:153: dtbs] Error 2</span><br><span class="line">make[1]: *** Waiting <span class="keyword">for</span> unfinished <span class="built_in">jobs</span>....</span><br><span class="line">  CC      lib/fonts/fonts.o</span><br><span class="line">  CC      lib/fonts/font_8x16.o</span><br></pre></td></tr></table></figure><p>然而很抱歉，笔者翻阅了真我一加的 mt6877 源码后也没有找到这个文件，于是就注释掉了相关选项:</p><figure class="highlight bash"><figcaption><span>k6877v1_64_k419_defconfig</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y</span></span><br><span class="line"><span class="comment">#CONFIG_BUILD_ARM64_DTB_OVERLAY_IMAGE=y</span></span><br><span class="line"><span class="comment">#CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES=&quot;mediatek/mt6877&quot;</span></span><br><span class="line"><span class="comment">#CONFIG_BUILD_ARM64_DTB_OVERLAY_IMAGE_NAMES=&quot;mediatek/oplus6877_20181 mediatek/oplus6877_20181_v1 mediatek/oplus6877_20181_v2 mediatek/oplus6877_20181_v3 mediatek/oplus6877_20181_v4 mediatek/oplus6877_20355 mediatek/oplus6877_20355_v1 mediatek/oplus6877_20355_v2 mediatek/k6877v1_64_k419_dummy8 mediatek/oplus6877_21081  mediatek/oplus6877_212A1 mediatek/oplus6877_21851 mediatek/oplus6877_22612 mediatek/oplus6877_2169E mediatek/oplus6877_21711 mediatek/oplus6877_22710 mediatek/oplus6877_22633 mediatek/oplus6877_22037 mediatek/oplus6877_22277&quot;</span></span><br></pre></td></tr></table></figure><p>而且笔者也并没有在 arch&#x2F;arm64&#x2F;boot&#x2F;Makefile 里找到有关于 Image.gz-dtb 和 dtbo 的内容。</p><p>最后编译出了 Image.gz 文件</p><figure class="highlight bash"><figcaption><span>logcat</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">  AR      drivers/misc/built-in.a</span><br><span class="line">  AR      drivers/built-in.a</span><br><span class="line">  GEN     .version</span><br><span class="line">  CHK     include/generated/compile.h</span><br><span class="line">  AR      built-in.a</span><br><span class="line">  MODPOST vmlinux.o</span><br><span class="line">WARNING: modpost: Found 1 section mismatch(es).</span><br><span class="line">To see full details build your kernel with:</span><br><span class="line"><span class="string">&#x27;make CONFIG_DEBUG_SECTION_MISMATCH=y&#x27;</span></span><br><span class="line">  KSYM    .tmp_kallsyms1.o</span><br><span class="line">  KSYM    .tmp_kallsyms2.o</span><br><span class="line">  LD      vmlinux</span><br><span class="line">  SORTEX  vmlinux</span><br><span class="line">  SYSMAP  System.map</span><br><span class="line">  OBJCOPY <span class="built_in">arch</span>/arm64/boot/Image</span><br><span class="line">  Building modules, stage 2.</span><br><span class="line">  MODPOST 7 modules</span><br><span class="line">WARNING: sound/soc/codecs/mt6357-accdet: <span class="string">&#x27;accdet_read_audio_res&#x27;</span> exported twice. Previous <span class="built_in">export</span> was <span class="keyword">in</span> vmlinux</span><br><span class="line">WARNING: sound/soc/codecs/mt6357-accdet: <span class="string">&#x27;accdet_late_init&#x27;</span> exported twice. Previous <span class="built_in">export</span> was <span class="keyword">in</span> vmlinux</span><br><span class="line">WARNING: sound/soc/codecs/mt6359-accdet: <span class="string">&#x27;accdet_read_audio_res&#x27;</span> exported twice. Previous <span class="built_in">export</span> was <span class="keyword">in</span> vmlinux</span><br><span class="line">WARNING: sound/soc/codecs/mt6359-accdet: <span class="string">&#x27;accdet_late_init&#x27;</span> exported twice. Previous <span class="built_in">export</span> was <span class="keyword">in</span> vmlinux</span><br><span class="line">  CC      drivers/video/backlight/lcd.mod.o</span><br><span class="line">  CC      kernel/kheaders.mod.o</span><br><span class="line">  CC      kernel/trace/trace_mmstat.mod.o</span><br><span class="line">  GZIP    <span class="built_in">arch</span>/arm64/boot/Image.gz</span><br><span class="line">  CC      net/ipv4/tcp_htcp.mod.o</span><br></pre></td></tr></table></figure><p><del>附: 笔者比对了 android_kernel_oppo_mtk_4.19 ，除了配置文件不一样，其他地方应该是相同的</del></p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="kernel" scheme="https://dpkg123.netlify.app/tags/kernel/"/>
    
    <category term="android" scheme="https://dpkg123.netlify.app/tags/android/"/>
    
    <category term="OPPO" scheme="https://dpkg123.netlify.app/tags/OPPO/"/>
    
  </entry>
  
  <entry>
    <title>Android boot.img 文件的解包、修改与重打包小记</title>
    <link href="https://dpkg123.netlify.app/2023/12/24/Android%20boot.img%20%E6%96%87%E4%BB%B6%E7%9A%84%E8%A7%A3%E5%8C%85%E3%80%81%E4%BF%AE%E6%94%B9%E4%B8%8E%E9%87%8D%E6%89%93%E5%8C%85%E5%B0%8F%E8%AE%B0/"/>
    <id>https://dpkg123.netlify.app/2023/12/24/Android%20boot.img%20%E6%96%87%E4%BB%B6%E7%9A%84%E8%A7%A3%E5%8C%85%E3%80%81%E4%BF%AE%E6%94%B9%E4%B8%8E%E9%87%8D%E6%89%93%E5%8C%85%E5%B0%8F%E8%AE%B0/</id>
    <published>2023-12-24T12:01:05.000Z</published>
    <updated>2023-12-24T12:01:05.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>本文记录 Andoird 的 boot.img 文件的组成、解包、修改以及重打包方法。</p><p>Android 的文件由以下内容组成：</p><pre><code>- kernel，文件名一般为 zImage- ramdisk，文件名一般为 initrd.gz。该文件解压之后是一个 cpio archive 文件（亦是 cramfs 文件系统？）- second，这是第二阶段启动文件系统</code></pre><p>此外，上述文件的地址偏移量也是在打包的时候必须提供的信息。</p><p>使用 abootimg 可以轻松地解压。</p><p><a href="https://github.com/ggrandou/abootimg">https://github.com/ggrandou/abootimg</a></p><h2 id="处理过程"><a href="#处理过程" class="headerlink" title="处理过程"></a>处理过程</h2><pre><code>- 使用 abootimg 将 boot.img 解包，得到 kernel、ramdisk、second 等文件- 使用 cpio 将 ramdisk 文件解包- 修改 ramdisk 中的文件- 使用 cpio 将修改好的文件重新打包成新的 ramdisk 文件- 使用 abootimg 将新的 ramdisk 文件更新到 boot.img 中- 使用 fastboot 刷入 abootimg</code></pre><p>注意，cpio 解包和打包过程均应使用 root 用户。</p><h3 id="使用-cpio-解包-ramdisk"><a href="#使用-cpio-解包-ramdisk" class="headerlink" title="使用 cpio 解包 ramdisk"></a>使用 cpio 解包 ramdisk</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">gzip -d boot.img-ramdisk.gz</span><br><span class="line">mkdir ramdisk</span><br><span class="line">cd ramdisk</span><br><span class="line">cpio -i -d -H newc -F ../boot.img-ramdisk --no-absolute-filenames</span><br></pre></td></tr></table></figure><h3 id="使用-cpio-制作-ramdisk"><a href="#使用-cpio-制作-ramdisk" class="headerlink" title="使用 cpio 制作 ramdisk"></a>使用 cpio 制作 ramdisk</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># 在 ramdisk 目录下</span><br><span class="line">sudo find . | sudo cpio --create --format=&#x27;newc&#x27; &gt;../new-boot.img-ramdisk</span><br></pre></td></tr></table></figure><h3 id="使用-abootimg-将新的-ramdisk-更新到-boot-img-中"><a href="#使用-abootimg-将新的-ramdisk-更新到-boot-img-中" class="headerlink" title="使用 abootimg 将新的 ramdisk 更新到 boot.img 中"></a>使用 abootimg 将新的 ramdisk 更新到 boot.img 中</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">abootimg -u boot.img -r new-boot.img-ramdisk</span><br></pre></td></tr></table></figure><h3 id="摘录——Android-系统在连接电源时自动开机的方法"><a href="#摘录——Android-系统在连接电源时自动开机的方法" class="headerlink" title="摘录——Android 系统在连接电源时自动开机的方法"></a>摘录——Android 系统在连接电源时自动开机的方法</h3><p><a href="https://android.stackexchange.com/questions/20021/automatically-power-on-android-when-the-charger-is-connected">https://android.stackexchange.com/questions/20021/automatically-power-on-android-when-the-charger-is-connected</a></p><p><code>fastboot oem off-mode-charge 0</code> is the genuine method if your device supports. It’s Google’s recommended method but not all OEMs&#x2F;vendors implement the command in bootloader. Or on some devices it’s reset on next reboot. If off-mode-charge is disabled, bootloader won’t pass androidboot.mode&#x3D;charger commandline parameter to kernel when charger is inserted, so device boots normally.</p><p>Otherwise when ro.bootmode property is set to charger on boot, init doesn’t continue the normal boot process. Instead limited number of services are started and charging animation is displayed. So you can instruct init to reboot the device whenever charger mode is detected. Create a new .rc file or edit any existing one:</p><h1 id="system-etc-init-off-mode-charge-rc"><a href="#system-etc-init-off-mode-charge-rc" class="headerlink" title="&#x2F;system&#x2F;etc&#x2F;init&#x2F;off_mode_charge.rc"></a>&#x2F;system&#x2F;etc&#x2F;init&#x2F;off_mode_charge.rc</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">on charger</span><br><span class="line">    setprop sys.powerctl reboot,leaving-off-mode-charging</span><br><span class="line">Or execute reboot binary:</span><br><span class="line"></span><br><span class="line">on charger</span><br><span class="line">    exec - -- /system/bin/reboot leaving-off-mode-charging</span><br><span class="line">But if SELinux is enforcing, stock policy may not let init execute /system/bin/reboot. So use Magisk&#x27;s context (or whatever rooting solution you use):</span><br><span class="line"></span><br><span class="line">on charger</span><br><span class="line">    exec u:r:magisk:s0 -- /system/bin/reboot</span><br><span class="line">Don&#x27;t forget to set permissions on *.rc file (chown 0.0, chmod 0644, chcon u:object_r:system_file:s0).</span><br><span class="line"></span><br><span class="line">It&#x27;s also possible to continue boot process instead of restarting the device by replacing class_start charger with trigger late-init in /init.rc file:</span><br><span class="line"></span><br><span class="line">on charger</span><br><span class="line">    #class_start charger</span><br><span class="line">    trigger late-init</span><br><span class="line">Or by setting property sys.boot_from_charger_mode:</span><br><span class="line"></span><br><span class="line">on charger</span><br><span class="line">    setprop sys.boot_from_charger_mode 1</span><br></pre></td></tr></table></figure><p>This method should work on all devices irrespective of OEM as it doesn’t depend on vendor-specific charging binaries like playlpm, battery_charging, chargeonlymode, zchgd, kpoc_charger and so on.</p><p>Also replacing binaries of important services like healthd - which take care of a lot of things related to battery, storage etc. - is not a good idea. In this case if the service runs both in charger and normal mode, device may get into bootloop.</p><p>On non-System-as-Root devices it’s not necessary to modify &#x2F;system partition (e.g. if you don’t want to break dm-verity for OTA updates to work). Simply unpack boot.img and edit &#x2F;init.rc file in ramdisk.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="android" scheme="https://dpkg123.netlify.app/tags/android/"/>
    
  </entry>
  
  <entry>
    <title>twrp设备树从入门到放弃</title>
    <link href="https://dpkg123.netlify.app/2023/12/10/twrp%E8%AE%BE%E5%A4%87%E6%A0%91%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83/"/>
    <id>https://dpkg123.netlify.app/2023/12/10/twrp%E8%AE%BE%E5%A4%87%E6%A0%91%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83/</id>
    <published>2023-12-10T10:41:08.000Z</published>
    <updated>2023-12-10T10:41:08.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h1 id="⚠️-注意：本人非专业-Android-开发者，本文仅供参考，如有错误，欢迎指正！"><a href="#⚠️-注意：本人非专业-Android-开发者，本文仅供参考，如有错误，欢迎指正！" class="headerlink" title="⚠️ 注意：本人非专业 Android 开发者，本文仅供参考，如有错误，欢迎指正！"></a>⚠️ 注意：本人非专业 Android 开发者，本文仅供参考，如有错误，欢迎指正！</h1><p>本文章以适配OPPO Reno5 Pro+ 为例, OPPO Reno5 Pro+ 为 A only 设备, 支持动态分区 , 不兼容 GKI, VNDK 版本 30。</p><p>编译服务器系统: Ubuntu 20.04.4 lts</p><h2 id="需要准备的东西"><a href="#需要准备的东西" class="headerlink" title="需要准备的东西"></a>需要准备的东西</h2><ul><li>可以编译 Android 的高性能 PC 或服务器(需提前预留32gb的ram和100g的设备存储空间)</li><li>国际互联网连接</li><li>一台root过的OPPO Reno5 Pro+</li></ul><h2 id="准备开始"><a href="#准备开始" class="headerlink" title="准备开始"></a>准备开始</h2><h3 id="安装编译依赖"><a href="#安装编译依赖" class="headerlink" title="安装编译依赖"></a>安装编译依赖</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install bc bison build-essential ccache curl flex g++-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev libelf-dev liblz4-tool libncurses5 libncurses5-dev libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev git</span><br></pre></td></tr></table></figure><h2 id="配置-repo"><a href="#配置-repo" class="headerlink" title="配置 repo"></a>配置 repo</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo curl https://storage.googleapis.com/git-repo-downloads/repo &gt; /usr/bin/repo</span><br><span class="line">sudo chmod a+x /usr/bin/repo</span><br></pre></td></tr></table></figure><h2 id="同步-TWRP-源码"><a href="#同步-TWRP-源码" class="headerlink" title="同步 TWRP 源码"></a>同步 TWRP 源码</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir twrp &amp;&amp; cd twrp</span><br><span class="line">repo init -u https://github.com/minimal-manifest-twrp/platform_manifest_twrp_omni -b twrp-9.0 --depth=1</span><br><span class="line">repo sync</span><br></pre></td></tr></table></figure><p>如果安卓版本为安卓10及其以上，请更换网址为:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">repo init -u https://github.com/minimal-manifest-twrp/platform_manifest_twrp_aosp -b twrp-12.1 --depth=1</span><br></pre></td></tr></table></figure><p>注:如果同时安转了python2.7和python3，运行repo时可能会出现以下状况:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">File &quot;/usr/bin/repo&quot;, line 51</span><br><span class="line">    def print(self, *args, **kwargs):</span><br><span class="line">            ^</span><br><span class="line">SyntaxError: invalid syntax</span><br></pre></td></tr></table></figure><p>解决方法:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/usr/bin/python3 /usr/bin/repo sync</span><br></pre></td></tr></table></figure><p>或修改 &#x2F;usr&#x2F;bin&#x2F;repo</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">#!/bin/python</span><br></pre></td></tr></table></figure><p>改成</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/python3</span></span><br></pre></td></tr></table></figure><p>源码同步成功后会占用磁盘20g-30g的空间。</p><h2 id="初始化编译必要文件"><a href="#初始化编译必要文件" class="headerlink" title="初始化编译必要文件"></a>初始化编译必要文件</h2><blockquote><p>⚠️ 注意：下列步骤将由xxxx替代要适配的手机代号，yyyy代替手机厂商。</p></blockquote><p>不管是编译 Android 还是 TWRP，这些文件都是必要的:</p><ul><li>Android.mk</li><li>AndroidProduct.mk</li><li>BoardConfig.mk</li><li>twrp_xxxx.mk<br>这几个文件可以直接从其他的twrp设备树拿，然后进行修改。</li></ul><p>Android.mk、AndroidProduct.mk、twrp_xxxx.mk 一般情况下无需进行修改</p><p>编译 TWRP 需要对 BoardConfig.mk 等文件进行修改</p><h2 id="修改-BoardConfig-mk"><a href="#修改-BoardConfig-mk" class="headerlink" title="修改 BoardConfig.mk"></a>修改 BoardConfig.mk</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DEVICE_PATH := device/yyyy/xxxx</span><br></pre></td></tr></table></figure><p>此处定义了设备树的位置。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ALLOW_MISSING_DEPENDENCIES := true</span><br></pre></td></tr></table></figure><p>由于同步的只有 TWRP 源码，编译时需要打开这个。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">BUILD_BROKEN_DUP_RULES := true</span><br><span class="line">BUILD_BROKEN_ELF_PREBUILT_PRODUCT_COPY_FILES := true</span><br></pre></td></tr></table></figure><p>这两个选项可能会解决一些编译错误。当有两个或更多的条目试图将文件复制到相同的目标位置时。这个标志的作用是允许覆盖先前定义的目标命令，而不是报错。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"># Architecture</span><br><span class="line">TARGET_ARCH := arm64</span><br><span class="line">TARGET_ARCH_VARIANT := armv8-a</span><br><span class="line">TARGET_CPU_ABI := arm64-v8a</span><br><span class="line">TARGET_CPU_ABI2 :=</span><br><span class="line">TARGET_CPU_VARIANT := generic</span><br><span class="line">TARGET_CPU_VARIANT_RUNTIME := kryo385</span><br><span class="line"></span><br><span class="line">TARGET_2ND_ARCH := arm</span><br><span class="line">TARGET_2ND_ARCH_VARIANT := armv8-a</span><br><span class="line">TARGET_2ND_CPU_ABI := armeabi-v7a</span><br><span class="line">TARGET_2ND_CPU_ABI2 := armeabi</span><br><span class="line">TARGET_2ND_CPU_VARIANT := generic</span><br><span class="line">TARGET_2ND_CPU_VARIANT_RUNTIME := kryo385</span><br></pre></td></tr></table></figure><p>这里定义要适配的机型的cpu的一些信息。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">TARGET_BOARD_SUFFIX := _64</span><br><span class="line">TARGET_USES_64_BIT_BINDER := true</span><br></pre></td></tr></table></figure><p>如果适配的安卓设备的soc是64位soc，且系统也是64位，请启用它。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">TARGET_OTA_ASSERT_DEVICE := xxxx</span><br></pre></td></tr></table></figure><p>此处定义了设备ota时候的机型代号，ota机型检查的时候会检查是否匹配。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># Bootloader</span><br><span class="line">PRODUCT_PLATFORM := kona</span><br><span class="line">TARGET_BOOTLOADER_BOARD_NAME := kona</span><br><span class="line">TARGET_NO_BOOTLOADER := true</span><br><span class="line">TARGET_USES_UEFI := true</span><br></pre></td></tr></table></figure><p>此处定义了bootloader的一些信息。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">BOARD_USES_MTK_HARDWARE := true</span><br><span class="line">BOARD_HAS_MTK_HARDWARE := true</span><br></pre></td></tr></table></figure><p>这两个选项仅适用于mtk芯片组。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># Platform</span><br><span class="line">TARGET_BOARD_PLATFORM := sm8250</span><br></pre></td></tr></table></figure><p>此处定义了cpu的代号。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"># BOARD_BOOTIMG_HEADER_VERSION := 2</span><br><span class="line"># BOARD_KERNEL_BASE := 0x40078000</span><br><span class="line"># BOARD_KERNEL_CMDLINE := ttyMSM0,115200n8 earlycon=msm_geni_serial,0xa90000 androidboot.hardware=qcom androidboot.console=ttyMSM0 androidboot.memcg=1 lpm_levels.sleep_disabled=1 video=vfb:640x400,bpp=32,memsize=3072000 msm_rtb.filter=0x237 service_locator.enable=1 androidboot.usbcontroller=a600000.dwc3 swiotlb=2048 loop.max_part=7 cgroup.memory=nokmem,nosocket reboot=panic_warm kpti=off buildvariant=user</span><br><span class="line"># BOARD_KERNEL_PAGESIZE := 2048</span><br><span class="line"># BOARD_RAMDISK_OFFSET := 0x11088000</span><br><span class="line"># BOARD_KERNEL_TAGS_OFFSET := 0x07c08000</span><br><span class="line"># BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOTIMG_HEADER_VERSION)</span><br><span class="line"># BOARD_MKBOOTIMG_ARGS += --ramdisk_offset $(BOARD_RAMDISK_OFFSET)</span><br><span class="line"># BOARD_MKBOOTIMG_ARGS += --tags_offset $(BOARD_KERNEL_TAGS_OFFSET)</span><br><span class="line"># BOARD_KERNEL_IMAGE_NAME := Image</span><br><span class="line"># BOARD_INCLUDE_DTB_IN_BOOTIMG := true</span><br><span class="line"># BOARD_KERNEL_SEPARATED_DTBO := true</span><br><span class="line"># TARGET_KERNEL_CONFIG := xxxx_defconfig</span><br><span class="line"># TARGET_KERNEL_SOURCE := device/yyyy/xxxx</span><br></pre></td></tr></table></figure><p>使用源码编译才使用此部分。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">BOARD_KERNEL_CMDLINE := ttyMSM0,115200n8 earlycon=msm_geni_serial,0xa90000 androidboot.hardware=qcom androidboot.console=ttyMSM0 androidboot.memcg=1 lpm_levels.sleep_disabled=1 video=vfb:640x400,bpp=32,memsize=3072000 msm_rtb.filter=0x237 service_locator.enable=1 androidboot.usbcontroller=a600000.dwc3 swiotlb=2048 loop.max_part=7 cgroup.memory=nokmem,nosocket reboot=panic_warm kpti=off buildvariant=user</span><br><span class="line">TARGET_PREBUILT_KERNEL := $(DEVICE_PATH)/prebuilt/kernel</span><br><span class="line">TARGET_PREBUILT_DTB := $(DEVICE_PATH)/prebuilt/dtb.img</span><br><span class="line">BOARD_PREBUILT_DTBOIMAGE := $(DEVICE_PATH)/prebuilt/dtbo.img</span><br><span class="line">BOARD_INCLUDE_RECOVERY_DTBO := true</span><br><span class="line">BOARD_BOOTIMG_HEADER_VERSION := 2</span><br><span class="line">BOARD_RAMDISK_OFFSET := 0x11088000</span><br><span class="line">BOARD_KERNEL_BASE := 0x40078000</span><br><span class="line">BOARD_KERNEL_TAGS_OFFSET := 0x07c08000</span><br><span class="line">BOARD_KERNEL_PAGESIZE := 2048</span><br><span class="line">BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOTIMG_HEADER_VERSION)</span><br><span class="line">BOARD_MKBOOTIMG_ARGS += --ramdisk_offset $(BOARD_RAMDISK_OFFSET)</span><br><span class="line">BOARD_MKBOOTIMG_ARGS += --tags_offset $(BOARD_KERNEL_TAGS_OFFSET)</span><br><span class="line">BOARD_MKBOOTIMG_ARGS += --dtb $(TARGET_PREBUILT_DTB)</span><br><span class="line">BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOTIMG_HEADER_VERSION)</span><br><span class="line">BOARD_KERNEL_IMAGE_NAME := kernel</span><br></pre></td></tr></table></figure><p>使用预编译内核。你需要提取手机的boot.img并使用<a href="https://github.com/osm0sis/Android-Image-Kitchen">Android Image Kitchen</a>来获取预编译内核，dtb和dtbo(如果有)以及cmdline。</p><p>然后替换cmdline。</p><p>再将预编译内核放入引用的路径。这里引用的路径是<code>$(DEVICE_PATH)/prebuilt/</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"># Android Verified Boot</span><br><span class="line">BOARD_AVB_ENABLE := true</span><br><span class="line">BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --set_hashtree_disabled_flag</span><br><span class="line">BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --flags 2</span><br><span class="line">BOARD_AVB_RECOVERY_KEY_PATH := external/avb/test/data/testkey_rsa4096.pem</span><br><span class="line">BOARD_AVB_RECOVERY_ALGORITHM := SHA256_RSA4096</span><br><span class="line">BOARD_AVB_RECOVERY_ROLLBACK_INDEX := 1</span><br><span class="line">BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION := 1</span><br><span class="line">BOARD_AVB_VBMETA_SYSTEM := product system</span><br><span class="line">BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)</span><br><span class="line">BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1</span><br></pre></td></tr></table></figure><p>此处定义了avb的一些信息。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># Metadata</span><br><span class="line">BOARD_USES_METADATA_PARTITION := true</span><br></pre></td></tr></table></figure><p>在twrp中使用metadata分区。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># Hack: prevent anti rollback</span><br><span class="line">PLATFORM_SECURITY_PATCH := 2127-12-31</span><br></pre></td></tr></table></figure><p>加入补丁更新日期来回避防回滚机制。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># Partitions</span><br><span class="line">BOARD_FLASH_BLOCK_SIZE := 262144</span><br><span class="line">BOARD_RECOVERYIMAGE_PARTITION_SIZE := 134217728</span><br><span class="line">BOARD_BOOTIMAGE_PARTITION_SIZE := 167772160</span><br></pre></td></tr></table></figure><p>此处定义了boot分区和recovery分区的大小，以及块大小。修改分区大小时要注意单位是b而不是kb。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># Dynamic Partition</span><br><span class="line">BOARD_SUPER_PARTITION_SIZE := 10200547328</span><br><span class="line">BOARD_SUPER_PARTITION_GROUPS := qti_dynamic_partitions</span><br><span class="line">BOARD_QTI_DYNAMIC_PARTITIONS_SIZE := 10200547328</span><br><span class="line">BOARD_QTI_DYNAMIC_PARTITIONS_PARTITION_LIST := system system_ext product vendor odm</span><br></pre></td></tr></table></figure><p>此处定义了动态分区的信息。可按需修改。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># File systems</span><br><span class="line">BOARD_HAS_LARGE_FILESYSTEM := true</span><br><span class="line">BOARD_SYSTEMIMAGE_PARTITION_TYPE := ext4</span><br><span class="line">BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE := f2fs</span><br><span class="line">BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4</span><br><span class="line">TARGET_USERIMAGES_USE_EXT4 := true</span><br><span class="line">TARGET_USERIMAGES_USE_F2FS := true</span><br><span class="line">TARGET_COPY_OUT_VENDOR := vendor</span><br></pre></td></tr></table></figure><p>此处依次定义了system，vendor和data分区的文件系统，以及vendor分区的相对路径。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># Fstab</span><br><span class="line">TARGET_RECOVERY_FSTAB := $(DEVICE_PATH)/recovery/root/system/etc/recovery.fstab</span><br></pre></td></tr></table></figure><p>此处定义了fstab的位置。可提取recovery中的ramdisk.cpio中的进行使用。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"># TWRP Configuration</span><br><span class="line">TW_THEME := portrait_hdpi</span><br><span class="line">TW_BRIGHTNESS_PATH := &quot;/sys/devices/soc/c900000.qcom\x2cmdss_mdp/c900000.qcom\x2cmdss_mdp:qcom\x2cmdss_fb_primary/leds/lcd-backlight/brightness&quot; </span><br><span class="line">TW_MAX_BRIGHTNESS := 255</span><br><span class="line">TW_DEFAULT_BRIGHTNESS := 155</span><br><span class="line">TW_EXTRA_LANGUAGES := ture</span><br><span class="line">TW_IGNORE_MISC_WIPE_DATA := true</span><br><span class="line">TW_SCREEN_BLANK_ON_BOOT := true</span><br><span class="line">TW_NO_EXFAT_FUSE := true</span><br><span class="line">TW_INCLUDE_CRYPTO := true</span><br><span class="line">TARGET_CRYPTFS_HW_PATH := vendor/qcom/opensource/commonsys/cryptfs_hw</span><br></pre></td></tr></table></figure><p>此处依次定义了twrp要使用的主题，亮度调节的内核节点，亮度调节，添加亚洲语言， 是否在 wipe data 时忽略 misc，是否添加加密，解密所需依赖源码路径等信息。</p><p>注:亮度调节的内核节点语言根据本机的位置进行修改。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">TW_USE_TOOLBOX := true </span><br><span class="line">TWRP_INCLUDE_LOGCAT := true </span><br><span class="line">TARGET_USES_LOGD := true </span><br></pre></td></tr></table></figure><p>此处定义了twrp是否启用调试功能，例如toolbox,logcat等。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># Include some binaries</span><br><span class="line">TW_INCLUDE_LIBRESETPROP := true</span><br><span class="line">TW_INCLUDE_RESETPROP := true</span><br><span class="line">TW_INCLUDE_REPACKTOOLS := true</span><br></pre></td></tr></table></figure><p>此处定义twrp编译时引用的第三方库。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">TARGET_USES_MKE2FS := true</span><br></pre></td></tr></table></figure><p>此处添加了mke2fs，可将分区格式化成f2fs。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">TW_DEFAULT_LANGUAGE := zh_CN</span><br></pre></td></tr></table></figure><p>此处设置了启动twrp时的默认语言为中文。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">TW_OZIP_DECRYPT_KEY := 0000</span><br></pre></td></tr></table></figure><p>此处定义了刷入ozip时解密ozip的秘钥。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">AB_OTA_UPDATER := true</span><br><span class="line">BOARD_USES_RECOVERY_AS_BOOT := true</span><br><span class="line">BOARD_BUILD_SYSTEM_ROOT_IMAGE := true</span><br></pre></td></tr></table></figure><p>如果是 A&#x2F;B 分区的话还得加入这些。</p><h2 id="修改-device-mk"><a href="#修改-device-mk" class="headerlink" title="修改 device.mk"></a>修改 device.mk</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">LOCAL_PATH := device/yyyy/xxxx</span><br></pre></td></tr></table></figure><p>定义local_path变量，一般有这一行就够了。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">PRODUCT_USE_DYNAMIC_PARTITIONS := true</span><br></pre></td></tr></table></figure><p>是否启用动态分区。如果设备是动态分区就启用。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># Crypto</span><br><span class="line">PRODUCT_PACKAGES += \</span><br><span class="line">    qcom_decrypt \</span><br><span class="line">    qcom_decrypt_fbe</span><br></pre></td></tr></table></figure><p>此处添加解密所需依赖。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># Soong namespaces</span><br><span class="line">PRODUCT_SOONG_NAMESPACES += \</span><br><span class="line">$(LOCAL_PATH)</span><br></pre></td></tr></table></figure><p>此处定义Soong namespaces的路径。</p><p>注:下述内容需要设备为A&#x2F;B分区。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">AB_OTA_UPDATER := true</span><br></pre></td></tr></table></figure><p>此处定义了是否启用A&#x2F;B支持。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">AB_OTA_PARTITIONS += \</span><br><span class="line">    boot \</span><br><span class="line">    system \</span><br><span class="line">    vendor</span><br></pre></td></tr></table></figure><p>此处定义了使用 A&#x2F;B 特性的分</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">AB_OTA_POSTINSTALL_CONFIG += \ </span><br><span class="line">    RUN_POSTINSTALL_system=true \</span><br><span class="line">    POSTINSTALL_PATH_system=system/bin/otapreopt_script \</span><br><span class="line">    FILESYSTEM_TYPE_system=ext4 \</span><br><span class="line">    POSTINSTALL_OPTIONAL_system=true</span><br></pre></td></tr></table></figure><p>此处定义了A&#x2F;B分区ota的一些选项。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">PRODUCT_PACKAGES += \</span><br><span class="line">    otapreopt_script \</span><br><span class="line">    cppreopts.sh \</span><br><span class="line">    update_engine \</span><br><span class="line">    update_verifier \</span><br><span class="line">    update_engine_sideload</span><br><span class="line"></span><br><span class="line"># Boot control</span><br><span class="line">PRODUCT_PACKAGES += \</span><br><span class="line">    android.hardware.boot@1.0-impl \</span><br><span class="line">    android.hardware.boot@1.0-service \</span><br><span class="line">    bootctrl.sm8250 \</span><br><span class="line"></span><br><span class="line">PRODUCT_PACKAGES_DEBUG += \</span><br><span class="line">    bootctl</span><br><span class="line"></span><br><span class="line">PRODUCT_STATIC_BOOT_CONTROL_HAL := \</span><br><span class="line">    bootctrl.sm8250 \</span><br><span class="line">    libcutils \</span><br><span class="line">    libgptutils \</span><br><span class="line">    libz</span><br></pre></td></tr></table></figure><p>此处定义了需要引用的包。</p><p>修改完成后，在 twrp_xxxx.mk 里调用</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$(call inherit-product, device/yyyy/xxxx/device.mk)</span><br></pre></td></tr></table></figure><h2 id="配置-TWRP-分区表"><a href="#配置-TWRP-分区表" class="headerlink" title="配置 TWRP 分区表"></a>配置 TWRP 分区表</h2><p>可以从本机recovery里提取一份recovery.fstab并放在之前引用的位置。我这里引用的是<code>recovery/root/system/etc/recovery fastb</code></p><p>然后新建文件twrp.flags并放在<code>与recovery.fastb相同的路径</code>。</p><p>twrp.flags文件示例:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"># mount point   fstype     device                                   device2                       flags</span><br><span class="line"># 定义挂载点  定义文件系统类型 定义挂载原块文件路径                                                       定义一些特性</span><br><span class="line"># Other partitions</span><br><span class="line">/boot           emmc    /dev/block/bootdevice/by-name/boot             flags=backup=1;display=&quot;Boot&quot;;flashimg=1</span><br><span class="line">/recovery       emmc    /dev/block/bootdevice/by-name/recovery         flags=backup=1;display=&quot;Recovery&quot;;flashimg=1</span><br><span class="line">/dtbo           emmc    /dev/block/bootdevice/by-name/dtbo             flags=backup=1;display=&quot;Dtbo&quot;;flashimg=1</span><br><span class="line">/cache          ext4    /dev/block/bootdevice/by-name/cache            flags=backup=1;display=&quot;Cache&quot;;wipeingui</span><br><span class="line">/metadata       ext4    /dev/block/bootdevice/by-name/metadata         flags=display=&quot;Metadata&quot;;wrappedkey</span><br><span class="line">/data           f2fs    /dev/block/bootdevice/by-name/userdata         flags=fileencryption=aes-256-xts:aes-256-cts:v2+inlinecrypt_optimized+wrappedkey_v0,metadata_encryption=aes-256-xts:wrappedkey_v0,keydirectory=/metadata/vold/metadata_encryption</span><br><span class="line"></span><br><span class="line"># System</span><br><span class="line">/system ext4/dev/block/bootdevice/by-name/systemflags=slotselect;display=&quot;System&quot;;backup=1;wipeingui</span><br><span class="line">/system_image        emmc/dev/block/bootdevice/by-name/systemflags=slotselect;flashimg=1</span><br><span class="line">/vendorext4/dev/block/bootdevice/by-name/vendorflags=slotselect;display=&quot;Vendor&quot;;backup=1;wipeingui</span><br><span class="line">/vendor_image        emmc/dev/block/bootdevice/by-name/vendorflags=slotselect;flashimg=1</span><br><span class="line">/productext4/dev/block/bootdevice/by-name/productflags=slotselect;display=&quot;Product&quot;;backup=1</span><br><span class="line">/product_image        emmc/dev/block/bootdevice/by-name/productflags=slotselect;flashimg=1</span><br><span class="line">/odm                            ext4    /dev/block/bootdevice/by-name/odm               display=&quot;ODM&quot;;logical</span><br><span class="line">/odm_image                emmc/dev/block/bootdevice/by-name/odm       flags=display=&quot;ODM&quot;;flashimg;backup=1</span><br><span class="line">/system_ext                     ext4    /dev/block/bootdevice/by-name/system_ext        logical</span><br><span class="line">/system_ext_imageemmc/dev/block/bootdevice/by-name/system_extflags=slotselect;flashimg=1</span><br><span class="line"></span><br><span class="line">/system                         erofs   /dev/block/bootdevice/by-name/system            display=&quot;system&quot;;logical</span><br><span class="line">/vendor                         erofs   /dev/block/bootdevice/by-name/vendor            display=&quot;Vendor&quot;;logical</span><br><span class="line">/product                        erofs   /dev/block/bootdevice/by-name/product           display=&quot;Product&quot;;logical</span><br><span class="line">/odm                            erofs   /dev/block/bootdevice/by-name/odm               display=&quot;ODM&quot;;logical</span><br><span class="line">/system_ext                     erofs   /dev/block/bootdevice/by-name/system_ext        display=&quot;system_ext&quot;;logical</span><br><span class="line"></span><br><span class="line">/usbstorage     vfat       /dev/block/sdg1</span><br></pre></td></tr></table></figure><p>关于 flags:</p><ul><li>如果是 A&#x2F;B 设备，请给使用 A&#x2F;B 特性的分区定义 <code>slotselect</code></li><li>用 backup 来定义可备份分区</li><li>display 用来自定义分区名</li><li>encryptable 来定义加密类型</li><li>removable 用来定义可否热拔插</li></ul><p>如果是A&#x2F;B分区，还需要添加<code>recovery.wipe</code>:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"># All the partitions to be wiped (in order) under recovery.</span><br><span class="line">/dev/block/bootdevice/by-name/system_a</span><br><span class="line">/dev/block/bootdevice/by-name/system_b</span><br><span class="line">/dev/block/bootdevice/by-name/vendor_a</span><br><span class="line">/dev/block/bootdevice/by-name/vendor_b</span><br><span class="line">/dev/block/bootdevice/by-name/userdata</span><br><span class="line"># Wipe the boot partitions last so that all partitions will be wiped</span><br><span class="line"># correctly even if the wiping process gets interrupted by a force boot.</span><br><span class="line">/dev/block/bootdevice/by-name/boot_a</span><br><span class="line">/dev/block/bootdevice/by-name/boot_b</span><br></pre></td></tr></table></figure><h2 id="init-rc"><a href="#init-rc" class="headerlink" title="init.rc"></a>init.rc</h2><p>不同机型，init 部分也不一样</p><p>可以复制recovery.img里面的</p><h2 id="bootctrl-和-gpt-utils"><a href="#bootctrl-和-gpt-utils" class="headerlink" title="bootctrl 和 gpt-utils"></a>bootctrl 和 gpt-utils</h2><p>如果你的设备采用 A&#x2F;B 分区，那必须编译这两个组件</p><p>确保 tree 里面有编译 bootctrl 和 gpt-utils</p><p>这两个东西可以从其它机型的 tree 里面拿，通用的</p><h2 id="开始编译"><a href="#开始编译" class="headerlink" title="开始编译"></a>开始编译</h2><p>上面的东西都配置好后就可以开始编译了</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">cd twrp</span><br><span class="line">. build/envsetup.sh</span><br><span class="line">lunch twrp_xxxx-eng</span><br><span class="line">mka bootimage</span><br></pre></td></tr></table></figure><p>如果设备不是 A&#x2F;B 分区</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mka recoveryimage</span><br></pre></td></tr></table></figure><h2 id="制作卡刷包"><a href="#制作卡刷包" class="headerlink" title="制作卡刷包"></a>制作卡刷包</h2><p>需要再BoardConfig.mk加入</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">USE_RECOVERY_INSTALLER := true</span><br><span class="line">RECOVERY_INSTALLER_PATH := device/yyyy/xxxx/installer</span><br></pre></td></tr></table></figure><p>新建以下目录:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">installer</span><br><span class="line">installer/META-INF/</span><br><span class="line">installer/META-INF/com</span><br><span class="line">installer/META-INF/com/google</span><br><span class="line">installer/META-INF/com/google/android/</span><br></pre></td></tr></table></figure><p>添加magiskboot到installer目录</p><p>添加update-binary到installer&#x2F;META-INF&#x2F;com&#x2F;google&#x2F;android&#x2F;目录:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line">#!/sbin/sh</span><br><span class="line"></span><br><span class="line">tmp=/tmp/twrp-install</span><br><span class="line"></span><br><span class="line">if [ &quot;$3&quot; ]; then</span><br><span class="line">zip=$3</span><br><span class="line">console=/proc/$$/fd/$2</span><br><span class="line"># write the location of the console buffer to /tmp/console for other scripts to use</span><br><span class="line">echo &quot;$console&quot; &gt; /tmp/console</span><br><span class="line">else</span><br><span class="line">console=$(cat /tmp/console)</span><br><span class="line">[ &quot;$console&quot; ] || console=/proc/$$/fd/1</span><br><span class="line">fi</span><br><span class="line"></span><br><span class="line">print() &#123;</span><br><span class="line">if [ &quot;$1&quot; ]; then</span><br><span class="line">echo &quot;ui_print $1&quot; &gt; &quot;$console&quot;</span><br><span class="line">else</span><br><span class="line">echo &quot;ui_print  &quot; &gt; &quot;$console&quot;</span><br><span class="line">fi</span><br><span class="line">echo</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">abort() &#123;</span><br><span class="line">[ &quot;$1&quot; ] &amp;&amp; &#123;</span><br><span class="line">print &quot;Error: $1&quot;</span><br><span class="line">print &quot;Aborting...&quot;</span><br><span class="line">&#125;</span><br><span class="line">cleanup</span><br><span class="line">print &quot;Failed to patch boot image!&quot;</span><br><span class="line">exit 1</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">cleanup() &#123;</span><br><span class="line">[ &quot;$zip&quot; ] &amp;&amp; rm /tmp/console</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">extract() &#123;</span><br><span class="line">rm -rf &quot;$2&quot;</span><br><span class="line">mkdir -p &quot;$2&quot;</span><br><span class="line">unzip -o &quot;$1&quot; -d &quot;$2&quot; || abort &quot;Failed to extract zip to $2!&quot;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">print &quot;#########################################&quot;</span><br><span class="line">print &quot;#          TWRP installer               #&quot;</span><br><span class="line">print &quot;#########################################&quot;</span><br><span class="line"></span><br><span class="line"># Unpack the installer</span><br><span class="line">[ &quot;$zip&quot; ] &amp;&amp; &#123;</span><br><span class="line">print &quot;Unpacking the installer...&quot;</span><br><span class="line">extract &quot;$zip&quot; &quot;$tmp&quot;</span><br><span class="line">&#125;</span><br><span class="line">cd &quot;$tmp&quot;</span><br><span class="line">toolname=&quot;/magiskboot&quot;</span><br><span class="line">tool=&quot;$tmp$toolname&quot;</span><br><span class="line">targetfile=&quot;/boot.img&quot;</span><br><span class="line">target=&quot;$tmp$targetfile&quot;</span><br><span class="line"></span><br><span class="line">chmod 755 &quot;$tool&quot;</span><br><span class="line"></span><br><span class="line">print &quot;Running boot image patcher on slot A...&quot;</span><br><span class="line">dd if=/dev/block/bootdevice/by-name/boot_a &quot;of=$target&quot;</span><br><span class="line">&quot;$tool&quot; --unpack boot.img</span><br><span class="line">cp -f ramdisk-recovery.cpio ramdisk.cpio</span><br><span class="line">&quot;$tool&quot; --repack boot.img</span><br><span class="line">dd if=new-boot.img of=/dev/block/bootdevice/by-name/boot_a</span><br><span class="line">rm boot.img</span><br><span class="line">rm dtb</span><br><span class="line">rm kernel</span><br><span class="line">rm new-boot.img</span><br><span class="line">rm ramdisk.cpio</span><br><span class="line">print &quot;Running boot image patcher on slot B...&quot;</span><br><span class="line">dd if=/dev/block/bootdevice/by-name/boot_b &quot;of=$target&quot;</span><br><span class="line">&quot;$tool&quot; --unpack boot.img</span><br><span class="line">cp -f ramdisk-recovery.cpio ramdisk.cpio</span><br><span class="line">&quot;$tool&quot; --repack boot.img</span><br><span class="line">dd if=new-boot.img of=/dev/block/bootdevice/by-name/boot_b</span><br><span class="line"></span><br><span class="line">print &quot;Boot image patching complete&quot;</span><br><span class="line"></span><br><span class="line">#cleanup</span><br><span class="line">print &quot;Done installing TWRP!&quot;</span><br></pre></td></tr></table></figure><p>注:A&#x2F;B分区可能需要准备installer&#x2F;META-INF&#x2F;MANIFEST.MF，installer&#x2F;META-INF&#x2F;CERT.SF，installer&#x2F;META-INF&#x2F;CERT.RSA</p>]]></content>
    
    
    <summary type="html">虽然但是，安卓设备树比这个难。</summary>
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="android" scheme="https://dpkg123.netlify.app/tags/android/"/>
    
    <category term="twrp" scheme="https://dpkg123.netlify.app/tags/twrp/"/>
    
    <category term="build" scheme="https://dpkg123.netlify.app/tags/build/"/>
    
  </entry>
  
  <entry>
    <title>3DS折腾linux小记</title>
    <link href="https://dpkg123.netlify.app/2023/10/06/3DS%E6%8A%98%E8%85%BElinux%E5%B0%8F%E8%AE%B0/"/>
    <id>https://dpkg123.netlify.app/2023/10/06/3DS%E6%8A%98%E8%85%BElinux%E5%B0%8F%E8%AE%B0/</id>
    <published>2023-10-06T13:24:53.000Z</published>
    <updated>2023-10-06T13:24:53.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>为了使上下学路上不再无聊，笔者在某宝上淘了一台<code>B9S破解的老大三</code>(老3ds，不带任何后缀的那种)。熟悉我的人都知道，我经常在一些平台上折腾各种功能和工具，不是为了有多实用，而是为了测试和研究比较炫酷的东西。</p><p>于是乎就有了这篇文章。</p><h3 id="DS-Linux"><a href="#DS-Linux" class="headerlink" title="DS Linux"></a>DS Linux</h3><p>DSLinux的部署和使用相对容易很多，因为它提供了预编译的Linux文件系统和内核，也将启动文件打包成了.nds的格式。可以通过烧录卡或者TWilight Menu的方式启动DSLinux，在这里只介绍通过R4卡启动的方法，因为TWilight启动并不稳定，经常导致3DS系统崩溃并强制重启。</p><p>首先先在<a href="http://www.dslinux.org/">DSLinux官网</a>上下载DLDI版本的DSLinux。将获得的文件解压并全部放在R4卡的Micro SD卡的根目录下。需要注意的是，请使用Linux系统进行解压和复制的操作，因为Windows下文件的结尾符与Linux并不相同，有的Windows解压工具也会忽略空目录，这些都会影响DSLinux的正常使用。在完成解压之后将R4卡重新装回3DS内，启动对应的入口程序进入R4菜单之后（这一步由于每个人使用的内核不一样，具体也略有不同），进入文件管理器，并且启动刚刚复制进去的.nds文件。之后DS模式会软重启并且加载DSLinux，DLDI版本的DSLinux能够自动登录，所以可以直接获取Shell。</p><p><img src="/img/20231006/1.jpg" alt="1" title="DSLinux效果图"></p><p>不过由于这一移植系统的局限性，有些命令在这里不能使用。虽然文件系统被挂载为读写，而且有WiFi芯片的驱动(<del>然而这并没有什么用，连xorg都没有</del>)</p><h3 id="Linux-for-3DS"><a href="#Linux-for-3DS" class="headerlink" title="Linux for 3DS"></a>Linux for 3DS</h3><p>Linux for 3DS是为原生3DS开发的一个Linux环境，使用的是Busybox+Buildroot的方式来获得Linux的指令集。</p><p>但是这一项目基本已经停止更新。</p><p>可以参考<a href="https://gbatemp.net/threads/release-linux-for-the-3ds.407187/">GBATEMP上的一个帖子</a>以及<a href="https://firefox2100.github.io/kernel/2020/03/09/Linux_3DS/">这个教程</a></p><p>取下3DS的SD卡并连接电脑，（建议这种事还是把卡取下来，万一FTP传输的时候损坏文件比较麻烦）。在根目录下新建&#x2F;linux文件夹，并在其中放入由arm9linuxfw编译获得的arm9linuxfw.bin，和由linux_3ds编译获得的.&#x2F;arch&#x2F;arm&#x2F;boot&#x2F;zImage镜像和.&#x2F;arch&#x2F;arm&#x2F;boot&#x2F;dts&#x2F;nintendo3ds_ctr.dtb文件。之后将firm_linux_loader.firm放入&#x2F;luma&#x2F;payload内，插卡按住start开机，选择firm_linux_loader，等待其加载完成。</p><p>rootfs的用户名和密码都是root。</p><p><img src="/img/20231006/2.jpg" alt="2" title="Buildroot"></p><h3 id="引导其他linux"><a href="#引导其他linux" class="headerlink" title="引导其他linux"></a>引导其他linux</h3><p>严格来说，这一Linux文件系统是Buildroot+busybox的方式。并不是所熟知的Linux。</p><p>所以笔者尝试构建了debian bullseye armel 和devuan chimaera armel的rootfs并启动他们，但是内核会panic:<br><img src="/img/20231006/3.jpg" alt="3" title="panic"><br>或者卡在starting sysctl不动:<br><img src="/img/20231006/4.jpg" alt="4" title="sysctl"></p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="3DS" scheme="https://dpkg123.netlify.app/tags/3DS/"/>
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="buildroot" scheme="https://dpkg123.netlify.app/tags/buildroot/"/>
    
    <category term="kernel" scheme="https://dpkg123.netlify.app/tags/kernel/"/>
    
  </entry>
  
  <entry>
    <title>暂停更新博客通知</title>
    <link href="https://dpkg123.netlify.app/2023/08/08/%E6%9A%82%E5%81%9C%E6%9B%B4%E6%96%B0%E5%8D%9A%E5%AE%A2%E9%80%9A%E7%9F%A5/"/>
    <id>https://dpkg123.netlify.app/2023/08/08/%E6%9A%82%E5%81%9C%E6%9B%B4%E6%96%B0%E5%8D%9A%E5%AE%A2%E9%80%9A%E7%9F%A5/</id>
    <published>2023-08-08T14:11:26.000Z</published>
    <updated>2023-08-08T14:11:26.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>Hi guys!</p><p>Due to academic factors, I have to temporarily stop updating the blog.  I also ask for your understanding.</p><p>This will run until June 30th next year.  There may be some blog post updates along the way.</p><p>Those who have exchanged links, please do not remove the links during the suspension of my blog. Thank you.</p><p>dpkg123</p><p>Written on August 8</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="杂谈" scheme="https://dpkg123.netlify.app/tags/%E6%9D%82%E8%B0%88/"/>
    
  </entry>
  
  <entry>
    <title>Makefile入门</title>
    <link href="https://dpkg123.netlify.app/2023/08/05/Makefile%E5%85%A5%E9%97%A8/"/>
    <id>https://dpkg123.netlify.app/2023/08/05/Makefile%E5%85%A5%E9%97%A8/</id>
    <published>2023-08-04T16:56:05.000Z</published>
    <updated>2023-08-04T16:56:05.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>本文章旨在教会一个新用户学会编写makefile.</p><p>在了解makefile之前，我们需要知道make是什么。</p><h1 id="make命令简介"><a href="#make命令简介" class="headerlink" title="make命令简介"></a>make命令简介</h1><p>make是一个在软件开发中所使用的工具程序（Utility software），经由读取“makefile”的文件以自动化建构软件。它是一种转化文件形式的工具，转换的目标称为“target”；与此同时，它也检查文件的依赖关系，如果需要的话，它会调用一些外部软件来完成任务。它的依赖关系检查系统非常简单，主要根据依赖文件的修改时间进行判断。大多数情况下，它被用来编译源代码，生成结果代码，然后把结果代码连接起来生成可执行文件或者库文件。它使用叫做“makefile”的文件来确定一个target文件的依赖关系，然后把生成这个target的相关命令传给shell去执行。</p><p><del>由此可见，Makefile可以抽象理解为有make这个解释器去执行的shell脚本</del></p><p>运行make help，输出结果如下:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line">user@localhost ~ &gt;  make help</span><br><span class="line"></span><br><span class="line">用法：make [选项] [目标] ...</span><br><span class="line">选项：</span><br><span class="line">  -b, -m                      为兼容性而忽略。</span><br><span class="line">  -B, --always-make           无条件制作 (make) 所有目标。</span><br><span class="line">  -C 目录, --directory=目录    在执行前先切换到 &lt;目录&gt;。</span><br><span class="line">  -d                          打印大量调试信息。</span><br><span class="line">  --debug[=旗标]               打印各种调试信息。</span><br><span class="line">  -e, --environment-overrides</span><br><span class="line">                              环境变量覆盖 makefile 中的变量。</span><br><span class="line">  -E 字串, --eval=字串        将 &lt;字串&gt; 作为 makefile 语句估值。</span><br><span class="line">  -f 文件, --file=文件, --makefile=文件</span><br><span class="line">                              从 &lt;文件&gt; 中读入 makefile。</span><br><span class="line">  -h, --help                  打印该消息并退出。</span><br><span class="line">  -i, --ignore-errors         忽略来自命令配方的错误。</span><br><span class="line">  -I 目录, --include-dir=目录  在 &lt;目录&gt; 中搜索被包含的 makefile。</span><br><span class="line">  -j [N], --jobs[=N]          同时允许 N 个任务；无参数表明允许无限个任务。</span><br><span class="line">  -k, --keep-going            当某些目标无法制作时仍然继续。</span><br><span class="line">  -l [N], --load-average[=N], --max-load[=N]</span><br><span class="line">                              在系统负载高于 N 时不启动多任务。</span><br><span class="line">  -L, --check-symlink-times   使用软链接及软链接目标中修改时间较晚的一个。</span><br><span class="line">  -n, --just-print, --dry-run, --recon</span><br><span class="line">                              只打印命令配方，不实际执行。</span><br><span class="line">  -o 文件, --old-file=文件, --assume-old=文件</span><br><span class="line">                              将 &lt;文件&gt; 当做很旧，不必重新制作。</span><br><span class="line">  -O[类型], --output-sync[=类型]</span><br><span class="line">                           使用 &lt;类型&gt; 方式同步并行任务输出。</span><br><span class="line">  -p, --print-data-base       打印 make 的内部数据库。</span><br><span class="line">  -q, --question              不运行任何配方；退出状态说明是否已全部更新。</span><br><span class="line">  -r, --no-builtin-rules      禁用内置隐含规则。</span><br><span class="line">  -R, --no-builtin-variables  禁用内置变量设置。</span><br><span class="line">  -s, --silent, --quiet       不输出配方命令。</span><br><span class="line">  --no-silent                 对配方进行回显（禁用 --silent 模式）。</span><br><span class="line">  -S, --no-keep-going, --stop</span><br><span class="line">                              关闭 -k。</span><br><span class="line">  -t, --touch                 touch 目标（更新修改时间）而不是重新制作它们。</span><br><span class="line">  --trace                     打印跟踪信息。</span><br><span class="line">  -v, --version               打印 make 的版本号并退出。</span><br><span class="line">  -w, --print-directory       打印当前目录。</span><br><span class="line">  --no-print-directory        关闭 -w，即使 -w 默认开启。</span><br><span class="line">  -W 文件, --what-if=文件, --new-file=文件, --assume-new=文件</span><br><span class="line">                              将 &lt;文件&gt; 当做最新。</span><br><span class="line">  --warn-undefined-variables  当引用未定义变量的时候发出警告。</span><br><span class="line"></span><br><span class="line">该程序为 aarch64-unknown-linux-gnu 编译</span><br><span class="line">报告错误到 &lt;bug-make@gnu.org&gt;</span><br></pre></td></tr></table></figure><p>Make命令依赖这个文件进行构建。Makefile文件也可以写为makefile， 或者用命令行参数指定为其他文件名。</p><p>例如</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make -f Makefile.txt</span><br></pre></td></tr></table></figure><h1 id="Makefile基本语法"><a href="#Makefile基本语法" class="headerlink" title="Makefile基本语法"></a>Makefile基本语法</h1><p>Makefile的编写一般遵循以下规则:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;target&gt; : &lt;prerequisites&gt; </span><br><span class="line">[tab]  &lt;commands&gt;</span><br></pre></td></tr></table></figure><p>target也就是一个目标文件，可以是Object File，也可以是执行文件。还可以是一个标签（Label）。</p><p>prerequisites就是，要生成那个target所需要的文件或是目标。</p><p>command也就是make需要执行的命令。（任意的Shell命令）</p><p>prerequisites中如果有一个以上的文件比target文件要新的话，command所定义的命令就会被执行。</p><p>下面是一个简单的Makefile示例。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">build: src</span><br><span class="line">gcc -c src/main.c -o src/main.o</span><br><span class="line">clean: src/main.o</span><br><span class="line">rm -rf src/main.o</span><br></pre></td></tr></table></figure><h1 id="Makefile扩展语法"><a href="#Makefile扩展语法" class="headerlink" title="Makefile扩展语法"></a>Makefile扩展语法</h1><h3 id="Makefile手动变量"><a href="#Makefile手动变量" class="headerlink" title="Makefile手动变量"></a>Makefile手动变量</h3><p>下面是一个Makefile的一部分:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">build: src</span><br><span class="line">cd src</span><br><span class="line">gcc -c main.c -o main.o</span><br><span class="line">gcc -c ui.c -o ui.o</span><br><span class="line">gcc -c src.c -o src.o</span><br></pre></td></tr></table></figure><p>我们可以看到[.o]文件的字符串被重复了三次，如果我们的工程需要加入一个新的[.o]文件，那么我们需要在三个地方加（应该是四个地方，还有一个地方在clean中，这里并没有展示）。当然，我们的makefile并不复杂，所以在两个地方加也不累，但如果makefile变得复杂，那么我们就有可能会忘掉一个需要加入的地方，而导致编译失败。所以，为了makefile的易维护，在makefile中我们可以使用变量。makefile的变量也就是一个字符串，理解成C语言中的宏可能会更好</p><p>比如，我们声明一个变量，叫objects, OBJECTS, objs, OBJS, obj, 或是 OBJ。我们在makefile一开始就这样定义:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">objects = main.o src.o ui.o</span><br><span class="line">outs : $(objects)</span><br></pre></td></tr></table></figure><p>于是，我们就可以很方便地在我们的makefile中以“$(objects)”的方式来使用这个变量了。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -o outs $(objects)</span><br></pre></td></tr></table></figure><p>同理。我们也可以使用系统自带变量。</p><p>有些有默认值，有些没有。比如常见的几个：</p><blockquote><p>CPPFLAGS : 预处理器需要的选项 如：-I<br>CFLAGS：编译的时候使用的参数 –Wall –g -c<br>LDFLAGS ：链接库使用的选项 –L -l</p></blockquote><h3 id="Makefile自动变量"><a href="#Makefile自动变量" class="headerlink" title="Makefile自动变量"></a>Makefile自动变量</h3><p>Makefile提供了很多自动变量，但常用的为以下三个。这些自动变量只能在规则中的命令中使用，其它地方使用都不行。</p><ul><li><p>$@ –&gt; 规则中的目标</p></li><li><p>$&lt; –&gt; 规则中的第一个依赖条件</p></li><li><p>$^ –&gt; 规则中的所有依赖条件</p></li></ul><p>例如:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">app: main.c func1.c fun2.c ​gcc $^ - o $@</span><br></pre></td></tr></table></figure><p>其中：$^表示main.c func1.c fun2.c，$&lt;表示main.c，$@表示app。</p><h3 id="Makefile模式规则"><a href="#Makefile模式规则" class="headerlink" title="Makefile模式规则"></a>Makefile模式规则</h3><p>模式规则是在目标及依赖条件中使用%来匹配对应的文件，比如在目录下有main.c, src.c, ui.c三个文件，对这三个文件的编译可以由一条规则完成：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%.o:%.c ​ $(CC) –c $&lt; -o $@</span><br></pre></td></tr></table></figure><p>这条模式规则表示：</p><p>main.o由main.c生成， ​ src.o由src.c生成， ​ src.o由src.c生成</p><h3 id="Makefile-目标"><a href="#Makefile-目标" class="headerlink" title="Makefile 目标"></a>Makefile 目标</h3><p>一般来说，make的最终目标是makefile中的第一个目标，而其它目标一般是由这个目标连带出来的。这是make的默认行为。当然，一般来说，你的makefile中的第一个目标是由许多个目标组成，你可以指示make，让其完成你所指定的目标。要达到这一目的很简单，需在make命令后直接跟目标的名字就可以完成（如前面提到的“make clean”形式）</p><p>任何在makefile中的目标都可以被指定成终极目标，但是除了以“-”打头，或是包含了“&#x3D;”的目标，因为有这些字符的目标，会被解析成命令行参数或是变量。甚至没有被我们明确写出来的目标也可以成为make的终极目标，也就是说，只要make可以找到其隐含规则推导规则，那么这个隐含目标同样可以被指定成终极目标。</p><p>使用指定终极目标的方法可以很方便地让我们编译我们的程序，例如下面这个例子：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">.PHONY: all</span><br><span class="line">all: arg1 arg2 arg3</span><br></pre></td></tr></table></figure><p>从这个例子中，我们可以使用“make all”命令来编译所有的目标（如果把all置成第一个目标，那么只需执行“make”），我们也可以使用 “make arg2”来单独编译目标“arg2”。</p><p>即然make可以指定所有makefile中的目标，那么也包括“伪目标”，于是我们可以根据这种性质来让我们的makefile根据指定的不同的目标来完成不同的事。</p><p>下面请看这个例子</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">claen: out</span><br><span class="line">rm -rf out</span><br></pre></td></tr></table></figure><p>如果当前目录下存在名为clean的文件，则该命令不执行。</p><p>最稳妥的做法是下面这样:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">.PHONY : clean</span><br><span class="line"></span><br><span class="line">clean :</span><br><span class="line">-rm -rf out</span><br></pre></td></tr></table></figure><p>.PHONY意思表示clean是一个“伪目标”，伪目标一般没有依赖的文件。而在rm命令前面加了一个小减号的意思就是，也许某些文件出现问题，但不要管，继续做后面的事。当然，clean的规则不要放在文件的开头，不然，这就会变成make的默认目标。</p><h3 id="Makefile返回值"><a href="#Makefile返回值" class="headerlink" title="Makefile返回值"></a>Makefile返回值</h3><p>一般地，Makefile有三个返回值:</p><ul><li>0 —— 表示成功执行。</li><li>1 —— 如果make运行时出现任何错误，其返回1。</li><li>2 —— 如果你使用了make的“-q”选项，并且make使得一些目标不需要更新，那么返回2。</li></ul><p>实际上一个Makefile可能不仅只有这三个返回值。</p><h3 id="引进其他Makefile"><a href="#引进其他Makefile" class="headerlink" title="引进其他Makefile"></a>引进其他Makefile</h3><p>只需要在Makefile开头加入</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">include &lt;src/Makefile&gt;</span><br></pre></td></tr></table></figure><h3 id="Makefile判断"><a href="#Makefile判断" class="headerlink" title="Makefile判断"></a>Makefile判断</h3><p>请看下面的例子:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ifeq ($(CC),gcc)</span><br><span class="line">  ld=$(ld)</span><br><span class="line">else</span><br><span class="line">  ld=$(ld.lld)</span><br><span class="line">endif</span><br></pre></td></tr></table></figure><p>上面代码判断当前编译器是否 gcc ，然后指定不同ld。</p><h3 id="附录-一个简单的Makefile例子"><a href="#附录-一个简单的Makefile例子" class="headerlink" title="附录:一个简单的Makefile例子"></a>附录:一个简单的Makefile例子</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">CC = gcc</span><br><span class="line">CXX = g++</span><br><span class="line">CFLAGS = -static -Wall -o</span><br><span class="line"></span><br><span class="line">SRCS = $(wildcard *.c *.cpp)</span><br><span class="line"></span><br><span class="line">OBJS = $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SRCS)))</span><br><span class="line"></span><br><span class="line">%.o: %.c</span><br><span class="line">$(CC) $(CFLAGS) $@ $&lt;</span><br><span class="line">%.o: %.cpp</span><br><span class="line">$(CXX) $(CFLAGS) $@ $&lt;</span><br><span class="line"></span><br><span class="line">.PHONY: all</span><br><span class="line">all: $(OBJS)</span><br><span class="line"></span><br><span class="line">.PHONY: clean</span><br><span class="line">clean:</span><br><span class="line">-rm -rf *.o</span><br></pre></td></tr></table></figure><p>这个Makefile可以编译目录下所有独立的cpp和c</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="makefile" scheme="https://dpkg123.netlify.app/tags/makefile/"/>
    
  </entry>
  
  <entry>
    <title>linux电脑给手机进行9008刷机</title>
    <link href="https://dpkg123.netlify.app/2023/07/28/linux%E7%94%B5%E8%84%91%E7%BB%99%E6%89%8B%E6%9C%BA%E8%BF%9B%E8%A1%8C9008%E5%88%B7%E6%9C%BA/"/>
    <id>https://dpkg123.netlify.app/2023/07/28/linux%E7%94%B5%E8%84%91%E7%BB%99%E6%89%8B%E6%9C%BA%E8%BF%9B%E8%A1%8C9008%E5%88%B7%E6%9C%BA/</id>
    <published>2023-07-28T11:30:41.000Z</published>
    <updated>2023-07-28T11:30:41.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h1 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h1><ul><li>一台装有linux的电脑</li><li>一台能进入9008模式的手机</li><li>一双手</li></ul><h1 id="安装依赖"><a href="#安装依赖" class="headerlink" title="安装依赖"></a>安装依赖</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install adb fastboot python3-dev python3-pip liblzma-dev git -y</span><br></pre></td></tr></table></figure><h1 id="安装驱动"><a href="#安装驱动" class="headerlink" title="安装驱动"></a>安装驱动</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install libusb-dev -y</span><br></pre></td></tr></table></figure><h1 id="安装edl工具"><a href="#安装edl工具" class="headerlink" title="安装edl工具"></a>安装edl工具</h1><h3 id="克隆"><a href="#克隆" class="headerlink" title="克隆"></a>克隆</h3><p>执行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git --init --recursive clone https://github.com/bkerler/edl</span><br></pre></td></tr></table></figure><h3 id="复制规则"><a href="#复制规则" class="headerlink" title="复制规则"></a>复制规则</h3><p>执行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo cp Drivers/51-edl.rules /etc/udev/rules.d</span><br><span class="line">sudo cp Drivers/50-android.rules /etc/udev/rules.d</span><br></pre></td></tr></table></figure><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p>执行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">python3 setup.py build</span><br><span class="line">sudo python3 setup.py install</span><br></pre></td></tr></table></figure><h1 id="使用edl工具箱"><a href="#使用edl工具箱" class="headerlink" title="使用edl工具箱"></a>使用edl工具箱</h1><h3 id="手机进入9008模式"><a href="#手机进入9008模式" class="headerlink" title="手机进入9008模式"></a>手机进入9008模式</h3><p>执行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">adb reboot edl</span><br></pre></td></tr></table></figure><p>输入</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">edl</span><br></pre></td></tr></table></figure><p>如无报错，证明连接成功。</p><h3 id="刷入分区"><a href="#刷入分区" class="headerlink" title="刷入分区"></a>刷入分区</h3><p>这里以boot为例。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">edl w boot boot.img</span><br></pre></td></tr></table></figure><h3 id="重启"><a href="#重启" class="headerlink" title="重启"></a>重启</h3><p>执行</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">edl restart</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="刷机" scheme="https://dpkg123.netlify.app/tags/%E5%88%B7%E6%9C%BA/"/>
    
    <category term="9008" scheme="https://dpkg123.netlify.app/tags/9008/"/>
    
  </entry>
  
  <entry>
    <title>浅谈安卓内核的碎片化</title>
    <link href="https://dpkg123.netlify.app/2023/07/20/%E6%B5%85%E8%B0%88%E5%AE%89%E5%8D%93%E5%86%85%E6%A0%B8%E7%9A%84%E7%A2%8E%E7%89%87%E5%8C%96/"/>
    <id>https://dpkg123.netlify.app/2023/07/20/%E6%B5%85%E8%B0%88%E5%AE%89%E5%8D%93%E5%86%85%E6%A0%B8%E7%9A%84%E7%A2%8E%E7%89%87%E5%8C%96/</id>
    <published>2023-07-19T22:51:37.000Z</published>
    <updated>2023-07-19T22:51:37.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>如题所见，这篇文章浅谈一下安卓内核的碎片化。<br><del>我编译过安卓内核我觉得我应该有话语权.jpg</del></p><h1 id="gki时期"><a href="#gki时期" class="headerlink" title="gki时期"></a>gki时期</h1><p>这里指gki2.0时期。gki1.0不在讨论范围内</p><h3 id="什么是gki？"><a href="#什么是gki？" class="headerlink" title="什么是gki？"></a>什么是gki？</h3><p><a href="https://source.android.google.cn/docs/core/architecture/kernel/generic-kernel-image?hl=zh-cn">谷歌官方对gki的介绍:</a></p><blockquote><p>通用内核映像 (GKI) 项目通过统一核心内核并将 SoC 和板级支持从核心内核移至可加载模块中，解决了内核碎片化问题。GKI 内核为内核模块提供了稳定的内核模块接口 (KMI)，因此模块和内核可以独立进行更新。</p></blockquote><h3 id="GKI-2-0"><a href="#GKI-2-0" class="headerlink" title="GKI 2.0"></a>GKI 2.0</h3><blockquote><p>搭载 Android S (2021) 平台版本且使用内核版本 v5.x（5.x 是 2020 年年底被选为 LTS 的内核版本）或更高版本的设备必须附带 GKI 内核。将提供已签名的启动映像，并通过 LTS 和重大问题修复定期对其进行更新。由于 KMI 将保持二进制稳定性，因此无需对供应商映像进行任何更改，即可安装这些启动映像。</p></blockquote><h3 id="gki的特性"><a href="#gki的特性" class="headerlink" title="gki的特性"></a>gki的特性</h3><ul><li>基于 ACK 来源构建而成。</li><li>是每个架构和每个 LTS 版本的单内核二进制文件以及关联的可加载模块（目前只有适用于 android11-5.4 和 android12-5.4 的 arm64）。</li><li>已经过关联 ACK 支持的所有 Android 平台版本的测试。在 GKI 内核版本的生命周期内不会发生功能弃用。</li><li>为给定 LTS 中的驱动程序提供了稳定版 KMI。</li><li>不包含 SoC 专用代码或板卡专用代码。</li></ul><p><img src="https://source.android.google.cn/static/docs/core/architecture/images/generic-kernel-image-architecture.png?hl=zh-cn" alt="图片"></p><p>这就意味着只要内核是gki内核，就可以通刷同内核大版本(例如5.15.xxx)的内核。<br>某些厂商将私有代码集成在了内核里面。刷入gki内核将丢失私有代码所产生的特性。例如小米的机器刷完gki后会丢快充。</p><h1 id="非gki时期"><a href="#非gki时期" class="headerlink" title="非gki时期"></a>非gki时期</h1><p>主要指的是内核版本为4.x或3.x的内核版本时期。这一阶段，厂商内核的碎片化是极其严重的。<br>一般地，android kernel的来源是这样的:</p><blockquote><p>linux kernel &gt; aosp kernel &gt; 供应商添加soc或外围设备的驱动及特性 &gt; oem厂商添加附加特性 &gt; android kernel</p></blockquote><p>供应商内核和设备内核位于 ACK 的下游。供应商通过修改内核源代码并添加设备驱动程序，添加了对 SoC 和外围设备的支持。这些修改内容可能很多，以至于设备上运行的代码中有多达 50% 是树外代码，并非来自上游 Linux 和 AOSP 通用内核。<br><img src="https://source.android.google.cn/static/docs/core/architecture/images/generic-kernel-image-overview.png?hl=zh-cn" alt="图片"></p><p>几乎所有设备都具有自定义内核。这就导致了内核碎片化问题。</p><h3 id="aosp-kernel"><a href="#aosp-kernel" class="headerlink" title="aosp kernel"></a>aosp kernel</h3><p><del>众所周知，android不是gnu&#x2F;linux,</del>这就意味着aosp kernel和linux kernel会有一些不同。</p><p><a href="https://android.googlesource.com/kernel/common/">AOSP通用内核</a>（也称为 Android 通用内核或 ACK）是 kernel.org 内核的下游，包含与 Android 社区相关但尚未合并到 Mainline 内核或长期支持 (LTS) 内核的补丁程序。这些补丁程序可能包括：</p><ul><li>Android 功能所需的向后移植和精选的上游功能</li><li>可供 Android 设备使用但仍处于上游开发阶段的功能（例如，Energy Aware Scheduler 任务放置优化）。</li><li>对其他生态系统合作伙伴有用的供应商&#x2F;原始设备制造商 (OEM) 功能（例如，sdcardfs）。</li></ul><p>目前 Android 通用内核也分以下两种：</p><ul><li>功能内核<blockquote><p>包含最新 Android 平台版本功能的增强内核称为功能内核。对于 Android 11，功能内核基于内核版本 4.14.y、4.19.y 和 5.4.y。在过去的平台版本中，功能内核与启动内核相同。但在 Android 12 中，将有两个功能内核和三个启动内核。</p></blockquote></li><li>启动内核<blockquote><p>指定的启动内核可用于启动搭载特定 Android 平台版本的设备。对于 Android 11，可以使用基于内核版本 4.14.y、4.19.y 和 5.4.y 的内核启动设备。</p></blockquote></li></ul><p>每个 Android 平台版本都支持基于三个 Linux 内核版本中的任何一个启动新设备。例如Android 11 的启动内核为 android-4.14-stable、android-4.19-stable 和 android11-5.4。</p><p>由于更新平台版本时通常不需要升级内核，因此缺少平台版本最新功能的内核仍然可以用来启动设备。因此，即使设备上的平台版本已升级到 Android 11，为 Android 10 设计的内核（例如 android-4.19-q）也可以在设备上使用。</p><p>这就导致某些厂商秉承着能用就行的原则，能不升级内核版本就不升级内核版本。吃力可能不讨好的事厂商不会去干。</p><p>厂商不升级内核版本导致了Android 框架代码必须假设支持的内核版本多达 5 个，并且没有针对新的平台版本进行任何内核更改（Android 10 支持内核版本 3.18、4.4、4.9、4.14 和 4.19；在某些情况下，这些版本自 2017 年 Android 8 发布以来还未添加新功能）。</p><h3 id="supplier-kernel"><a href="#supplier-kernel" class="headerlink" title="supplier kernel"></a>supplier kernel</h3><p>供应商在aosp kernel的基础上添加设备（相机，屏幕等）的驱动或特性所产生的内核。</p><h3 id="oem-kernel"><a href="#oem-kernel" class="headerlink" title="oem kernel"></a>oem kernel</h3><p>oem厂商在supplier kernel后添加大量私有特性后所发布的源码。大部分厂商都是非实时开源的。</p><p>通俗讲就是一次性开源，后续安卓版本更新内核代码不会及时提交。</p><p>而且厂商会添加大量私有特性在内核源码中。</p><p>例如<a href="https://github.com/Coconutat/HuaweiP10-GSI-And-Modify-Or-Support-KernelSU-Tutorial/wiki/7.KernelSU%E9%80%82%E9%85%8DEMUI9%E6%88%969.1.0%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%86%85%E6%A0%B8">华为</a>会在config里添加大量海思麒麟的特性。<br>而<a href="https://github.com/dabao1955/android_kernel_OPPO_OP4ED5/commit/d05b666078e50111f8cf74033221545a862518c2">OPPO</a>会将私有特性配置在xxxfetures.mk里。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="kernel" scheme="https://dpkg123.netlify.app/tags/kernel/"/>
    
    <category term="android" scheme="https://dpkg123.netlify.app/tags/android/"/>
    
    <category term="android kernel" scheme="https://dpkg123.netlify.app/tags/android-kernel/"/>
    
    <category term="gki" scheme="https://dpkg123.netlify.app/tags/gki/"/>
    
  </entry>
  
  <entry>
    <title>哔哩哔哩危险地带部分补档</title>
    <link href="https://dpkg123.netlify.app/2023/06/29/%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%E5%8D%B1%E9%99%A9%E5%9C%B0%E5%B8%A6%E9%83%A8%E5%88%86%E8%A1%A5%E6%A1%A3/"/>
    <id>https://dpkg123.netlify.app/2023/06/29/%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9%E5%8D%B1%E9%99%A9%E5%9C%B0%E5%B8%A6%E9%83%A8%E5%88%86%E8%A1%A5%E6%A1%A3/</id>
    <published>2023-06-28T20:09:52.000Z</published>
    <updated>2023-06-28T20:09:52.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><h3 id="地址"><a href="#地址" class="headerlink" title="地址"></a>地址</h3><p><a href="../../../../ubc26/">点击这里</a></p><h3 id="备注"><a href="#备注" class="headerlink" title="备注"></a>备注</h3><p>搬运自<a href="https://ubc2.github.io/links/menu.html">ubc26</a>, 侵删</p>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="哔哩哔哩" scheme="https://dpkg123.netlify.app/tags/%E5%93%94%E5%93%A9%E5%93%94%E5%93%A9/"/>
    
    <category term="av10492" scheme="https://dpkg123.netlify.app/tags/av10492/"/>
    
    <category term="猎奇" scheme="https://dpkg123.netlify.app/tags/%E7%8C%8E%E5%A5%87/"/>
    
  </entry>
  
  <entry>
    <title>使用dh_make快速构建deb</title>
    <link href="https://dpkg123.netlify.app/2023/06/22/%E4%BD%BF%E7%94%A8dh-make%E5%BF%AB%E9%80%9F%E6%9E%84%E5%BB%BAdeb/"/>
    <id>https://dpkg123.netlify.app/2023/06/22/%E4%BD%BF%E7%94%A8dh-make%E5%BF%AB%E9%80%9F%E6%9E%84%E5%BB%BAdeb/</id>
    <published>2023-06-22T13:34:29.000Z</published>
    <updated>2023-06-22T13:34:29.000Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>注: 本方法适用于需要编译的项目</p><h1 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h1><p>以<a href="https://github.com/moe-hacker/ruri">ruri</a>为例<br>克隆</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/moe-hacker/ruri</span><br></pre></td></tr></table></figure><p>安装编译所需依赖</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install dh_make dpkg-dev build-essential libcap-dev -y</span><br></pre></td></tr></table></figure><p>删除.git文件夹</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd ruri</span><br><span class="line">rm -rf .git</span><br></pre></td></tr></table></figure><h1 id="运行dh-make生成基本文件"><a href="#运行dh-make生成基本文件" class="headerlink" title="运行dh_make生成基本文件"></a>运行dh_make生成基本文件</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dh_make --createorig -y -s -a -c apache -e Moe-hacker@outlook.com -p ruri</span><br></pre></td></tr></table></figure><p>dh_make是一个用于创建Debian软件包的工具，它可以根据源代码生成debian目录和一些模板文件。dh_make的选项有以下几种：</p><ul><li>-e, –email <email>：指定维护者的电子邮件地址，如果不指定，则使用环境变量DEBEMAIL或EMAIL。</li><li>-f, –file <file>：指定源代码的压缩文件，如果不指定，则使用当前目录下的第一个压缩文件。</li><li>-n, –native：创建一个原生的Debian软件包，即没有上游的源代码。</li><li>-s, –single：创建一个单一的二进制软件包，即只有一个deb文件。</li><li>-i, –indep：创建一个独立的二进制软件包，即不依赖于架构的deb文件。</li><li>-m, –multi：创建一个多个二进制软件包，即有多个deb文件。</li><li>-l, –library：创建一个库软件包，即包含共享库或静态库的deb文件。</li><li>-k, –kmod：创建一个内核模块软件包，即包含内核模块的deb文件。</li><li>-b, –cdbs：使用cdbs（Common Debian Build System）来构建软件包，这是一种简化的构建系统。</li><li>-r, –createorig：创建一个.orig.tar.gz文件，这是Debian软件包中用于存放上游源代码的压缩文件。</li><li>-c, –copyright <name>：指定版权所有者的姓名，如果不指定，则使用环境变量DEBFULLNAME或NAME。</li><li>-p, –packagename <name>：指定软件包的名称，如果不指定，则使用源代码目录的名称。</li><li>-v, –version <version>：指定软件包的版本号，如果不指定，则使用源代码压缩文件中的版本号。</li><li>-t, –templates <dir>:指定模板文件的目录，如果不指定，则使用&#x2F;usr&#x2F;share&#x2F;dh-make&#x2F;templates&#x2F;目录。</li><li>-d, –defaultless：不使用默认值来填充模板文件中的字段，而是让用户自己输入。</li><li>-y, –yes：不询问用户任何问题，而是使用默认值或环境变量来填充模板文件中的字段。</li><li>-h, –help：显示帮助信息并退出。</li></ul><p>当前目录下会自动创建debian目录,目录下有很多打包使用的模板文件,以.ex&#x2F;.EX结尾。可以删除换成自己的</p><h1 id="修改文件"><a href="#修改文件" class="headerlink" title="修改文件"></a>修改文件</h1><p>主要修改以下几个文件:</p><ul><li>postinst<br>可以用作者配置好的，如果没有可以不用填写</li><li>changelog<br>参考以下格式:</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ruri (9.0) unstable; urgency=low</span><br><span class="line"></span><br><span class="line">  * Initial release.</span><br><span class="line"></span><br><span class="line"> -- Moe-hacker &lt;Moe-hacker@outlook.com&gt;  Mon, 19 Jun 2023 16:32:34 +0800</span><br></pre></td></tr></table></figure><ul><li>copyright</li></ul><p>一般不用修改。如果要往里添加的话参考</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Files: src/riru</span><br><span class="line">Copyright: 2023 Moe-hacker &lt;moe-hacker@outlook.com&gt;</span><br><span class="line"></span><br><span class="line">License: Apache-2.0</span><br></pre></td></tr></table></figure><ul><li>compat<br>一般为9,构建的时候可能会出现警告，调成10即可。</li><li>rules<br>参考</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">#!/usr/bin/make -f</span><br><span class="line">include /usr/share/dpkg/default.mk</span><br><span class="line"></span><br><span class="line">%:</span><br><span class="line">dh $@ --parallel</span><br><span class="line"></span><br><span class="line">override_dh_auto_configure:</span><br><span class="line">dh_auto_configure -- DEFINES+=&quot;VERSION=$(DEB_VERSION_UPSTREAM)&quot;</span><br></pre></td></tr></table></figure><ul><li>ruri.install</li></ul><p>默认是没有这个文件的，需要手动创建。<br>建议先make一下。看看编译后生成的文件到底在哪。<br>ruri编译后默认生成到根目录<br>就可以写</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ruri /usr/bin</span><br></pre></td></tr></table></figure><ul><li>control<br>主要修改以下内容<br>Maintainer: 换成你自己的名字+你自己的邮箱，邮箱可以不填<br>Homepage: 项目主页<br>Depends: 所需要的依赖<br>Build-Depends: 编译所需要的依赖<br>Description: 描述<br>参考</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">ource: ruri</span><br><span class="line">Priority: optional</span><br><span class="line">Maintainer: Moe-hacker &lt;Moe-hacker@outlook.com&gt;</span><br><span class="line">Build-Depends: debhelper-compat (= 13) ,clang ,build-essential ,libcap-dev</span><br><span class="line">Standards-Version: 4.6.0</span><br><span class="line">Homepage: https://github.com/Moe-hacker/ruri</span><br><span class="line">Rules-Requires-Root: no</span><br><span class="line"></span><br><span class="line">Package: ruri</span><br><span class="line">Architecture: any</span><br><span class="line">Depends: xz-utils</span><br><span class="line">Description: chroot/unshare Linux containers</span><br><span class="line"> simple &amp; secure</span><br></pre></td></tr></table></figure><h1 id="打包deb"><a href="#打包deb" class="headerlink" title="打包deb"></a>打包deb</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dpkg-buildpackage -b -us -uc</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;link rel=&quot;stylesheet&quot; class=&quot;aplayer-secondary-style-marker&quot; href=&quot;/assets/css/APlayer.min.css&quot;&gt;&lt;script src=&quot;/assets/js/APlayer.min.js&quot; cla</summary>
      
    
    
    
    
    <category term="linux" scheme="https://dpkg123.netlify.app/tags/linux/"/>
    
    <category term="debian" scheme="https://dpkg123.netlify.app/tags/debian/"/>
    
  </entry>
  
</feed>
