Alasan booting kanonis

Android 9 menyertakan perubahan berikut pada spesifikasi alasan booting bootloader.

Alasan booting

Bootloader menggunakan resource hardware dan memori yang tersedia secara unik untuk menentukan alasan perangkat dimulai ulang, lalu menyampaikan penentuan tersebut dengan menambahkan androidboot.bootreason=<reason> ke command line kernel Android untuk peluncurannya. init kemudian menerjemahkan command line ini untuk disebarkan ke properti Android bootloader_boot_reason_prop (ro.boot.bootreason). Untuk perangkat yang diluncurkan dengan Android 12 atau yang lebih tinggi, menggunakan kernel versi 5.10 atau yang lebih baru, androidboot.bootreason=<reason> ditambahkan ke bootconfig, bukan command line kernel.

Spesifikasi alasan booting

Rilis Android sebelumnya menentukan format alasan booting yang tidak menggunakan spasi, semuanya dalam huruf kecil, menyertakan beberapa persyaratan (seperti untuk melaporkan kernel_panic, watchdog, cold/warm/hard), dan yang membuat pengecualian untuk alasan unik lainnya. Spesifikasi yang longgar ini mengakibatkan proliferasi ratusan string alasan booting kustom (dan terkadang tidak bermakna), yang kemudian menyebabkan situasi yang tidak dapat dikelola. Mulai rilis Android saat ini, momentum konten yang hampir tidak dapat diuraikan atau tidak bermakna yang diajukan oleh bootloader telah menimbulkan masalah kepatuhan untuk bootloader_boot_reason_prop.

Dengan rilis Android 9, tim Android menyadari bahwa bootloader_boot_reason_prop lama memiliki momentum yang substansial dan tidak dapat ditulis ulang saat runtime. Oleh karena itu, setiap peningkatan pada spesifikasi alasan booting harus berasal dari interaksi dengan developer bootloader dan penyesuaian pada sistem yang ada. Untuk mencapai hal tersebut, tim Android:

  • Berinteraksi dengan developer bootloader untuk mendorong mereka agar:
    • Berikan alasan kanonis, yang dapat diuraikan, dan dapat dikenali ke bootloader_boot_reason_prop.
    • Berpartisipasi dalam daftar system/core/bootstat/bootstat.cpp kBootReasonMap.
  • Menambahkan sumber system_boot_reason_prop (sys.boot.reason) yang terkontrol dan dapat ditulis ulang saat runtime. Serangkaian aplikasi sistem terbatas (seperti bootstat dan init) dapat menulis ulang properti ini, tetapi semua aplikasi dapat diberi hak sepolicy untuk membacanya.
  • Memberi tahu pengguna tentang alasan booting untuk menunggu hingga setelah userdata dipasang sebelum memercayai konten di properti alasan booting sistem system_boot_reason_prop.

Mengapa terlambat? Meskipun bootloader_boot_reason_prop tersedia sejak awal booting, bootloader_boot_reason_prop diblokir oleh kebijakan keamanan Android sesuai kebutuhan karena mewakili informasi yang tidak akurat, tidak dapat diuraikan, dan non-kanonis. Dalam sebagian besar situasi, hanya developer dengan pengetahuan mendalam tentang sistem booting yang perlu mengakses informasi ini. API yang dioptimalkan, dapat diuraikan, dan kanonis untuk alasan booting dengan system_boot_reason_prop dapat diambil dengan andal dan akurat hanya setelah userdata di-mount. Khususnya:

  • Sebelum userdata dipasang, system_boot_reason_prop akan berisi nilai dari bootloader_boot_reason_prop.
  • Setelah userdata di-mount, system_boot_reason_prop dapat diperbarui agar mematuhi kebijakan atau melaporkan informasi yang lebih akurat.

Karena alasan ini, Android 9 memperpanjang periode waktu sebelum alasan booting dapat diperoleh secara resmi, mengubahnya dari langsung akurat saat booting (dengan bootloader_boot_reason_prop) menjadi hanya tersedia setelah userdata di-mount (dengan system_boot_reason_prop).

Logika bootstat bergantung pada bootloader_boot_reason_prop yang lebih informatif dan mematuhi standar. Jika properti tersebut menggunakan format yang dapat diprediksi, properti tersebut akan meningkatkan akurasi semua skenario mulai ulang dan penonaktifan yang dikontrol, yang pada akhirnya akan meningkatkan dan memperluas akurasi dan makna system_boot_reason_prop.

Format alasan booting kanonis

Format alasan booting kanonis untuk bootloader_boot_reason_prop di Android 9 menggunakan sintaksis berikut:

<reason>,<subreason>,<detail>…

Aturan pemformatan:

  • Huruf kecil
  • Tidak ada spasi kosong (gunakan garis bawah)
  • Semua karakter yang dapat dicetak
  • reason, subreason, dan satu atau beberapa instance detail yang dipisahkan koma.
    • reason wajib yang mewakili alasan prioritas tertinggi mengapa perangkat harus dimulai ulang atau dimatikan.
    • subreason opsional yang mewakili ringkasan singkat tentang alasan perangkat harus dimulai ulang atau dimatikan (atau siapa yang memulai ulang atau mematikan perangkat).
    • Satu atau beberapa nilai detail opsional. detail dapat mengarah ke subsistem untuk membantu menentukan sistem tertentu yang menghasilkan subreason. Anda dapat menentukan beberapa nilai detail, yang umumnya harus mengikuti hierarki kepentingan. Namun, Anda juga dapat melaporkan beberapa nilai detail yang sama pentingnya.

