sifive / freedom-u540-c000-bootloader

Freedom U540-C000 Bootloader Code
Other
85 stars 39 forks source link

Challenge #6

Open esmil opened 6 years ago

esmil commented 6 years ago

This solves the challenge, at least with my toolchain:

$ make
...
$ diff -sq u540-c000-release/bootrom.bin zsbl.bin 
Files u540-c000-release/bootrom.bin and zsbl.bin are identical
esmil commented 6 years ago

The toolchain used to generate the original bootrom.bin seems to choose whether to relax function calls in it's own peculiar way, and also newer gcc versions seem to be better at avoiding unnecessary divisions.

Hence it seems to me there are 2 ways to solve the challenge: 1) Do some archaeological work to figure out the exact version of binutils and gcc used to generate the original, and then change the C-code, linkerscript and dtb accordingly. 2) Change big parts of the program to assembly that aligns with the original bootrom.bin so that it also works with newer toolchains.

This solution uses the second approach.

tmagik commented 6 years ago

Here's a hint for option 1. https://github.com/riscv/riscv-tools/commit/3921adb93efb6e9422701209b6926fbc8b693059

If that is not very close to what built that rom, then I have more software archaeology to do.

esmil commented 6 years ago

Right. If your aim is to understand the code option 1 is better. But if your aim is to verify that the bootrom doesn't contain malicious code I actually think option 2 is a better. I'd much rather read through the bits of assembly I just added and verify that it generates the bootrom with a toolchain I trust, than I'd read some C code, download a special toolchain and then have to read through all that code to check that it doesn't add something extra to generated binary.

ddevault commented 6 years ago

You're never going to attain option 2 nirvana, though. Your suggestion only works if you can take an OOTB risc-v gcc/binutils and compile a binary-perfect copy of the bootloader, but as the target improves and new optimizations are made that's just going to happen less and less often.

esmil commented 6 years ago

You're right that in this pull request the generated zsbl.bin still contain functions compiled from C, and those might change with a future update of gcc that optimizes differently. For now I've tried to keep as many benefits from option 1 as possible, eg. more readable C.

However if this happens you just have switch those functions to assembly like I've done with some of the other functions, and that process has a natural end when every function is switched to assembly, so you're not right that complete option 2 is never going to happen.