플래싱, 부팅, 업데이트

이미지 플래싱

flash 명령어는 호스트 fastboot 도구가 erase 명령어를 먼저 전송하지 않는 한 파티션을 삭제하지 않습니다. 이 때문에 'skip' 블록으로 시작하여 이미 쓰기가 완료된 영역을 탐색하는 희소 이미지를 다수 사용하는 여러 개의 작은 청크의 대규모 파티션을 플래싱할 수 있게 됩니다. 이러한 이미지를 즉시 생성하는 작업은 fastboot 호스트 측 도구에서 이미 처리되고 있습니다.

잠금 해제 모드에서 플래싱하기 전에 라디오 및 부트로더 이미지에서 상태 검사를 완료해야 합니다. 예를 들어 빌드에서 생성된 android-info.txt와 비교하여 버전이 일치하는지 확인합니다. 또한 플래시 시점에 부트로더 이미지 서명을 확인하여 유효성 검사(안티 롤백 기능을 포함하고 있을 수 있음)를 부팅 중에 통과하도록 합니다.

Google 브랜드 기기의 경우 이전 버전의 부트로더로 올바르게 플래싱되며 상업용으로 출시된 첫 번째 부트로더부터 시작하여 출시순으로 진행됩니다.

부팅: 커널 명령줄

커널 명령줄은 다음 위치에서 함께 연결되어야 합니다.

  • 부트로더 명령줄: 부트로더에 의해 결정되는 정적 및 동적 매개변수 집합
  • 기기 트리: chosen/bootargs 노드에서
  • defconfig: CONFIG_CMDLINE에서
  • boot.img: cmdline에서(오프셋 및 크기 관련 정보는 system/core/mkbootimg/bootimg.h 참조)
  • 전원 관리 집적 회로(PMIC), 기타 하드웨어 리소스, 재부팅 매직 인수 메시징(LINUX_REBOOT_CMD_RESTART2)을 통해 결정한 대로 Android 호환성 정의 문서에 의한 표준 재부팅 또는 종료 이유로, androidboot.bootreason=<reason>으로 랜딩됩니다.

부팅: 기기 트리/기기 트리 오버레이

다양한 구성을 지원하기 위해 부트로더는 부트로더가 실행되는 하드웨어/제품 버전을 식별하고 올바른 기기 트리 오버레이 집합을 로드할 수 있습니다.

커널 주소 공간 레이아웃 임의 추출 지원

커널 이미지가 로드되는 가상 주소의 임의 추출을 지원하기 위해(커널 구성 RANDOMIZE_BASE에서 사용 설정) 부트로더는 DT 노드 /chosen/kaslr-seed에 있는 임의의 u64 값을 전달하여 엔트로피를 제공해야 합니다.

자체 검사 부팅 구현

자체 검사 부팅을 참조하세요.

업데이트 지원

Google 무선 업데이트(GOTA)의 업데이트 프로세스를 지원하려면 복구 RAM 디스크가 있어야 합니다.

표준 AOSP 복구 이미지를 사용하는 경우 부트로더는 부팅 중에 기타 파티션의 첫 32바이트를 읽고, 데이터가 '부팅-복구'와 일치할 때 복구 이미지로 부팅해야 합니다. 이렇게 하면 보류 중인 복구 작업(예: OTA 적용, 데이터 삭제 실행)이 완료될 때까지 재개될 수 있습니다.

복구 및 부트로더 통신에 사용되는 플래시의 블록 콘텐츠에 관한 자세한 내용은 bootable/recovery/bootloader_message/bootloader_message.h를 참조하세요.

A/B 업데이트

