Alasan Boot Kanonik

Android 9 menyertakan perubahan berikut pada spesifikasi alasan boot bootloader.

Alasan boot

Bootloader menggunakan sumber daya perangkat keras dan memori yang tersedia secara unik untuk menentukan alasan perangkat di-boot ulang, lalu mengomunikasikan penentuan tersebut dengan menambahkan androidboot.bootreason=<reason> ke baris perintah kernel Android untuk peluncurannya. init kemudian menerjemahkan baris perintah ini untuk disebarkan ke properti Android bootloader_boot_reason_prop ( ro.boot.bootreason ). Untuk perangkat yang diluncurkan dengan Android 12 atau lebih baru, menggunakan kernel versi 5.10 atau lebih tinggi, androidboot.bootreason=<reason> ditambahkan ke bootconfig, bukan baris perintah kernel.

Spesifikasi alasan boot

Rilis Android sebelumnya menetapkan format alasan booting yang tidak menggunakan spasi, semuanya menggunakan huruf kecil, menyertakan beberapa persyaratan (seperti untuk pelaporan kernel_panic , watchdog , cold / warm / hard ), dan yang memberikan pengecualian untuk alasan unik lainnya. Spesifikasi yang longgar ini mengakibatkan berkembangnya ratusan string alasan booting khusus (dan terkadang tidak berarti), yang pada gilirannya menyebabkan situasi yang tidak dapat dikelola. Pada rilis Android saat ini, momentum konten yang hampir tidak dapat diurai atau tidak berarti yang diajukan oleh bootloader telah menimbulkan masalah kepatuhan untuk bootloader_boot_reason_prop .

Dengan dirilisnya Android 9, tim Android menyadari bahwa bootloader_boot_reason_prop yang lama memiliki momentum yang besar dan tidak dapat ditulis ulang saat runtime. Oleh karena itu, setiap perbaikan pada spesifikasi alasan booting harus berasal dari interaksi dengan pengembang bootloader dan penyesuaian pada sistem yang ada. Untuk itu tim Android adalah:

  • Terlibat dengan pengembang bootloader untuk mendorong mereka untuk:
    • Berikan alasan kanonik, dapat diurai, dan dikenali untuk bootloader_boot_reason_prop .
    • Berpartisipasi dalam daftar kBootReasonMap system/core/bootstat/bootstat.cpp .
  • Menambahkan sumber system_boot_reason_prop ( sys.boot.reason ) yang terkontrol dan dapat ditulis ulang runtime. Sejumlah aplikasi sistem terbatas (seperti bootstat dan init ) dapat menulis ulang properti ini, namun semua aplikasi dapat diberikan hak sepolicy untuk membacanya.
  • Memberi tahu pengguna tentang alasan boot untuk menunggu hingga data pengguna dipasang sebelum memercayai konten di properti alasan boot sistem system_boot_reason_prop .

Mengapa sangat terlambat? Meskipun bootloader_boot_reason_prop tersedia di awal boot, bootloader_boot_reason_prop diblokir oleh kebijakan keamanan Android sesuai kebutuhan karena mewakili informasi yang tidak akurat, tidak dapat diurai, dan tidak kanonik. Dalam kebanyakan situasi, hanya pengembang dengan pengetahuan mendalam tentang sistem boot yang perlu mengakses informasi ini. API yang disempurnakan, dapat diurai, dan kanonik untuk alasan booting melalui system_boot_reason_prop dapat diambil dengan andal dan akurat hanya setelah data pengguna dipasang. Secara khusus:

  • Sebelum data pengguna dipasang, system_boot_reason_prop akan berisi nilai dari bootloader_boot_reason_prop .
  • Setelah data pengguna dipasang, system_boot_reason_prop dapat diperbarui agar sesuai atau untuk melaporkan informasi yang lebih akurat.

Karena alasan ini, Android 9 memperpanjang periode waktu sebelum alasan booting dapat diperoleh secara resmi, mengubahnya dari akurat langsung saat boot (dengan bootloader_boot_reason_prop ) menjadi tersedia hanya setelah data pengguna dipasang (dengan system_boot_reason_prop ).

Logika bootstat bergantung pada bootloader_boot_reason_prop yang lebih informatif dan sesuai. Jika properti tersebut menggunakan format yang dapat diprediksi, properti tersebut akan meningkatkan keakuratan semua skenario reboot dan shutdown yang terkontrol, yang pada gilirannya menyempurnakan dan memperluas akurasi dan makna system_boot_reason_prop .

Format alasan boot kanonik

Format alasan boot kanonik untuk bootloader_boot_reason_prop di Android 9 menggunakan sintaksis berikut:

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

