Android 9에는 부트로더 부팅 이유 사양에 다음 변경사항이 포함됩니다.
부팅 이유
부트로더는 고유한 방식으로 사용 가능한 하드웨어 및 메모리 리소스를 사용하여 기기가 재부팅된 이유를 확인한 다음, androidboot.bootreason=<reason>
의 실행을 위해 이를 Android 커널 명령줄에 추가하여 확인 내용을 전달합니다. 그런 다음 init
에서 이 명령줄을 변환하여 Android 속성 bootloader_boot_reason_prop
(ro.boot.bootreason
)에 전파합니다. Android 12 이상으로 출시되는 기기의 경우 커널 버전 5.10 이상을 사용하면 androidboot.bootreason=<reason>
이 커널 명령줄 대신 bootconfig에 추가됩니다.
부팅 이유 사양
이전 Android 버전은 부팅 이유 형식을 지정했습니다. 형식에는 공백 없이 소문자만 사용하도록 했고, 일부 요구사항(예: kernel_panic
, watchdog
, cold
/warm
/hard
보고)을 적용하였으며 기타 고유한 이유를 고려했습니다. 사양이 정밀하지 못하다 보니 때때로 무의미하기까지 한 맞춤 부팅 이유 문자열이 수백 가지로 늘어나 관리하기가 어려워졌습니다. 현재 Android 버전에는 부트로더가 파일링한, 파싱이 거의 불가능하거나 무의미한 콘텐츠가 급증하면서 bootloader_boot_reason_prop
의 규정 준수 관련 문제가 발생했습니다.
Android 9 버전을 통해 Android팀은 기존 bootloader_boot_reason_prop
이 상당히 증가하고 있으며 런타임에 다시 작성할 수 없다는 것을 인지하게 되었습니다. 따라서, 부트로더 개발자와의 상호작용과 기존 시스템 변경을 통해 부팅 이유 사양을 개선해야 합니다. 이를 위해 Android팀은 다음 활동을 진행하고 있습니다.
- 부트로더 개발자와 소통하며 다음을 권장합니다.
bootloader_boot_reason_prop
에 표준 이유와 파싱 및 인식 가능한 이유를 제공합니다.system/core/bootstat/bootstat.cpp
kBootReasonMap
목록에 참여합니다.
- 제어 및 런타임 재작성이 가능한
system_boot_reason_prop
의 소스(sys.boot.reason
)를 추가합니다. 시스템 애플리케이션의 제한된 집합(예:bootstat
,init
)은 이 속성을 재작성할 수 있으나, 이를 읽을 수 있는 sepolicy 권한이 모든 애플리케이션에 부여될 수 있습니다. - 시스템 부팅 이유 속성인
system_boot_reason_prop
의 콘텐츠를 신뢰하기 전에 사용자 데이터가 마운트될 때까지 대기하는 부팅 이유를 사용자에게 알립니다.
지연되는 이유는 무엇일까요? bootloader_boot_reason_prop
은 부팅 초기에 사용할 수 있지만, 부정확하고 파싱 가능하지 않으며 비표준화된 정보를 나타내므로 Android 보안 정책에 따라 필요시 차단되기 때문입니다.
대부분의 경우 부팅 시스템을 잘 알고 있는 개발자만 이 정보에 액세스해야 합니다. system_boot_reason_prop
을 통해 부팅 이유에 사용되는 상세하고 파싱 가능하며 표준화된 API는 사용자 데이터가 마운트된 후에만 안정적이고 정확하게 선택할 수 있습니다.
구체적으로는 다음과 같습니다.
- 사용자 데이터가 마운트되기 전에
system_boot_reason_prop
에bootloader_boot_reason_prop
의 값이 포함됩니다. - 사용자 정보가 마운트된 후에 규정을 준수하고 더 정확한 정보를 전달하기 위해
system_boot_reason_prop
이 업데이트될 수 있습니다.
따라서, Android 9에서는 부팅 이유를 공식적으로 파악하기 전까지의 기간을 연장하여 부팅 이유가 부팅 상태에서 즉각적으로 정확히 파악(bootloader_boot_reason_prop
사용)되기보다는 사용자 데이터가 마운트된 후에 파악(system_boot_reason_prop
사용)되도록 합니다.
Bootstat 로직은 보다 더 유익하고 규정을 잘 준수하는 bootloader_boot_reason_prop
에 따라 다릅니다. 이 속성이 예측 가능한 형식을 사용하는 경우 제어되는 모든 재부팅 및 종료 시나리오의 정확도가 개선되어 system_boot_reason_prop
의 정확성과 의미가 구체화되고 확장됩니다.
표준 부팅 이유 형식
Android 9에서 bootloader_boot_reason_prop
의 표준 부팅 이유 형식은 다음 구문을 사용합니다.
<reason>,<subreason>,<detail>…
형식 지정 규칙:
- 소문자
- 공백 없음(밑줄 사용)
- 인쇄 가능한 모든 문자
- 쉼표로 구분된
reason
,subreason
및 하나 이상의detail
.- 필수
reason
은 기기가 재부팅 또는 종료된 이유 중 가장 우선순위가 높은 이유를 나타냅니다. - 선택사항인
subreason
은 기기가 재부팅이나 종료된 이유 또는 누가 기기를 재부팅이나 종료했는지에 관해 요약을 표시합니다. - 선택사항인
detail
값으로 하나 이상입니다.detail
은 하위 시스템을 지정하여 어떤 특정 시스템에서subreason
이 발생했는지 파악하도록 지원할 수 있습니다. 일반적으로 중요도의 계층 구조에 따라detail
값을 여러 개 지정할 수 있습니다. 한편, 중요도가 동일한 다수의detail
값을 보고할 수도 있습니다.
- 필수
이후에 다른 에이전트가 부팅 이유를 삽입할 수 있으므로 bootloader_boot_reason_prop
의 값이 비어 있는 경우에는 잘못된 것으로 간주합니다.
이유 요구사항
reason
에 지정된 값(첫 스팬으로 마침표나 쉼표 앞에 위치)은 커널, 타당도가 높은 이유, 타당도가 낮은 이유로 구분되는 다음 집합에 속해야 합니다.
- 커널 집합은 다음과 같습니다.
- "
watchdog"
"kernel_panic"
- "
- 타당도가 높은 이유의 집합입니다.
"recovery"
"bootloader"
- 타당도가 낮은 이유의 집합입니다.
"cold"
: 일반적으로 메모리를 포함한 모든 기기의 전체 재설정을 나타냅니다."hard"
: 일반적으로 하드웨어에서 상태를 재설정했으며ramoops
는 영구 콘텐츠를 유지해야 합니다."warm"
: 일반적으로 메모리와 기기에서 일부 상태를 유지하며 저장을 지원하는ramoops
(커널의pstore
드라이버 참고)에는 영구 콘텐츠가 포함됩니다."shutdown"
"reboot"
: 일반적으로ramoops
상태 및 하드웨어 상태를 알 수 없음을 의미합니다.cold
,hard
,warm
값이 기기 재설정의 깊이에 관한 정보를 제공하기 때문에 이 값은 포괄적인 값입니다.
부트로더는 커널 집합 또는 타당도가 낮은 집합 reason
을 제공해야 하며, 결정이 가능하다면 subreason
을 제공하는 것이 좋습니다. 예를 들어, 전원 키를 길게 누를 경우(ramoops
백업 가능 또는 불가) 부팅 이유가 "reboot,longkey"
일 수 있습니다.
첫 스팬이 아닌 reason
은 subreason
또는 detail
의 일부일 수 있습니다. 하지만, 사용자 공간에서 커널 집합 이유를 생성할 수 없으므로 "watchdog"
은 타당도가 낮은 집합 이유 후에 소스의 세부사항과 함께 재사용될 수 있습니다(예: "reboot,watchdog,service_manager_unresponsive"
또는 "reboot,software,watchdog"
).
부팅 이유는 전문적인 내부 지식이 없이도 이해할 수 있어야 하고 직관적인 보고로 사람이 알아볼 수 있어야 합니다. 예를 들어, "shutdown,vbxd"
(나쁨), "shutdown,uv"
(보통), "shutdown,undervoltage"
(양호)로 표시하는 식입니다.
이유 및 하위 이유 조합
Android는 일반적인 사용에서 오버로드되지 않는 reason
과 subreason
의 조합을 미리 지정해 두었지만, 조합이 관련 조건을 정확하게 반영하는 경우 사례별로 사용할 수 있습니다. 지정된 조합의 예는 다음과 같습니다.
"reboot,userrequested"
"shutdown,userrequested"
"shutdown,thermal"
(thermald
에서)"shutdown,battery"
"shutdown,battery,thermal"
(BatteryStatsService
에서)"reboot,adb"
"reboot,shell"
"reboot,bootloader"
"reboot,recovery"
자세한 내용은 system/core/bootstat/bootstat.cpp
의 kBootReasonMap
과 Android 소스 저장소의 관련 Git 변경 로그 기록을 참고하세요.
부팅 이유 보고
모든 부팅 이유는 부트로더에서 발생하든 표준 부팅 이유에 기록되든지와 상관없이 system/core/bootstat/bootstat.cpp
의 kBootReasonMap
섹션에 기록되어야 합니다. kBootReasonMap
목록에는 규정을 준수하는 이유와 규정을 준수하지 않는 기존 이유가 혼합되어 있습니다. 부트로더 개발자는 여기에 규정을 준수하는 새로운 이유만 등록해야 하며, 제품이 이미 배송되어 변경할 수 없는 경우가 아닌 이상 규정을 준수하지 않는 이유를 등록해서는 안 됩니다.
규정을 준수하지 않는 문자열을 사용하기보다는 규정을 준수하는 system/core/bootstat/bootstat.cpp
의 기존 항목을 사용하고 제한을 실행하는 것이 좋습니다. 가이드라인은 다음과 같습니다.
bootstat
에서ramoops
를 검사하여kernel_panic signatures
가 하위 이유를 표준system_boot_reason_prop
으로 세분화할 수 있으므로 부트로더의"kernel_panic"
을 보고해도 됩니다.- 부트로더의
kBootReasonMap
과 같이 규정을 준수하지 않는 문자열(예:"panic")
을 보고해서는 안 됩니다. 이 경우reason
을 세분화하는 기능이 결국 중지되기 때문입니다.
예를 들어, kBootReasonMap
이 "wdog_bark"
를 포함하는 경우 부트로더 개발자는 다음을 따라야 합니다.
"watchdog,bark"
로 변경하고kBootReasonMap
의 목록에 추가합니다.- 이 기술에 익숙하지 않은 경우
"bark"
를 어떻게 이해할지 고려하고 더 유용한subreason
을 사용할 수 있는지 확인하세요.
부팅 이유 규정 준수 자체 검사
현재 Android는 부트로더가 제공할 수 있는 모든 가능한 부팅 이유를 정확하게 트리거하거나 검사할 수 있는 활성 CTS 테스트를 제공하지 않습니다. 파트너는 수동적 테스트를 실행하여 호환성을 확인할 수 있습니다.
따라서, 부트로더 규정을 준수하려면 부트로더 개발자가 위에 설명된 규칙 및 가이드라인의 의도와 의미에 동의하고 이를 자발적으로 준수해야 합니다.
부트로더 개발자의 경우 AOSP(특히, system/core/bootstat/bootstat.cpp
)에 기여하면서 이를 부팅 이유 문제에 관한 토론의 장으로 활용하시기 바랍니다.