The idea behind this next series of diary entries is to give an idea of what it takes to port Inferno to another platform, what steps need to be taken, what to look out for, where to find information, and so on. It's not going to be very comprehensive because we're already starting with a working compiler toolchain and existing ports to related platforms.
I started by fetching the Arm Cortex-M7 Processor Technical Reference Manual, the Arm Cortex-M7 Devices Generic User Guide and the i.MX RT1060 Processor Reference Manual, available from the Teensy 4.1 product page.
I always try to remember that setting up these boards involves figuring out a virtual checklist of items: vectors/interrupts, power, clocks, pin modes. This gives me an idea of what to look at in the reference manual. In this case, I started to figure out what might be needed to get the status LED to light up in bare metal code, then decided to cheat a bit by firing up the Arduino programming environment to get it to print out the values held in various registers. Then I went looking for the thesis about porting Inferno to the same hardware. I also started digging into the Arduino core for the Teensy 4.1.
Booting from flash memory seems to involve something called FlexSPI. Looking at the linker script for a bare metal Zig program, there is a FlexSPI configuration section which is similar to the one in the bootdata.c file in the Arduino core. That, in turn, refers to the FlexSPI Configuration Block section (9.6.3.1) in revision 3 of the i.MX RT1060 PRM.
The Zig example is probably the simplest and most informative. It looks like the payload is structured like this:
With a plausible-looking binary bundle ready, I made a HEX file with the bin2hex.py tool that is supplied with the python3-intelhex package on Debian, and used the teensy_loader_cli tool to send it to the device. The result was 9 flashes of the PROG LED, repeating periodically. A quick search for this was quite frustrating given that describing the issue using the terms “blink” or “flash” tends to return fairly basic guides that involve running the stock LED-blinking example. In the end, after stumbling over various forum posts that mention the problem, I found a link to the Bootloader Chip for DIY Teensy 4.0 & 4.1 Projects page which gives the describes the “diagnostic blink codes”. About the only useful suggestion there is that it might be caused by a hard fault in early startup code.
I changed a couple of instructions involving the stack pointer and disabled interrupts until all the vectors were set up, and this helped get my first program to run and light up the status LED. Adding a loop with delays in which the LED is switched on and off resulted in the usual blinking LED program.