Recovery Bootloader Bugs?

Hello, I’ve been trying to use the recovery instructions in the wiki to copy and run a recovery image for the JH7100 core. I’ve run into a few problems and while I’ve got a path forward worked out, I figured I’d share my my findings in case anyone else finds themselves with a similar problem.

So the initial loader when connecting to the debug pins and holding boot provides a small list of commands. The load command is supposed to open up for an XMODEM connection to receive binary data and load it at a given address. In the recovery instructions, this is used to load the recovery to 0x18000000. Afterwards, a do command is used to enter this address. I’ve not been able to get the XMODEM connection to work for this particular item thus far, although it has worked in the past for the later stage boot loader restorations. I simply get some sort of ACK error, I’ll have to copy the text verbatim next time I try.

Another task the loader seems to have trouble with is reading 4-byte longs that occupy the second half of an 8-byte quad-word. The commands are r(b|w|l) and w(b|w|l) to read and write a byte, word, or long respectively. The byte command can read any, and the word command appears to need to be 16-byte word aligned, and will pass back an error if this isn’t the case, but the long command only succeeds on 8-byte boundaries, and fails to pass back an error or return on the odd 4-byte boundaries.

Finally, there is a show command that appears to be somewhat similar to “od” on Unix in that it is used to dump a range of memory in some sort of intelligible fashion. However, I’ve found using this function only prints one line as individual bytes and then hangs until an interrupt is sent. I haven’t tried in a few days, I will update this with the exact behavior, but I’m pretty sure if I left the address and length off in subsequent calls, it would print back another line of bytes but likewise hang after printing rather than printing the full length or exiting.

I can verify that the do command seems to enter the program text correctly, as I used the wb command to write in an arbitrary binary and enter it and observed what I expected to happen.

This component passes back a copyright notice of SiFive, so the component itself may not be in direct control of StarFive.

The XModem implementation in the on-chip ROM apparently has a bug that prevents it from working with some XModem implementations. You basically have to use this tool as linked to in the recovery guide:

See the comment in the source code:

If you’re interested in the the recovery shell, so to speak, I found that it resembles the one implemented in this file:

I could not verify whether or not this is exactly the same version, but it could be a good place to start looking.

Oooh, I didn’t think I’d see code as a response to this. That’s great, that’ll definitely help me along in what I’m working on. Good to see it’s on Github too, that way if I find any fixes for these bugs I can stage PRs and hopefully help others out.

Glad to know they explicitly mention lrzsz tools, that’s precisely what I was using and had failing. I was a little iffy on how much the specific instructions needed to be followed on the wiki. They’re using specific tools for interacting with the serial port (TeraTerm and Minicom on WinNT/Unix respectively).

While helpful, the bare minimum you need to interact with the device, at least on Unix, is stty and cat, the former to set the baud and other terminal characteristics and the latter to open I/O to the port. I’ve found with the right stty settings, something to the effect of “cat /dev/ttyUSB0 & cat > /dev/ttyUSB0” will setup a rudimentary communication channel. It’s not as easy as using, say, screen, or one of the listed tools, but it gets the job done, and is especially helpful if you want to do each in a separate terminal and keep a clean stdout log uninterrupted by local input data in your terminal. Only snag I really hit there is cat > /dev/ttyUSB0 takes exclusive ownership of the input of the TTY so that if you pop open another terminal and try to sx > /dev/ttyUSB0, it won’t let the XMODEM attempt through, or it will take control of the /dev/ttyUSB0 so you can’t issue the device-side listen for connection. I’ll continue to take jabs at this, as one of my goals is to have this process defined with as few external dependencies as possible, hence trying to get base-level communication to work well with just cat and stty, as every Unix under the sun should have those.

I’ll report back with any other relevant findings.