OEM에서 A/B 업데이트를 지원하기로 하는 경우 부트로더는 다음 기준을 충족해야 합니다.

  • OTA를 통해 업데이트되는 모든 파티션은 복구를 통하지 않고 기본 시스템이 부팅되는 동안 업데이트할 수 있어야 합니다.
  • A/B 업데이트의 경우 업데이터는 부팅 제어 HAL을 쿼리하고, 현재 사용하지 않는 부팅 슬롯을 업데이트하고, HAL을 통해 활성 슬롯을 변경한 다음 업데이트된 운영체제로 재부팅합니다. 부팅 제어 HAL 구현을 참조하세요.
  • A/B를 지원하는 모든 파티션은 이름에 접미사가 추가됩니다. 이를 통해 부트로더의 특정 슬롯에 속한 파티션이 구분됩니다. 각 파티션에는 값이 'yes'와 상응하는 변수 has-slot:이 있습니다.
  • 슬롯의 이름은 접미사가 _a, _b, _c 등인 파티션에 상응하는 a, b, c 등으로, 알파벳 순서에 따라 지정됩니다.
  • 부트로더는 다음 방법 중 하나를 사용하여 어떤 슬롯이 부팅되었는지 운영체제에 알려야 합니다.
    • DT 속성: /firmware/android/slot_suffix 또는
    • 명령줄 속성: androidboot.slot_suffix
  • 부트로더는 boot_control HAL을 지원해야 합니다(hardware/libhardware/include/hardware/boot_control.h).
  • A/B에서 /system을 부팅하려면 부트로더는 커널 명령줄에서 ro root=/dev/[node] rootwait skip_initramfs init=/init를 전달해야 합니다. skip_initramfs를 전달하지 않으면 복구로 부팅됩니다.
  • slot-retry-countsetActiveBootSlot 콜백 또는 fastboot set_active 명령어를 통한 부팅 제어 HAL에 의해 양의 값으로 재설정됩니다(보통 '3'으로 재설정됨).
  • 슬롯의 일부인 파티션을 수정하는 경우 부트로더는 'successfully booted'를 지우고 문제가 되는 슬롯의 retry_count를 재설정합니다.
  • 부트로더는 로드할 슬롯도 결정합니다. 결정 흐름을 보려면 이 섹션의 다이어그램을 참조하세요. 일반적인 단계는 다음과 같습니다.
    1. 시도할 슬롯을 결정합니다. 'slot-unbootable'으로 표시된 슬롯을 로드해서는 안 됩니다. 이 슬롯은 빠른 부팅에서 반환한 값과 일치해야 하며, 이제 현재 슬롯으로 지칭됩니다.
    2. 현재 슬롯이 slot-successful로 표시되어 있지 않고 slot-retry-count가 0인가요?
      현재 슬롯을 'slot-unbootable'로 표시한 뒤 'unbootable'이 아닌 'slot-successful'로 표시된 다른 슬롯을 선택합니다. 이제 이 슬롯은 선택된 슬롯입니다. 사용 가능한 현재 슬롯이 없는 경우 복구로 부팅하거나 사용자에게 도움이 되는 오류 메시지를 표시합니다.
    3. 적절한 boot.img를 선택하고 커널 명령줄에서 올바른 시스템 파티션의 경로를 포함합니다.
    4. 복구로 부팅하지 않는 경우 커널 명령줄에 skip_initramfs를 추가합니다.
    5. DT 또는 명령줄 slot_suffix 매개변수를 채웁니다.
    6. 부팅합니다. 'slot-successful'로 표시되지 않으면 slot-retry-count를 줄입니다.
      부트로더 슬롯 처리 흐름
      그림 1. 부트로더 슬롯 처리 흐름
  • 빠른 부팅 유틸리티는 플래싱 명령어를 실행할 때 플래싱할 파티션을 결정합니다. 예를 들어 fastboot flash system system.img는 먼저 current-slot 변수를 쿼리한 후 결과를 시스템에 연결하여 플래싱되어야 하는 파티션의 이름을 생성합니다(예: system_a 또는 system_b).
  • 빠른 부팅 set_active 또는 부팅 제어 HAL의 setActiveBootSlot을 통해 현재 슬롯을 설정할 때 부트로더는 현재 슬롯을 업데이트하고 slot-unbootable을 삭제한 후 slot-successful을 삭제하고 retry-count를 재설정합니다. 위 방법을 통해서만 slot-unbootable을 삭제할 수 있습니다.
  • HAL에서 markBootSuccessful을 호출하는 것은 Android 프레임워크의 책임입니다. 부트로더는 파티션을 부팅 완료로 절대 표시해서는 안 됩니다.

A/B 외 업데이트

업데이트를 지원하려면 A/B 외의 업데이트 가능하지 않은 기기가 다음 기준을 충족해야 합니다.

  • 복구 파티션에는 지원되는 일부 파티션(캐시, 사용자 데이터)에서 시스템 이미지를 읽고 시스템 파티션에 이를 쓸 수 있는 이미지가 있어야 합니다.
  • 부트로더는 복구 모드로 바로 재부팅할 수 있도록 지원해야 합니다.
  • 라디오 이미지 업데이트가 지원되는 경우 복구 파티션도 라디오를 플래싱할 수 있어야 합니다. 이는 다음 두 가지 방법 중 하나를 통해 이루어질 수 있습니다.
    • 부트로더가 라디오를 플래시합니다. 이 경우 복구 파티션에서 부트로더로 재부팅하여 업데이트를 완료합니다.
    • 복구 이미지가 라디오를 플래시합니다. 이 기능은 바이너리 라이브러리 또는 유틸리티의 형태로 제공될 수도 있습니다.