Nilai kosong untuk bootloader_boot_reason_prop dianggap ilegal (karena hal ini memungkinkan agen lain memasukkan alasan booting setelah kejadian).

Persyaratan alasan

Nilai yang diberikan untuk reason (rentang pertama, sebelum penghentian atau koma) harus berasal dari kumpulan berikut yang dibagi menjadi alasan kernel, kuat, dan tumpul:

  • kernel set:
    • "watchdog"
    • "kernel_panic"
  • set kuat:
    • "recovery"
    • "bootloader"
  • setelan tumpul:
    • "cold". Umumnya menunjukkan reset total semua perangkat, termasuk memori.
    • "hard". Umumnya menunjukkan bahwa hardware telah mereset statusnya dan ramoops harus mempertahankan konten persisten.
    • "warm". Umumnya menunjukkan bahwa memori dan perangkat mempertahankan beberapa status, dan penyimpanan pendukung ramoops (lihat driver pstore di kernel) berisi konten persisten.
    • "shutdown"
    • "reboot". Umumnya berarti status ramoops tidak diketahui dan status hardware tidak diketahui. Nilai ini adalah nilai umum karena nilai cold, hard, dan warm memberikan petunjuk tentang kedalaman reset untuk perangkat.

Bootloader harus menyediakan set kernel atau set blunt reason, dan sangat disarankan untuk menyediakan subreason jika dapat ditentukan. Misalnya, penekanan lama tombol daya yang mungkin atau mungkin tidak memiliki cadangan ramoops akan memiliki alasan booting "reboot,longkey".

Tidak ada reason span pertama yang dapat menjadi bagian dari subreason atau detail. Namun, karena alasan penetapan kernel tidak dapat dihasilkan oleh ruang pengguna, "watchdog" dapat digunakan kembali setelah alasan penetapan yang tidak jelas, beserta detail sumber (misalnya, "reboot,watchdog,service_manager_unresponsive", atau "reboot,software,watchdog").

Alasan booting tidak boleh memerlukan pengetahuan internal pakar untuk mendekripsi dan/atau harus dapat dibaca manusia dengan laporan intuitif. Contoh: "shutdown,vbxd" (buruk), "shutdown,uv" (lebih baik), "shutdown,undervoltage" (lebih disukai).

Kombinasi alasan-subalasan

Android mencadangkan kumpulan kombinasi reason-subreason yang tidak boleh kelebihan beban dalam penggunaan normal, tetapi dapat digunakan berdasarkan kasus per kasus jika kombinasi tersebut secara akurat mencerminkan kondisi terkait. Contoh kombinasi yang direservasi meliputi:

  • "reboot,userrequested"
  • "shutdown,userrequested"
  • "shutdown,thermal" (dari thermald)
  • "shutdown,battery"
  • "shutdown,battery,thermal" (dari BatteryStatsService)
  • "reboot,adb"
  • "reboot,shell"
  • "reboot,bootloader"
  • "reboot,recovery"

Untuk mengetahui detail selengkapnya, lihat kBootReasonMap di system/core/bootstat/bootstat.cpp dan histori log perubahan git terkait di repositori sumber Android.

Melaporkan alasan booting

Semua alasan booting, baik dari bootloader maupun yang dicatat dalam alasan booting kanonis, harus dicatat di bagian kBootReasonMap pada system/core/bootstat/bootstat.cpp. Daftar kBootReasonMap adalah campuran alasan yang mematuhi kebijakan dan lama tidak mematuhi kebijakan. Developer bootloader sebaiknya hanya mendaftarkan alasan baru yang mematuhi kebijakan di sini (dan tidak boleh mendaftarkan alasan yang tidak mematuhi kebijakan kecuali jika produk sudah dikirimkan dan tidak dapat diubah).

Sebaiknya Anda menggunakan entri yang sudah ada dan mematuhi kebijakan di system/core/bootstat/bootstat.cpp dan menerapkan pembatasan sebelum menggunakan string yang tidak mematuhi kebijakan. Sebagai panduan, ukurannya adalah:

  • OK untuk melaporkan "kernel_panic" dari bootloader, karena bootstat mungkin dapat memeriksa ramoops untuk kernel_panic signatures guna menyaring subalasan menjadi system_boot_reason_prop kanonis.
  • Tidak OK untuk melaporkan string yang tidak mematuhi di kBootReasonMap (seperti "panic") dari bootloader, karena hal ini pada akhirnya akan merusak kemampuan untuk menyaring reason.

Misalnya, jika kBootReasonMap berisi "wdog_bark", developer bootloader harus:

  • Ubah ke "watchdog,bark" dan tambahkan ke daftar di kBootReasonMap.
  • Pertimbangkan arti "bark" bagi pengguna yang tidak memahami teknologi ini dan tentukan apakah subreason yang lebih bermakna tersedia.

Memverifikasi kepatuhan alasan booting

Saat ini, Android tidak menyediakan pengujian CTS aktif yang dapat memicu atau memeriksa semua kemungkinan alasan booting yang dapat diberikan bootloader secara akurat; partner masih dapat mencoba menjalankan pengujian pasif untuk menentukan kompatibilitas.

Akibatnya, kepatuhan bootloader mengharuskan developer bootloader secara sukarela mematuhi prinsip-prinsip aturan dan pedoman yang dijelaskan di atas. Kami mendesak developer tersebut untuk berkontribusi pada AOSP (khususnya system/core/bootstat/bootstat.cpp) dan menggunakan peluang ini sebagai forum untuk berdiskusi tentang masalah alasan booting.