trezor / trezor-firmware

:lock: Trezor Firmware Monorepo
https://trezor.io
Other
1.35k stars 656 forks source link

Firmware boot sequence in Rust #2134

Open matejcik opened 2 years ago

matejcik commented 2 years ago

Due to memory layout optimization and the unimport mechanism, the contents of main.py are very fragile in terms of order of import statements: a wrongly placed import can significantly increase memory footprint, or in some cases even cause basic functions to fail (such as in #2129 experiments)

When the Rust UI is done, it should be relatively easy to implement boot.py fully in Rust, and that paves the way to implement all of main.py in Rust. This would remove the fragility and significantly shorten boot-up time. (which is currently ~3 seconds until the user sees any content on screen).

In order to run the main boot sequence, we would also need to modify modtrezorio-usb-* and directly export the interface objects from Rust.

Open question: if the main sequence runs from Rust, when does the MicroPython interpreter start? A nice answer would be to restart it after every workflow, but we could only do that if the startup of the interpreter itself is fast enough.

jpochyla commented 2 years ago

I've thought about this a bit, and my plan was to:

matejcik commented 2 years ago
  • the fun part:

I envision this part of the sequence a little differently:

  1. do a small event loop in Rust that can dispatch USB and UI events (to Rust code)
  2. make sure all the relevant parts of boot.py are either already in Rust, or implementable in Rust
    • Lockscreen UI element
    • PIN entry element
    • storage initialization and data retrieval calls (before fully replacing storage, we can call C's storage_get() directly)
    • display init and backlight control
  3. from C main(), invoke this Rust event loop
  4. when it exits, proceed to invoke MicroPython interpreter on main.py (which now excludes import boot and friends)

next step from that is expanding the Rust part to initialize the uPy interpreter, then to run the main.py loop, etc.

jpochyla commented 2 years ago

That's a faster way to have the boot in Rust, yes.