Aturan pemformatan:

  • Huruf kecil
  • Tidak ada yang kosong (gunakan garis bawah)
  • Semua karakter yang dapat dicetak
  • reason yang dipisahkan koma , subreason , dan satu atau lebih detail .
    • reason wajib yang mewakili alasan prioritas tertinggi mengapa perangkat harus di-boot ulang atau dimatikan.
    • subreason opsional yang mewakili ringkasan singkat mengapa perangkat harus di-boot ulang atau dimatikan (atau siapa yang melakukan boot ulang atau mematikan perangkat).
    • Satu atau beberapa nilai detail opsional. detail mungkin menunjuk ke subsistem untuk membantu menentukan sistem spesifik mana yang menghasilkan subreason . Anda dapat menentukan beberapa nilai detail , yang umumnya mengikuti hierarki kepentingan. Namun, laporan beberapa nilai detail yang sama pentingnya juga dapat diterima.

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

Persyaratan alasan

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

  • kumpulan kernel:
    • " watchdog"
    • "kernel_panic"
  • himpunan kuat:
    • "recovery"
    • "bootloader"
  • set tumpul:
    • "cold" . Umumnya menunjukkan reset penuh semua perangkat, termasuk memori.
    • "hard" . Umumnya menunjukkan perangkat keras telah disetel ulang statusnya dan ramoops harus mempertahankan konten yang persisten.
    • "warm" . Umumnya menunjukkan memori dan perangkat mempertahankan beberapa keadaan, dan penyimpanan cadangan ramoops (lihat driver pstore di kernel) berisi konten yang persisten.
    • "shutdown"
    • "reboot" . Secara umum berarti status ramoops tidak diketahui dan status perangkat keras tidak diketahui. Nilai ini merupakan nilai umum karena nilai cold , hard , dan warm memberikan petunjuk mengenai seberapa dalam penyetelan ulang perangkat.

Bootloader harus menyediakan set kernel atau reason set tumpul, dan sangat dianjurkan untuk memberikan subreason jika dapat ditentukan. Misalnya, menekan lama tombol daya yang mungkin memiliki cadangan ramoops atau tidak akan memiliki alasan boot "reboot,longkey" .

Tidak ada reason rentang pertama yang dapat menjadi bagian dari subreason atau detail apa pun. Namun, karena alasan kumpulan kernel tidak dapat dihasilkan oleh ruang pengguna, "watchdog" dapat digunakan kembali setelah alasan yang jelas, bersama dengan detail sumbernya (misalnya "reboot,watchdog,service_manager_unresponsive" , atau "reboot,software,watchdog" ).

Alasan boot tidak memerlukan pengetahuan internal ahli untuk menguraikannya 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 serangkaian reason - kombinasi subreason yang tidak boleh kelebihan beban dalam penggunaan normal namun dapat digunakan berdasarkan kasus per kasus jika kombinasi tersebut secara akurat mencerminkan kondisi terkait. Contoh kombinasi yang dicadangkan 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 detail selengkapnya, lihat kBootReasonMap di system/core/bootstat/bootstat.cpp dan riwayat git changelog terkait di repositori sumber Android.

Melaporkan alasan booting

Semua alasan boot, baik dari bootloader atau dicatat dalam alasan boot kanonik, harus dicatat di bagian kBootReasonMap system/core/bootstat/bootstat.cpp . Daftar kBootReasonMap merupakan campuran dari alasan kepatuhan dan ketidakpatuhan lama. Pengembang bootloader hanya boleh mendaftarkan alasan kepatuhan baru di sini (dan tidak boleh mendaftarkan alasan ketidakpatuhan kecuali produk telah dikirimkan dan tidak dapat diubah).

Kami sangat menyarankan untuk menggunakan entri yang sesuai dan sudah ada di system/core/bootstat/bootstat.cpp dan menahan diri sebelum menggunakan string yang tidak sesuai. Sebagai pedomannya adalah:

  • OK untuk melaporkan "kernel_panic" dari bootloader, karena bootstat mungkin dapat memeriksa ramoops untuk kernel_panic signatures untuk menyaring subalasan ke dalam kanonik system_boot_reason_prop .
  • Tidak boleh melaporkan string yang tidak patuh di kBootReasonMap (seperti "panic") dari bootloader, karena hal ini pada akhirnya akan merusak kemampuan untuk memperbaiki reason .

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

  • Ubah ke "watchdog,bark" dan tambahkan ke daftar di kBootReasonMap .
  • Pertimbangkan apa arti "bark" bagi mereka yang tidak terbiasa dengan teknologi tersebut dan tentukan apakah ada subreason yang lebih bermakna.

Memverifikasi kepatuhan alasan boot

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

Oleh karena itu, kepatuhan bootloader mengharuskan pengembang bootloader untuk secara sukarela mematuhi semangat peraturan dan pedoman yang dijelaskan di atas. Kami mendorong pengembang tersebut untuk berkontribusi pada AOSP (khususnya untuk system/core/bootstat/bootstat.cpp ) dan menggunakan kesempatan ini sebagai forum untuk berdiskusi tentang masalah alasan boot.