| <html devsite><head> |
| <title>使用引导加载程序</title> |
| <meta name="project_path" value="/_project.yaml"/> |
| <meta name="book_path" value="/_book.yaml"/> |
| </head> |
| <body> |
| <!-- |
| Copyright 2017 The Android Open Source Project |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <h2 id="unlock">解锁和 Trusty</h2> |
| <h3 id="recommendations">建议</h3> |
| <p> |
| 所有 Google 品牌设备都应设为可解锁,以便可以重新刷写上述所有分区。可以使用 <code>fastboot |
| flashing unlock</code> 设置此解锁模式,设置后,此模式在系统重新启动后应保留。 |
| </p> |
| <p> |
| 除非<code> fastboot flashing get_unlock_ability </code>为“1”,否则设备应拒绝 <code>fastboot flashing unlock</code> 命令。如果 <code>get_unlock_ability</code> 为“0”,则用户需要启动进入主屏幕,依次转到<em></em>“设置”>“系统”> <a href="https://developer.android.com/studio/debug/dev-options.html">开发者选项</a>菜单并启用 <strong>OEM 解锁</strong>选项,将 <code>unlock_ability</code> 设置为“1”。该标记在重新启动后以及恢复出厂设置后应保持不变。 |
| </p> |
| <p> |
| 发送 <code>fastboot flashing unlock</code> 命令后,设备应提示用户,警告他们非官方映像可能会有问题。确认后,应恢复出厂设置,以防止未经授权的数据访问。即使引导加载程序无法正确重新格式化设备,也应将设备恢复出厂设置。只有在恢复出厂设置后,才能设置持久性标记,以便重新刷写设备。 |
| </p> |
| <p> |
| <code>fastboot flashing lock</code> 命令会重新锁定设备并使其恢复出厂设置,以便将来尝试刷写/解锁设备时需要再次恢复出厂设置。 |
| </p> |
| <p> |
| 所有尚未覆盖的 RAM 都应在 <code>fastboot flashing |
| unlock</code> 过程中被重置。此措施可防止出现读取上次启动的剩余 RAM 内容这一攻击。同样,解锁的设备应在每次启动时清除 RAM,前提是这样做不会造成不可接受的延迟,但应保留用于内核的 <a href="https://www.kernel.org/doc/html/v4.12/admin-guide/ramoops.html" class="external"><code>ramoops</code></a> 的区域。 |
| </p> |
| <p> |
| 打算零售的设备应以锁定状态发货(并且 <code>get_unlock_ability</code> 返回“0”)。这是为了确保攻击者不能通过安装自己的系统或启动映像来损害设备。 |
| </p> |
| <h3 id="properties">属性</h3> |
| <p> |
| <code> ro.oem_unlock_supported</code> 属性应在编译时根据设备是否支持刷写解锁来设置。 |
| 如果设备不支持刷写解锁,应将 <code>ro.oem_unlock_supported</code> 设置为“0”;如果支持刷写解锁,应将其设置为“1”。 |
| </p> |
| <p> |
| 如果设备支持刷写解锁(即 <code>ro.oem_unlock_supported = |
| 1</code>),则引导加载程序应通过将内核命令行变量 <code>androidboot.flash.locked</code>(或 <code>/firmware/android/flash.locked</code> DT 属性)设置为“1”(如果已锁定)或“0”(如果已解锁)来指示锁定状态。 |
| </p> |
| <p> |
| <strong>注意</strong>:对于支持 <a href="/security/verifiedboot/dm-verity">dm-verity</a> 的设备,您可以改用 <code>ro.boot.verifiedbootstate</code> 来设置 <code>ro.boot.flash.locked</code> 的值(如果验证启动状态显示为橙色,则值为“0”,即已解锁)。 |
| </p> |
| <h3 id="flashing-lock-unlock_critical">刷写锁定/解锁关键部分</h3> |
| <p> |
| 设备应支持锁定和解锁关键部分。这些关键部分是指将设备启动到引导加载程序所需的任何部分,可能包括 fuse、传感器中枢的虚拟分区、第一阶段引导加载程序等等。 |
| </p> |
| <p> |
| 锁定关键部分是指防止设备上运行的任何代码(内核、恢复映像、OTA 代码等)故意修改任何关键部分。这意味着,如果设备处于锁定关键部分状态,则 OTA 应无法更新关键部分。从锁定状态转换为解锁状态应需要与设备进行物理交互。 |
| </p> |
| <p> |
| 该物理交互与 <code>fastboot flashing |
| unlock</code> 产生的效果相似:用户必须按设备上的某些物理按钮。设计不应允许在没有进行物理交互的情况下以编程方式从 <code>lock critical</code> 状态转换为 <code>unlock critical </code>状态。设备应以 <code>unlock critical</code> 状态发货。 |
| </p> |
| <h2 id="designation-of-critical-partitions-data">关键分区/数据的定义</h2> |
| <p> |
| 即运行设备所需的任何分区或数据,需要满足以下任一条件: |
| </p><ul> |
| <li>可重新刷写 - 可重新编译、已提供或可通过某个 <code>fastboot oem</code> 命令提取 |
| </li><li>受到全面保护(即,根据上一部分被视为关键部分)</li></ul> |
| <p> |
| 包括每个设备的出厂特定设置、序列号、校准数据等。</p> |
| <h2 id="off-mode-charging">关机模式充电</h2> |
| <p> |
| 如果设备支持“关机模式充电”或在接通电源后自动启动到一种特殊模式,则 <code>fastboot oem off-mode-charge 0</code> 应绕过这些特殊模式,并像用户按了电源按钮一样启动。 |
| </p> |
| <h2 id="bootloader-for-trusty">Trusty 的引导加载程序</h2> |
| <p> |
| <a href="/security/trusty/">Trusty</a> 是 Google 可信执行环境 (TEE) 操作系统的实现,它与 Android 一起运行。此处列出的是使用 ARM Trustzone<sup>TM</sup> 技术提供 TEE 的设备需遵循的规范。 |
| </p> |
| <p> |
| 如果将 Trusty 用作 ARM 设备上的安全操作系统解决方案,则应按照下面几个部分所述的内容实现引导加载程序。 |
| </p> |
| <h3 id="initialization">初始化</h3> |
| <p> |
| 要加载并初始化 Trusty 操作系统 (TOS),引导加载程序应执行以下操作: |
| </p><ul> |
| <li>设置并配置所有可用的 RAM |
| </li><li>至少初始化一个串行端口 |
| </li><li>验证 TOS 映像的签名 |
| </li><li>将 TOS 加载到 RAM 中(不支持通过刷写或 TCM 执行) |
| </li><li>在设置状态和寄存器后,跳转到 TOS 映像中的第一条指令,如下一部分中所述</li></ul> |
| <h3 id="calling-into-tos-image">调用 TOS 映像</h3> |
| <p> |
| 应在入口时配置以下状态: |
| </p><ul> |
| <li>已关闭 MMU |
| </li><li>已刷写并关闭数据缓存(指令缓存可以开启或关闭) |
| </li><li>已停用所有中断(IRQ 和 FIQ) |
| </li><li>在 ARM v7 上,CPU 处于 SVC 模式;在 ARM v8 上,CPU 处于 EL3 模式 |
| </li><li>寄存器处于以下状态:<ul> |
| <li>r0/x0:分配给 TOS 的内存大小。 |
| </li><li>r1/x1:连续内存块(包含特定于平台的启动参数)的物理地址。此块的布局特定于平台。 |
| </li><li>r2/x2:上述内存块的大小。 |
| </li><li>r14/x30:返回在 TOS 初始化后跳转到(在非安全模式下)的地址。</li> </ul> |
| </li> </ul> |
| <p> |
| <strong>注意</strong>:r0-r3/x0-x3 也可充当 TOS 的擦写寄存器。返回时不会保留它们的值。 |
| </p> |
| <p> |
| 在 64 位平台上: |
| </p><ul> |
| <li>只有 w0-w2 用于参数,所以 x0-x2 应仅包含 32 位值。 |
| </li><li>x30 可以包含一个 64 位值。 |
| </li><li>将 x0 中的值添加到 TOS 入口点的基址时,应得出一个 32 位值。添加到 x1 中的启动参数块的地址时,寄存器 x2 中的大小也是如此。</li></ul> |
| <h3 id="return-from-tos">从 TOS 返回</h3> |
| <p> |
| TOS 在完成初始化后会在非安全模式下(SCR.NS 设置为“1”)返回引导加载程序,以便引导加载程序可以继续加载主要操作系统(例如 Android)。 |
| </p> |
| |
| </body></html> |