https://news.ycombinator.com/item?id=26114417
https://support.apple.com/guide/security/boot-process-secac7...
The only major thing it can't boot to my knowledge is Windows, but it might be doable if you chain-load Grub.
What makes x86 feel nicer is that most of the peripherals fall into two categories: 1) Standardized for the arch, so their configuration can be assumed and hardcoded, or 2) Attached to a bus that can be dynamically enumerated (i.e. USB, PCI, etc.) This generally makes the per-system configuration relatively simple.
Embedded systems are not like this. Each SoC is effectively its own system architecture that just happens to share a CPU instruction set with other systems, and the devicetree ends up being the description of this architecture. So it looks gross and ugly and complex by comparison, but the complexity of defining peripherals for a system has to exist somewhere!
The messy bits are, of course, that both the OS and bootloader need access to subsets of this data, and you'd like to ship the tables with the bootloader for a SoC (so the OS can be gneeric and not care), but really, the bootloader only needs a little bit of this, and the OS needs almost all of it... and this leads to coupling between the two being tighter than it should be.
Care to elaborate? I only have a passing interest in the ACPI / UEFI / Open Firmware / device trees / etc. story, but I haven’t encountered anything particularly awful about device trees, or (until you) anybody saying there was.
While there are alternatives, you generally seem to get "device trees and a barebones bootloader" on ARM and "UEFI + ACPI" on amd64.
ACPI will list hardware and necessary hardware properties based on some basic API calls to the system interface. UEFI initialises the ACPI data structure and exposes it to the bootloader so the appropriate drivers can be loaded and configured.
With device trees, you basically configure and build the drivers and configuration into the kernel/OS you're trying to load. That's why compiling Linux on amd64 is generally easy and produces a single image, while for many other devices (smartphones, some SBCs) you need to compile a kernel per device. The device trees only need to be imported/written once per device (or device type, depending on how nice the manufacturers are), but that's how you get stuff like this: https://github.com/torvalds/linux/tree/master/arch/arm64/boo...
On ARM there are actually a few devices that implement UEFI, but most of them have Secure Boot locked in and configured to only boot Windows.
ACPI is not perfect and it's not technically required to have UEFI to implement something better than device trees, but I'm not sure if reinventing the wheel here is necessary or even preferable. UEFI already has open source implementations ready to go, with kernels and other tools already containing code to interact with those APIs, whereas a custom ACPI replacement protocol would need more implementation work,
"Much of the firmware ACPI functionality is provided in bytecode of ACPI Machine Language (AML), a Turing-complete, domain-specific low-level language, stored in the ACPI tables.[7] To make use of the ACPI tables, the operating system must have an interpreter for the AML bytecode."[1]
And it's not like this was intended to truly be fully interoperable. "Maybe we could define the APIs so that they work well with NT and not the others even if they are open."[2]
ARM has none of that: no standardized platform, no device discovery through bus enumeration, no standard VESA graphics implementation. Device tree is a consequence of the non-standardization of ARM devices, not the cause. You could easily have the devicetree in the phone's ROM (just like ACPI, but without the executable code vector) and have the kernel read that data on startup. But you would need a kernel of at least the same size as the PC kernel+initramfs; and unlike on PC's, on phones people still (somewhat) care about code size and performance.