Files
oxmc 9344e608f6 Initial commit: PawletOS vendor tree
Adds the full vendor/pawlet tree for PawletOS on Raspberry Pi 4/5:

- build/: envsetup.sh helpers (breakfast/brunch/mka), bacon OTA target,
  Soong namespace, build core hook
- config/: common.mk, version.mk, BoardConfigPawlet.mk, BoardConfigSoong.mk,
  privapp-permissions, me.pawlet.android feature XML
- hal/boot_control/rpi/: AIDL boot_control HAL for RPi A/B slot switching
- apps/Updater/: A/B OTA updater (download, verify, install, reboot)
- apps/PawletPlatform/: platform resource APK (device icons, strings)
- overlay/frameworks/base/core/res/: framework config overrides
- prebuilt/, vars/: init rc, aosp_target_release
2026-03-21 19:08:46 -07:00

61 lines
2.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (C) The Android Open Source Project
* Copyright (C) 2025 oxmc / PawletOS
*
* SPDX-License-Identifier: Apache-2.0
*
* On-disk metadata format for PawletOS A/B boot control.
*
* Layout in the misc partition (4 MB, GPT label "misc"):
* 0x0000 0x07FF Android Bootloader Control Block (BCB) — do NOT touch
* 0x0800 0x0FFF Unused padding
* 0x1000 (4096) PawletBootControl — read/written by this HAL
*
* Slot numbering: 0 = slot A (boot_a, cmdline: androidboot.slot_suffix=_a)
* 1 = slot B (boot_b, cmdline: androidboot.slot_suffix=_b)
*
* A/B boot flow on RPi:
* - Normal boot always loads boot_a (GPT partition 1) via the RPi firmware.
* - To boot slot B once: `reboot tryboot` causes firmware to use
* boot_partition=2 for one attempt (see [tryboot] in config.txt).
* - On a confirmed-successful boot from slot B, markBootSuccessful() copies
* boot_b → boot_a so that subsequent normal reboots use the new content.
*/
#pragma once
#include <stdint.h>
#include <string.h>
// Magic value: "PAWL" in little-endian ASCII.
static constexpr uint32_t PAWLET_MAGIC = 0x4C574150u;
static constexpr uint32_t PAWLET_VERSION = 1u;
// Byte offset inside the misc partition where our struct lives.
static constexpr off_t PAWLET_MISC_OFFSET = 4096;
// How many boot attempts to grant a freshly-activated slot.
static constexpr int PAWLET_MAX_BOOT_ATTEMPTS = 3;
// Per-slot metadata (4 bytes).
struct PawletSlot {
uint8_t priority; // 015. Higher = preferred. 0 = unbootable.
uint8_t tries_remaining; // Remaining attempts before slot is unbootable.
uint8_t successful_boot; // 1 once markBootSuccessful() has been called.
uint8_t reserved;
};
// Complete on-disk structure placed at PAWLET_MISC_OFFSET.
// Total size: 24 bytes.
struct __attribute__((packed)) PawletBootControl {
uint32_t magic; // PAWLET_MAGIC
uint32_t version; // PAWLET_VERSION
uint8_t active_slot; // 0 = A, 1 = B
uint8_t merge_status; // android.hardware.boot.MergeStatus enum value
uint8_t reserved[2];
PawletSlot slots[2]; // [0] = slot A, [1] = slot B
uint32_t crc32; // CRC32 over all preceding bytes
};
static_assert(sizeof(PawletBootControl) == 24,
"PawletBootControl layout changed update tests and partition docs");