August 28, 2018

Nanopi Fire3 and bl1-nanopi-m3 - more experiments

I rebuilt the loader with SYSLOG_ON configured to get more output. Then I grabbed an SD card and zeroed the first 129 blocks. This way I can put the SD card in the board, and when I hit reset, the on-chip boot loader will not find a valid loader in sector 1 (counting from zero) and will fall back to USB booting and I can load this bl1 loader I want to play with. It should then find the rest of the SD card to its liking. But it doesn't. I get the following messages:
Loading from sdmmc...
SIGNATURE: 0x00000000
3rd boot Sinature is wrong! SDMMC boot failure
 Image Loading Failure Try to USB boot
The question now is what sector on the SD card is it trying to load from and how is that determined. Since I am working from source I can look at the iSDHCBOOT.c source file and learn some things. I can even put in a print statement, which tells me it is trying to read sector 64 from the SD card. So, where does the 64 come from? Well it comes from offset 0x40 (which actually holds a byte offset in a long) in the header, which you can find in startup_aarch64.S.

My SD card was laid out for and with the U-Boot binaries that are part of the NanoPi Fire3 linux distribution. This puts the "thing" that this bl1 boot loader should be booting in sector 129. So, what I do is to add a feature to my usb_loader program to set the address field. I have it accept the option -a129, and then multiple 129*512 and put that in the header.

So, I dump the file bl1-mmcboot.bin that comes as part of my working U-boot setup. I see:

00000040 0002 0100 3054 0000 0000 ffff 0000 ffff
The little endian value at 0x40 is 0x00010200, which is 66048 and 66048/129 gives 129 -- aha, just as it should be. The other addresses specify "bl1" not the next "thing". In this case, the next "thing" is fip-loader.img. Dumping the interesting parts of fip-loader.img we see:
00000040 0000 0000 0000 0000 0000 0000 0000 0000
000001f0 0000 0000 0000 0000 0000 0000 4e53 4948               NSIH
So the file has the necessary "NSIH" signature at the end of the header, but all the interesting fields (such as the load address at 0x48) are zero. Indeed, bl1 tries to load this to address zero and gets a fault:
PANIC! exception 0x200 on CPU0 level 3, class=0x25 syndrome=0x61
So -- apparently the "bl1" loader that actually works for me on my Fire3 does something differently than this loader for the M3 that I have sources for. But all that is a mystery unless I want to break my neck dissasembling that code, which does not seem like time well spent, especially with the full source for the M3 "bl1" loader available.

Lessons Learned

I have a pretty solid idea now of how "bl1" works. "bl1" though badly named, is in fact the stage 2 boot loader and more or less replaces the usual U-Boot SPL.

I am throwing in the towel with the vendor supplied setup that gets U-Boot running to boot Linux. I see no reason the screw around with the FIP stuff and secure mode. For my purposes a much simpler setup will suffice and I am going to work to get that set up. In particular, I don't want any mysterious binary blobs as part of the path, and I believe I can see my way clear to getting rid of them.


Have any comments? Questions? Drop me a line!

Tom's electronics pages / [email protected]